From 59bb5d15c88728d698b348a9249e2619b891a8cd Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Fri, 8 Jan 2021 08:43:00 +1100 Subject: [PATCH 01/25] Filter PartAttachment API list by Part reference --- InvenTree/part/api.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/InvenTree/part/api.py b/InvenTree/part/api.py index b479575a35..3c848620d5 100644 --- a/InvenTree/part/api.py +++ b/InvenTree/part/api.py @@ -182,6 +182,10 @@ class PartAttachmentList(generics.ListCreateAPIView, AttachmentMixin): queryset = PartAttachment.objects.all() serializer_class = part_serializers.PartAttachmentSerializer + filter_backends = [ + DjangoFilterBackend, + ] + filter_fields = [ 'part', ] From ba1862478c7c53a3fd766eb07aa41b630516a347 Mon Sep 17 00:00:00 2001 From: eeintech Date: Tue, 12 Jan 2021 17:33:42 -0500 Subject: [PATCH 02/25] Allow user with part.change permission to delete BOM items --- InvenTree/part/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/InvenTree/part/views.py b/InvenTree/part/views.py index 1d76860ac1..e7fd281dbb 100644 --- a/InvenTree/part/views.py +++ b/InvenTree/part/views.py @@ -2554,7 +2554,7 @@ class BomItemDelete(AjaxDeleteView): context_object_name = 'item' ajax_form_title = _('Confim BOM item deletion') - role_required = 'part.delete' + role_required = 'part.change' class PartSalePriceBreakCreate(AjaxCreateView): From a1b2347784c03737d84df405c3ce7fe02f77d4e9 Mon Sep 17 00:00:00 2001 From: eeintech Date: Tue, 12 Jan 2021 17:43:12 -0500 Subject: [PATCH 03/25] Also allow part attachements and parameters to be deleted --- InvenTree/part/templates/part/params.html | 2 +- InvenTree/part/views.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/InvenTree/part/templates/part/params.html b/InvenTree/part/templates/part/params.html index af1c4cdab6..d07a19f79f 100644 --- a/InvenTree/part/templates/part/params.html +++ b/InvenTree/part/templates/part/params.html @@ -37,7 +37,7 @@ {% if roles.part.change %} {% endif %} - {% if roles.part.delete %} + {% if roles.part.change %} {% endif %} diff --git a/InvenTree/part/views.py b/InvenTree/part/views.py index e7fd281dbb..d1a612b7f4 100644 --- a/InvenTree/part/views.py +++ b/InvenTree/part/views.py @@ -231,7 +231,7 @@ class PartAttachmentDelete(AjaxDeleteView): ajax_template_name = "attachment_delete.html" context_object_name = "attachment" - role_required = 'part.delete' + role_required = 'part.change' def get_data(self): return { @@ -2073,7 +2073,7 @@ class PartParameterEdit(AjaxUpdateView): class PartParameterDelete(AjaxDeleteView): """ View for deleting a PartParameter """ - role_required = 'part.delete' + role_required = 'part.change' model = PartParameter ajax_template_name = 'part/param_delete.html' From 59c0a502892ac81f939847f7a10db5e9d682187f Mon Sep 17 00:00:00 2001 From: eeintech Date: Wed, 13 Jan 2021 13:35:49 -0500 Subject: [PATCH 04/25] Separated category from part permissions and location from stock item permissions --- InvenTree/part/templates/part/category.html | 8 ++++---- InvenTree/part/views.py | 14 +++++++------- InvenTree/stock/templates/stock/location.html | 8 +++++--- InvenTree/stock/templates/stock/location_list.html | 2 +- InvenTree/stock/views.py | 10 +++++----- InvenTree/users/admin.py | 13 +++++++++++-- InvenTree/users/models.py | 14 ++++++++++---- 7 files changed, 43 insertions(+), 26 deletions(-) diff --git a/InvenTree/part/templates/part/category.html b/InvenTree/part/templates/part/category.html index 6992d9bac4..47ef866e2e 100644 --- a/InvenTree/part/templates/part/category.html +++ b/InvenTree/part/templates/part/category.html @@ -9,7 +9,7 @@ {% if category %}

{{ category.name }} - {% if user.is_staff and roles.part.change %} + {% if user.is_staff and roles.part_category.change %} {% endif %}

@@ -20,18 +20,18 @@ {% endif %}

- {% if roles.part.add %} + {% if roles.part_category.add %} {% endif %} {% if category %} - {% if roles.part.change %} + {% if roles.part_category.change %} {% endif %} - {% if roles.part.delete %} + {% if roles.part_category.delete %} diff --git a/InvenTree/part/views.py b/InvenTree/part/views.py index d1a612b7f4..0e16bfb498 100644 --- a/InvenTree/part/views.py +++ b/InvenTree/part/views.py @@ -2088,7 +2088,7 @@ class CategoryDetail(InvenTreeRoleMixin, DetailView): queryset = PartCategory.objects.all().prefetch_related('children') template_name = 'part/category_partlist.html' - role_required = 'part.view' + role_required = ['part_category.view', 'part.view'] def get_context_data(self, **kwargs): @@ -2138,7 +2138,7 @@ class CategoryEdit(AjaxUpdateView): ajax_template_name = 'modal_form.html' ajax_form_title = _('Edit Part Category') - role_required = 'part.change' + role_required = 'part_category.change' def get_context_data(self, **kwargs): context = super(CategoryEdit, self).get_context_data(**kwargs).copy() @@ -2177,7 +2177,7 @@ class CategoryDelete(AjaxDeleteView): context_object_name = 'category' success_url = '/part/' - role_required = 'part.delete' + role_required = 'part_category.delete' def get_data(self): return { @@ -2193,7 +2193,7 @@ class CategoryCreate(AjaxCreateView): ajax_template_name = 'modal_form.html' form_class = part_forms.EditCategoryForm - role_required = 'part.add' + role_required = 'part_category.add' def get_context_data(self, **kwargs): """ Add extra context data to template. @@ -2233,7 +2233,7 @@ class CategoryCreate(AjaxCreateView): class CategoryParameterTemplateCreate(AjaxCreateView): """ View for creating a new PartCategoryParameterTemplate """ - role_required = 'part.add' + role_required = 'part_category.change' model = PartCategoryParameterTemplate form_class = part_forms.EditCategoryParameterTemplateForm @@ -2336,7 +2336,7 @@ class CategoryParameterTemplateCreate(AjaxCreateView): class CategoryParameterTemplateEdit(AjaxUpdateView): """ View for editing a PartCategoryParameterTemplate """ - role_required = 'part.change' + role_required = 'part_category.change' model = PartCategoryParameterTemplate form_class = part_forms.EditCategoryParameterTemplateForm @@ -2395,7 +2395,7 @@ class CategoryParameterTemplateEdit(AjaxUpdateView): class CategoryParameterTemplateDelete(AjaxDeleteView): """ View for deleting an existing PartCategoryParameterTemplate """ - role_required = 'part.delete' + role_required = 'part_category.change' model = PartCategoryParameterTemplate ajax_form_title = _("Delete Category Parameter Template") diff --git a/InvenTree/stock/templates/stock/location.html b/InvenTree/stock/templates/stock/location.html index fef3428373..765a4bd903 100644 --- a/InvenTree/stock/templates/stock/location.html +++ b/InvenTree/stock/templates/stock/location.html @@ -8,7 +8,7 @@ {% if location %}

{{ location.name }} - {% if user.is_staff and roles.stock.change %} + {% if user.is_staff and roles.stock_location.change %} {% endif %}

@@ -18,7 +18,7 @@

{% trans "All stock items" %}

{% endif %}
- {% if roles.stock.add %} + {% if roles.stock_location.add %} @@ -41,11 +41,13 @@ {% trans "Count stock" %}
+ {% endif %} + {% if roles.stock_location.change %}
diff --git a/InvenTree/stock/templates/stock/location_list.html b/InvenTree/stock/templates/stock/location_list.html index 4ad30e1310..a2ea4a361a 100644 --- a/InvenTree/stock/templates/stock/location_list.html +++ b/InvenTree/stock/templates/stock/location_list.html @@ -1,6 +1,6 @@ {% extends "collapse.html" %} -{% if roles.stock.view %} +{% if roles.stock_location.view or roles.stock.view %} {% block collapse_title %} Sub-Locations{{ children|length }} {% endblock %} diff --git a/InvenTree/stock/views.py b/InvenTree/stock/views.py index ab6f64fb44..830f2c66f7 100644 --- a/InvenTree/stock/views.py +++ b/InvenTree/stock/views.py @@ -73,7 +73,7 @@ class StockLocationDetail(InvenTreeRoleMixin, DetailView): template_name = 'stock/location.html' queryset = StockLocation.objects.all() model = StockLocation - role_required = 'stock.view' + role_required = ['stock_location.view', 'stock.view'] class StockItemDetail(InvenTreeRoleMixin, DetailView): @@ -121,7 +121,7 @@ class StockLocationEdit(AjaxUpdateView): context_object_name = 'location' ajax_template_name = 'modal_form.html' ajax_form_title = _('Edit Stock Location') - role_required = 'stock.change' + role_required = 'stock_location.change' def get_form(self): """ Customize form data for StockLocation editing. @@ -146,7 +146,7 @@ class StockLocationQRCode(QRCodeView): """ View for displaying a QR code for a StockLocation object """ ajax_form_title = _("Stock Location QR code") - role_required = 'stock.view' + role_required = ['stock_location.view', 'stock.view'] def get_qr_data(self): """ Generate QR code data for the StockLocation """ @@ -1361,7 +1361,7 @@ class StockLocationCreate(AjaxCreateView): context_object_name = 'location' ajax_template_name = 'modal_form.html' ajax_form_title = _('Create new Stock Location') - role_required = 'stock.add' + role_required = 'stock_location.add' def get_initial(self): initials = super(StockLocationCreate, self).get_initial().copy() @@ -1748,7 +1748,7 @@ class StockLocationDelete(AjaxDeleteView): ajax_template_name = 'stock/location_delete.html' context_object_name = 'location' ajax_form_title = _('Delete Stock Location') - role_required = 'stock.delete' + role_required = 'stock_location.delete' class StockItemDelete(AjaxDeleteView): diff --git a/InvenTree/users/admin.py b/InvenTree/users/admin.py index 29496d02a7..c84f1310ce 100644 --- a/InvenTree/users/admin.py +++ b/InvenTree/users/admin.py @@ -30,6 +30,8 @@ class RuleSetInline(admin.TabularInline): max_num = len(RuleSet.RULESET_CHOICES) min_num = 1 extra = 0 + # TODO: find better way to order inlines + ordering = ['name'] class InvenTreeGroupAdminForm(forms.ModelForm): @@ -87,7 +89,8 @@ class RoleGroupAdmin(admin.ModelAdmin): RuleSetInline, ] - list_display = ('name', 'admin', 'part', 'stock', 'build', 'purchase_order', 'sales_order') + list_display = ('name', 'admin', 'part_category', 'part', 'stock_location', + 'stock_item', 'build', 'purchase_order', 'sales_order') def get_rule_set(self, obj, rule_set_type): ''' Return list of permissions for the given ruleset ''' @@ -130,10 +133,16 @@ class RoleGroupAdmin(admin.ModelAdmin): def admin(self, obj): return self.get_rule_set(obj, 'admin') + def part_category(self, obj): + return self.get_rule_set(obj, 'part_category') + def part(self, obj): return self.get_rule_set(obj, 'part') - def stock(self, obj): + def stock_location(self, obj): + return self.get_rule_set(obj, 'stock_location') + + def stock_item(self, obj): return self.get_rule_set(obj, 'stock') def build(self, obj): diff --git a/InvenTree/users/models.py b/InvenTree/users/models.py index b54cddf7c4..776514fc9f 100644 --- a/InvenTree/users/models.py +++ b/InvenTree/users/models.py @@ -25,8 +25,10 @@ class RuleSet(models.Model): RULESET_CHOICES = [ ('admin', _('Admin')), + ('part_category', _('Part Categories')), ('part', _('Parts')), - ('stock', _('Stock')), + ('stock_location', _('Stock Locations')), + ('stock', _('Stock Items')), ('build', _('Build Orders')), ('purchase_order', _('Purchase Orders')), ('sales_order', _('Sales Orders')), @@ -48,21 +50,25 @@ class RuleSet(models.Model): 'authtoken_token', 'users_ruleset', ], + 'part_category': [ + 'part_partcategory', + 'part_partcategoryparametertemplate', + ], 'part': [ 'part_part', 'part_bomitem', - 'part_partcategory', 'part_partattachment', 'part_partsellpricebreak', 'part_parttesttemplate', 'part_partparametertemplate', 'part_partparameter', 'part_partrelated', - 'part_partcategoryparametertemplate', + ], + 'stock_location': [ + 'stock_stocklocation', ], 'stock': [ 'stock_stockitem', - 'stock_stocklocation', 'stock_stockitemattachment', 'stock_stockitemtracking', 'stock_stockitemtestresult', From af1abb7129b04763d344cb535a9f437a5aeb28bc Mon Sep 17 00:00:00 2001 From: eeintech Date: Wed, 13 Jan 2021 14:57:16 -0500 Subject: [PATCH 05/25] Added missing migration file --- .../migrations/0004_auto_20210113_1909.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 InvenTree/users/migrations/0004_auto_20210113_1909.py diff --git a/InvenTree/users/migrations/0004_auto_20210113_1909.py b/InvenTree/users/migrations/0004_auto_20210113_1909.py new file mode 100644 index 0000000000..d762dc4c08 --- /dev/null +++ b/InvenTree/users/migrations/0004_auto_20210113_1909.py @@ -0,0 +1,18 @@ +# Generated by Django 3.0.7 on 2021-01-13 19:09 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('users', '0003_auto_20201005_2227'), + ] + + operations = [ + migrations.AlterField( + model_name='ruleset', + name='name', + field=models.CharField(choices=[('admin', 'Admin'), ('part_category', 'Part Categories'), ('part', 'Parts'), ('stock_location', 'Stock Locations'), ('stock', 'Stock Items'), ('build', 'Build Orders'), ('purchase_order', 'Purchase Orders'), ('sales_order', 'Sales Orders')], help_text='Permission set', max_length=50), + ), + ] From 890ce9ef956fa132eceab737fbf24d66f94e2133 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Thu, 14 Jan 2021 10:58:29 +1100 Subject: [PATCH 06/25] Fix IPN comparison against null value --- InvenTree/part/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/InvenTree/part/views.py b/InvenTree/part/views.py index 0e16bfb498..26cf93e56d 100644 --- a/InvenTree/part/views.py +++ b/InvenTree/part/views.py @@ -1320,7 +1320,7 @@ class BomUpload(InvenTreeRoleMixin, FormView): # Otherwise, check to see if there is a matching IPN try: if row['part_ipn']: - part_matches = [part for part in self.allowed_parts if row['part_ipn'].lower() == part.IPN.lower()] + part_matches = [part for part in self.allowed_parts if part.IPN and row['part_ipn'].lower() == str(part.IPN.lower())] # Check for single match if len(part_matches) == 1: From 1316e6bf5b8134d4586f9ed8643bfe2e28c99854 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Thu, 14 Jan 2021 11:24:52 +1100 Subject: [PATCH 07/25] Properly save user data when creating a new StockItem --- InvenTree/stock/views.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/InvenTree/stock/views.py b/InvenTree/stock/views.py index 830f2c66f7..5d505b5280 100644 --- a/InvenTree/stock/views.py +++ b/InvenTree/stock/views.py @@ -1721,7 +1721,7 @@ class StockItemCreate(AjaxCreateView): item = form.save(commit=False) item.user = self.request.user - item.save() + item.save(user=self.request.user) return item @@ -1732,7 +1732,7 @@ class StockItemCreate(AjaxCreateView): item = form.save(commit=False) item.user = self.request.user - item.save() + item.save(user=self.request.user) return item From df327d4e6418810f898a3556ba55d59321c3f63c Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Thu, 14 Jan 2021 11:29:35 +1100 Subject: [PATCH 08/25] Add stocktake_date field to stock API, and to stock table --- InvenTree/InvenTree/static/script/inventree/tables.js | 3 +-- InvenTree/stock/serializers.py | 1 + InvenTree/templates/js/stock.js | 5 +++++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/InvenTree/InvenTree/static/script/inventree/tables.js b/InvenTree/InvenTree/static/script/inventree/tables.js index 1a50780393..4d868f94b4 100644 --- a/InvenTree/InvenTree/static/script/inventree/tables.js +++ b/InvenTree/InvenTree/static/script/inventree/tables.js @@ -131,8 +131,7 @@ $.fn.inventreeTable = function(options) { // Callback when a column is changed options.onColumnSwitch = function(field, checked) { - console.log(`${field} -> ${checked}`); - + var columns = table.bootstrapTable('getVisibleColumns'); var text = visibleColumnString(columns); diff --git a/InvenTree/stock/serializers.py b/InvenTree/stock/serializers.py index 70ad1abc18..6048d5e248 100644 --- a/InvenTree/stock/serializers.py +++ b/InvenTree/stock/serializers.py @@ -208,6 +208,7 @@ class StockItemSerializer(InvenTreeModelSerializer): 'stale', 'status', 'status_text', + 'stocktake_date', 'supplier_part', 'supplier_part_detail', 'tracking_items', diff --git a/InvenTree/templates/js/stock.js b/InvenTree/templates/js/stock.js index e3f124d252..9ce395db57 100644 --- a/InvenTree/templates/js/stock.js +++ b/InvenTree/templates/js/stock.js @@ -590,6 +590,11 @@ function loadStockTable(table, options) { return locationDetail(row); } }, + { + field: 'stocktake_date', + title: '{% trans "Stocktake" %}', + sortable: true, + }, {% settings_value "STOCK_ENABLE_EXPIRY" as expiry %} {% if expiry %} { From 1cb951bd0b682030255292eba236a042c42d99dc Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Thu, 14 Jan 2021 12:08:54 +1100 Subject: [PATCH 09/25] Fix for font-awesome icon --- InvenTree/part/templates/part/detail.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/InvenTree/part/templates/part/detail.html b/InvenTree/part/templates/part/detail.html index f723193abb..59c33ea7b6 100644 --- a/InvenTree/part/templates/part/detail.html +++ b/InvenTree/part/templates/part/detail.html @@ -214,9 +214,9 @@ {% if part.active %} - + {% else %} - + {% endif %} {% trans "Active" %} From d45994794981682064a1c6d5f7a05965f36c7733 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Thu, 14 Jan 2021 13:34:51 +1100 Subject: [PATCH 10/25] Add "Can Build" column in BOM view --- InvenTree/templates/js/bom.js | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/InvenTree/templates/js/bom.js b/InvenTree/templates/js/bom.js index 299045cfa5..e1b3b46cc0 100644 --- a/InvenTree/templates/js/bom.js +++ b/InvenTree/templates/js/bom.js @@ -255,6 +255,38 @@ function loadBomTable(table, options) { }); */ } + + cols.push( + { + 'field': 'can_build', + 'title': '{% trans "Can Build" %}', + formatter: function(value, row, index, field) { + var can_build = 0; + + if (row.quantity > 0) { + can_build = row.sub_part_detail.stock / row.quantity; + } + + return +can_build.toFixed(2); + }, + sorter: function(valA, valB, rowA, rowB) { + // Function to sort the "can build" quantity + var cb_a = 0; + var cb_b = 0; + + if (rowA.quantity > 0) { + cb_a = rowA.sub_part_detail.stock / rowA.quantity; + } + + if (rowB.quantity > 0) { + cb_b = rowB.sub_part_detail.stock / rowB.quantity; + } + + return (cb_a > cb_b) ? 1 : -1; + }, + sortable: true, + } + ) // Part notes cols.push( From aac835f634e8427c7c9689523a5d9e8ed8bef867 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Thu, 14 Jan 2021 13:41:38 +1100 Subject: [PATCH 11/25] Add menu item to set stock status for multiple items --- InvenTree/templates/js/stock.js | 8 ++++++++ InvenTree/templates/stock_table.html | 1 + 2 files changed, 9 insertions(+) diff --git a/InvenTree/templates/js/stock.js b/InvenTree/templates/js/stock.js index 9ce395db57..bc2db4098a 100644 --- a/InvenTree/templates/js/stock.js +++ b/InvenTree/templates/js/stock.js @@ -682,6 +682,14 @@ function loadStockTable(table, options) { }); }); + $("#multi-item-set-status").click(function() { + var selections = $("#stock-table").bootstrapTable('getSelections'); + + selections.forEach(function(item) { + // TODO + }); + }); + $("#multi-item-delete").click(function() { var selections = $("#stock-table").bootstrapTable("getSelections"); diff --git a/InvenTree/templates/stock_table.html b/InvenTree/templates/stock_table.html index 51f7c277db..f39f9c733a 100644 --- a/InvenTree/templates/stock_table.html +++ b/InvenTree/templates/stock_table.html @@ -23,6 +23,7 @@
  • {% trans "Count stock" %}
  • {% trans "Move stock" %}
  • {% trans "Order stock" %}
  • +
  • {% trans "Change stock status" %}
  • {% endif %} {% if roles.stock.delete %}
  • {% trans "Delete Stock" %}
  • From bb9fe98a7edd50d07b41e02730549f6e358f1b92 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Thu, 14 Jan 2021 14:04:24 +1100 Subject: [PATCH 12/25] Set status for multiple stock items at once --- InvenTree/templates/js/stock.js | 97 +++++++++++++++++++++++++++++++-- 1 file changed, 93 insertions(+), 4 deletions(-) diff --git a/InvenTree/templates/js/stock.js b/InvenTree/templates/js/stock.js index bc2db4098a..e9cb5e2696 100644 --- a/InvenTree/templates/js/stock.js +++ b/InvenTree/templates/js/stock.js @@ -6,8 +6,18 @@ * Requires api.js to be loaded first */ -/* Functions for interacting with stock management forms - */ + +function stockStatusCodes() { + return [ + {% for code in StockStatus.list %} + { + key: {{ code.key }}, + text: "{{ code.value }}", + }, + {% endfor %} + ]; +} + function removeStockRow(e) { // Remove a selected row from a stock modal form @@ -683,11 +693,90 @@ function loadStockTable(table, options) { }); $("#multi-item-set-status").click(function() { + // Select and set the STATUS field for selected stock items var selections = $("#stock-table").bootstrapTable('getSelections'); - selections.forEach(function(item) { - // TODO + // Select stock status + var modal = '#modal-form'; + + var status_list = makeOptionsList( + stockStatusCodes(), + function(item) { + return item.text; + }, + function (item) { + return item.key; + } + ); + + // Add an empty option at the start of the list + status_list.unshift(''); + + // Construct form + var html = ` +
    +
    + +
    + +
    +
    +
    `; + + openModal({ + modal: modal, }); + + modalEnable(modal, true); + modalSetTitle(modal, '{% trans "Set Stock Status" %}'); + modalSetContent(modal, html); + + attachSelect(modal); + + modalSubmit(modal, function() { + var label = $(modal).find('#id_status'); + + var status_code = label.val(); + + closeModal(modal); + + if (!status_code) { + showAlertDialog( + '{% trans "Select Status Code" %}', + '{% trans "Status code must be selected" %}' + ); + + return; + } + + var requests = []; + + selections.forEach(function(item) { + var url = `/api/stock/${item.pk}/`; + + requests.push( + inventreePut( + url, + { + status: status_code, + }, + { + method: 'PATCH', + success: function() { + } + } + ) + ); + }); + + $.when.apply($, requests).then(function() { + $("#stock-table").bootstrapTable('refresh'); + }); + }) }); $("#multi-item-delete").click(function() { From be41741b1e5d4250c707b037879701d36357a090 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Thu, 14 Jan 2021 14:37:49 +1100 Subject: [PATCH 13/25] Bug fix for cancelling purchase orders --- InvenTree/order/models.py | 6 +++++- InvenTree/order/templates/order/order_base.html | 2 +- InvenTree/order/views.py | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/InvenTree/order/models.py b/InvenTree/order/models.py index 184452f24e..23d07a0c2e 100644 --- a/InvenTree/order/models.py +++ b/InvenTree/order/models.py @@ -257,7 +257,11 @@ class PurchaseOrder(Order): self.save() def can_cancel(self): - return self.status not in [ + """ + A PurchaseOrder can only be cancelled under the following circumstances: + """ + + return self.status in [ PurchaseOrderStatus.PLACED, PurchaseOrderStatus.PENDING ] diff --git a/InvenTree/order/templates/order/order_base.html b/InvenTree/order/templates/order/order_base.html index d3e1e02437..fa45bbfe41 100644 --- a/InvenTree/order/templates/order/order_base.html +++ b/InvenTree/order/templates/order/order_base.html @@ -47,7 +47,7 @@ src="{% static 'img/blank_image.png' %}" {% endif %} - {% if order.status == PurchaseOrderStatus.PENDING or order.status == PurchaseOrderStatus.PLACED %} + {% if order.can_cancel %} diff --git a/InvenTree/order/views.py b/InvenTree/order/views.py index bd758e39fb..091b11e825 100644 --- a/InvenTree/order/views.py +++ b/InvenTree/order/views.py @@ -432,7 +432,7 @@ class PurchaseOrderCancel(AjaxUpdateView): form.add_error('confirm', _('Confirm order cancellation')) if not order.can_cancel(): - form.add_error(None, _('Order cannot be cancelled as either pending or placed')) + form.add_error(None, _('Order cannot be cancelled')) def save(self, order, form, **kwargs): """ From 1dc2636e456a4d5d6364f7ee46788d7f8b46cf66 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Thu, 14 Jan 2021 15:20:42 +1100 Subject: [PATCH 14/25] Add option to show part quantity in various forms Enabling this option can make BOM item forms *very* slow! --- InvenTree/common/models.py | 7 +++++++ InvenTree/part/forms.py | 12 +++++++++++- InvenTree/part/models.py | 8 +++++++- InvenTree/templates/InvenTree/settings/part.html | 1 + 4 files changed, 26 insertions(+), 2 deletions(-) diff --git a/InvenTree/common/models.py b/InvenTree/common/models.py index 5c04f9a7e9..4a6bde8bfe 100644 --- a/InvenTree/common/models.py +++ b/InvenTree/common/models.py @@ -160,6 +160,13 @@ class InvenTreeSetting(models.Model): 'validator': bool, }, + 'PART_SHOW_QUANTITY_IN_FORMS': { + 'name': _('Show Quantity in Forms'), + 'description': _('Display available part quantity in some forms'), + 'default': True, + 'validator': bool, + }, + 'STOCK_ENABLE_EXPIRY': { 'name': _('Stock Expiry'), 'description': _('Enable stock expiry functionality'), diff --git a/InvenTree/part/forms.py b/InvenTree/part/forms.py index 1ac62161a5..16518937ae 100644 --- a/InvenTree/part/forms.py +++ b/InvenTree/part/forms.py @@ -13,6 +13,8 @@ from mptt.fields import TreeNodeChoiceField from django import forms from django.utils.translation import ugettext as _ +import common.models + from .models import Part, PartCategory, PartAttachment, PartRelated from .models import BomItem from .models import PartParameterTemplate, PartParameter @@ -23,8 +25,16 @@ from .models import PartSellPriceBreak class PartModelChoiceField(forms.ModelChoiceField): """ Extending string representation of Part instance with available stock """ + def label_from_instance(self, part): - return f'{part} - {part.available_stock}' + + label = str(part) + + # Optionally display available part quantity + if common.models.InvenTreeSetting.get_setting('PART_SHOW_QUANTITY_IN_FORMS'): + label += f" - {part.available_stock}" + + return label class PartImageForm(HelperForm): diff --git a/InvenTree/part/models.py b/InvenTree/part/models.py index 8c88adf747..a45220c7ab 100644 --- a/InvenTree/part/models.py +++ b/InvenTree/part/models.py @@ -1990,7 +1990,13 @@ class BomItem(models.Model): Return the available stock items for the referenced sub_part """ - query = self.sub_part.stock_items.filter(StockModels.StockItem.IN_STOCK_FILTER).aggregate( + query = self.sub_part.stock_items.all() + + query = query.prefetch_related([ + 'sub_part__stock_items', + ]) + + query = query.filter(StockModels.StockItem.IN_STOCK_FILTER).aggregate( available=Coalesce(Sum('quantity'), 0) ) diff --git a/InvenTree/templates/InvenTree/settings/part.html b/InvenTree/templates/InvenTree/settings/part.html index fe46911dae..9174b2f127 100644 --- a/InvenTree/templates/InvenTree/settings/part.html +++ b/InvenTree/templates/InvenTree/settings/part.html @@ -18,6 +18,7 @@ {% include "InvenTree/settings/setting.html" with key="PART_IPN_REGEX" %} {% include "InvenTree/settings/setting.html" with key="PART_ALLOW_DUPLICATE_IPN" %} + {% include "InvenTree/settings/setting.html" with key="PART_SHOW_QUANTITY_IN_FORMS" icon="fa-hashtag" %} {% include "InvenTree/settings/setting.html" with key="PART_TEMPLATE" icon="fa-clone" %} {% include "InvenTree/settings/setting.html" with key="PART_ASSEMBLY" icon="fa-tools" %} From 834d9ec9a1cd7f0f066a5f0235758d6846e13138 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Thu, 14 Jan 2021 17:28:57 +1100 Subject: [PATCH 15/25] Add "target_date" field to PurchaseOrder --- .../migrations/0041_auto_20210114_1728.py | 28 +++++++++++++++++++ InvenTree/order/models.py | 21 ++++++++++++-- 2 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 InvenTree/order/migrations/0041_auto_20210114_1728.py diff --git a/InvenTree/order/migrations/0041_auto_20210114_1728.py b/InvenTree/order/migrations/0041_auto_20210114_1728.py new file mode 100644 index 0000000000..09be471433 --- /dev/null +++ b/InvenTree/order/migrations/0041_auto_20210114_1728.py @@ -0,0 +1,28 @@ +# Generated by Django 3.0.7 on 2021-01-14 06:28 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('order', '0040_salesorder_target_date'), + ] + + operations = [ + migrations.AddField( + model_name='purchaseorder', + name='target_date', + field=models.DateField(blank=True, help_text='Expected date for order delivery. Order will be overdue after this date.', null=True, verbose_name='Target Delivery Date'), + ), + migrations.AlterField( + model_name='purchaseorder', + name='complete_date', + field=models.DateField(blank=True, help_text='Date order was completed', null=True, verbose_name='Completion Date'), + ), + migrations.AlterField( + model_name='purchaseorder', + name='issue_date', + field=models.DateField(blank=True, help_text='Date order was issued', null=True, verbose_name='Issue Date'), + ), + ] diff --git a/InvenTree/order/models.py b/InvenTree/order/models.py index 23d07a0c2e..3a86cf4306 100644 --- a/InvenTree/order/models.py +++ b/InvenTree/order/models.py @@ -119,8 +119,11 @@ class PurchaseOrder(Order): supplier: Reference to the company supplying the goods in the order supplier_reference: Optional field for supplier order reference code received_by: User that received the goods + target_date: Expected delivery target date for PurchaseOrder completion (optional) """ + OVERDUE_FILTER = Q(status__in=PurchaseOrderStatus.OPEN) & ~Q(target_date=None) & Q(target_date__lte=datetime.now().date()) + @staticmethod def filterByDate(queryset, min_date, max_date): """ @@ -186,9 +189,23 @@ class PurchaseOrder(Order): related_name='+' ) - issue_date = models.DateField(blank=True, null=True, help_text=_('Date order was issued')) + issue_date = models.DateField( + blank=True, null=True, + verbose_name=_('Issue Date'), + help_text=_('Date order was issued') + ) - complete_date = models.DateField(blank=True, null=True, help_text=_('Date order was completed')) + target_date = models.DateField( + blank=True, null=True, + verbose_name=_('Target Delivery Date'), + help_text=_('Expected date for order delivery. Order will be overdue after this date.'), + ) + + complete_date = models.DateField( + blank=True, null=True, + verbose_name=_('Completion Date'), + help_text=_('Date order was completed') + ) def get_absolute_url(self): return reverse('po-detail', kwargs={'pk': self.id}) From 4d73aab090f3c5b0512fce4573d43dfe49c97788 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Thu, 14 Jan 2021 17:33:24 +1100 Subject: [PATCH 16/25] Add "overdue" flag to serializer - Also allow filtering by overdue status in the API --- InvenTree/order/api.py | 11 +++++++++++ InvenTree/order/serializers.py | 15 +++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/InvenTree/order/api.py b/InvenTree/order/api.py index 972ff16f9c..ce75a47697 100644 --- a/InvenTree/order/api.py +++ b/InvenTree/order/api.py @@ -80,6 +80,17 @@ class POList(generics.ListCreateAPIView): else: queryset = queryset.exclude(status__in=PurchaseOrderStatus.OPEN) + # Filter by 'overdue' status + overdue = params.get('overdue', None) + + if overdue is not None: + overdue = str2bool(overdue) + + if overdue: + queryset = queryset.filter(PurchaseOrder.OVERDUE_FILTER) + else: + queryset = queryset.exclude(PurchaseOrder.OVERDUE_FILTER) + # Special filtering for 'status' field status = params.get('status', None) diff --git a/InvenTree/order/serializers.py b/InvenTree/order/serializers.py index 5463feb26f..264523bb40 100644 --- a/InvenTree/order/serializers.py +++ b/InvenTree/order/serializers.py @@ -40,12 +40,24 @@ class POSerializer(InvenTreeModelSerializer): def annotate_queryset(queryset): """ Add extra information to the queryset + + - Number of liens in the PurchaseOrder + - Overdue status of the PurchaseOrder """ queryset = queryset.annotate( line_items=SubqueryCount('lines') ) + queryset = queryset.annotate( + overdue=Case( + When( + PurchaseOrder.OVERDUE_FILTER, then=Value(True, output_field=BooleanField()), + ), + default=Value(False, output_field=BooleanField()) + ) + ) + return queryset supplier_detail = CompanyBriefSerializer(source='supplier', many=False, read_only=True) @@ -54,6 +66,8 @@ class POSerializer(InvenTreeModelSerializer): status_text = serializers.CharField(source='get_status_display', read_only=True) + overdue = serializers.BooleanField(required=False, read_only=True) + class Meta: model = PurchaseOrder @@ -65,6 +79,7 @@ class POSerializer(InvenTreeModelSerializer): 'description', 'line_items', 'link', + 'overdue', 'reference', 'supplier', 'supplier_detail', From a8e6d0a89ff75ad583ba69cfd07049763b7ca39b Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Thu, 14 Jan 2021 17:37:10 +1100 Subject: [PATCH 17/25] Display overdue status in purchase order table - Allow table to be filtered by "overdue" status --- InvenTree/order/serializers.py | 1 + InvenTree/templates/js/order.js | 25 ++++++++++++++++++------- InvenTree/templates/js/table_filters.js | 4 ++++ 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/InvenTree/order/serializers.py b/InvenTree/order/serializers.py index 264523bb40..a04798c303 100644 --- a/InvenTree/order/serializers.py +++ b/InvenTree/order/serializers.py @@ -86,6 +86,7 @@ class POSerializer(InvenTreeModelSerializer): 'supplier_reference', 'status', 'status_text', + 'target_date', 'notes', ] diff --git a/InvenTree/templates/js/order.js b/InvenTree/templates/js/order.js index 18c315d17e..53063cd709 100644 --- a/InvenTree/templates/js/order.js +++ b/InvenTree/templates/js/order.js @@ -141,9 +141,9 @@ function loadPurchaseOrderTable(table, options) { switchable: false, }, { - sortable: true, field: 'reference', title: '{% trans "Purchase Order" %}', + sortable: true, switchable: false, formatter: function(value, row, index, field) { @@ -153,13 +153,19 @@ function loadPurchaseOrderTable(table, options) { value = `${prefix}${value}`; } - return renderLink(value, `/order/purchase-order/${row.pk}/`); + var html = renderLink(value, `/order/purchase-order/${row.pk}/`); + + if (row.overdue) { + html += makeIconBadge('fa-calendar-times icon-red', '{% trans "Order is overdue" %}'); + } + + return html; } }, { - sortable: true, field: 'supplier_detail', title: '{% trans "Supplier" %}', + sortable: true, formatter: function(value, row, index, field) { return imageHoverIcon(row.supplier_detail.image) + renderLink(row.supplier_detail.name, `/company/${row.supplier}/purchase-orders/`); } @@ -170,27 +176,32 @@ function loadPurchaseOrderTable(table, options) { sortable: true, }, { - sortable: true, field: 'description', title: '{% trans "Description" %}', + sortable: true, }, { - sortable: true, field: 'status', title: '{% trans "Status" %}', + sortable: true, formatter: function(value, row, index, field) { return purchaseOrderStatusDisplay(row.status, row.status_text); } }, { - sortable: true, field: 'creation_date', title: '{% trans "Date" %}', + sortable: true, }, { + field: 'target_date', + title: '{% trans "Target Date" %}', sortable: true, + }, + { field: 'line_items', - title: '{% trans "Items" %}' + title: '{% trans "Items" %}', + sortable: true, }, ], }); diff --git a/InvenTree/templates/js/table_filters.js b/InvenTree/templates/js/table_filters.js index 84aa12c139..81f72fb26d 100644 --- a/InvenTree/templates/js/table_filters.js +++ b/InvenTree/templates/js/table_filters.js @@ -214,6 +214,10 @@ function getAvailableTableFilters(tableKey) { type: 'bool', title: '{% trans "Outstanding" %}', }, + overdue: { + type: 'bool', + title: '{% trans "Overdue" %}', + }, }; } From 21e8ddd1e622f4bc9c5de1b923365630d69beff6 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Thu, 14 Jan 2021 17:42:38 +1100 Subject: [PATCH 18/25] Display overdue status on PurcahseOrder page --- InvenTree/order/models.py | 24 ++++++++++++------- .../order/templates/order/order_base.html | 21 ++++++++++++++-- 2 files changed, 35 insertions(+), 10 deletions(-) diff --git a/InvenTree/order/models.py b/InvenTree/order/models.py index 3a86cf4306..65729ab993 100644 --- a/InvenTree/order/models.py +++ b/InvenTree/order/models.py @@ -273,6 +273,18 @@ class PurchaseOrder(Order): self.complete_date = datetime.now().date() self.save() + def is_overdue(self): + """ + Returns True if this PurchaseOrder is "overdue" + + Makes use of the OVERDUE_FILTER to avoid code duplication. + """ + + query = PurchaseOrder.objects.filter(pk=self.pk) + query = query.filter(PurchaseOrder.OVERDUE_FILTER) + + return query.exists() + def can_cancel(self): """ A PurchaseOrder can only be cancelled under the following circumstances: @@ -440,17 +452,13 @@ class SalesOrder(Order): """ Returns true if this SalesOrder is "overdue": - - Not completed - - Target date is "in the past" + Makes use of the OVERDUE_FILTER to avoid code duplication. """ - # Order cannot be deemed overdue if target_date is not set - if self.target_date is None: - return False + query = SalesOrder.objects.filter(pk=self.pk) + query = query.filer(SalesOrder.OVERDUE_FILTER) - today = datetime.now().date() - - return self.is_pending and self.target_date < today + return query.exists() @property def is_pending(self): diff --git a/InvenTree/order/templates/order/order_base.html b/InvenTree/order/templates/order/order_base.html index fa45bbfe41..4e67325e48 100644 --- a/InvenTree/order/templates/order/order_base.html +++ b/InvenTree/order/templates/order/order_base.html @@ -26,7 +26,12 @@ src="{% static 'img/blank_image.png' %}" {% endif %} -

    {% purchase_order_status_label order.status large=True %}

    +

    + {% purchase_order_status_label order.status large=True %} + {% if order.is_overdue %} + {% trans "Overdue" %} + {% endif %} +


    {{ order.description }}

    @@ -72,7 +77,12 @@ src="{% static 'img/blank_image.png' %}" {% trans "Order Status" %} - {% purchase_order_status_label order.status %} + + {% purchase_order_status_label order.status %} + {% if order.is_overdue %} + {% trans "Overdue" %} + {% endif %} + @@ -105,6 +115,13 @@ src="{% static 'img/blank_image.png' %}" {{ order.issue_date }} {% endif %} + {% if order.target_date %} + + + {% trans "Target Date" %} + {{ order.target_date }} + + {% endif %} {% if order.status == PurchaseOrderStatus.COMPLETE %} From e8fd597f2958e95a3203a46532859b4a4467f137 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Thu, 14 Jan 2021 17:44:21 +1100 Subject: [PATCH 19/25] Adds ability to edit target_date in purchaseorder form --- InvenTree/order/forms.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/InvenTree/order/forms.py b/InvenTree/order/forms.py index 6db51b55e6..808ab7ed29 100644 --- a/InvenTree/order/forms.py +++ b/InvenTree/order/forms.py @@ -94,6 +94,7 @@ class EditPurchaseOrderForm(HelperForm): self.field_prefix = { 'reference': 'PO', 'link': 'fa-link', + 'target_date': 'fa-calendar-alt', } self.field_placeholder = { @@ -102,6 +103,10 @@ class EditPurchaseOrderForm(HelperForm): super().__init__(*args, **kwargs) + target_date = DatePickerFormField( + help_text=_('Target date for order delivery. Order will be overdue after this date.'), + ) + class Meta: model = PurchaseOrder fields = [ @@ -109,6 +114,7 @@ class EditPurchaseOrderForm(HelperForm): 'supplier', 'supplier_reference', 'description', + 'target_date', 'link', ] From 75e1442fceb1074dea8665c484235f30045c49f8 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Thu, 14 Jan 2021 17:48:16 +1100 Subject: [PATCH 20/25] Display overdue purchase orders on the index page --- InvenTree/templates/InvenTree/index.html | 10 ++++++++++ InvenTree/templates/InvenTree/po_overdue.html | 15 +++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 InvenTree/templates/InvenTree/po_overdue.html diff --git a/InvenTree/templates/InvenTree/index.html b/InvenTree/templates/InvenTree/index.html index 1b9a492a22..36e4f8bc49 100644 --- a/InvenTree/templates/InvenTree/index.html +++ b/InvenTree/templates/InvenTree/index.html @@ -35,6 +35,7 @@ InvenTree | {% trans "Index" %} {% if roles.purchase_order.view %} {% include "InvenTree/po_outstanding.html" with collapse_id="po_outstanding" %} {% endif %} + {% include "InvenTree/po_overdue.html" with collapse_id="po_overdue" %} {% if roles.sales_order.view %} {% include "InvenTree/so_outstanding.html" with collapse_id="so_outstanding" %} {% include "InvenTree/so_overdue.html" with collapse_id="so_overdue" %} @@ -130,6 +131,14 @@ loadPurchaseOrderTable("#po-outstanding-table", { } }); +loadPurchaseOrderTable("#po-overdue-table", { + url: "{% url 'api-po-list' %}", + params: { + supplier_detail: true, + overdue: true, + } +}); + loadSalesOrderTable("#so-outstanding-table", { url: "{% url 'api-so-list' %}", params: { @@ -158,6 +167,7 @@ loadSalesOrderTable("#so-overdue-table", { {% include "InvenTree/index/on_load.html" with label="stock-to-build" %} {% include "InvenTree/index/on_load.html" with label="po-outstanding" %} +{% include "InvenTree/index/on_load.html" with label="po-overdue" %} {% include "InvenTree/index/on_load.html" with label="so-outstanding" %} {% include "InvenTree/index/on_load.html" with label="so-overdue" %} diff --git a/InvenTree/templates/InvenTree/po_overdue.html b/InvenTree/templates/InvenTree/po_overdue.html new file mode 100644 index 0000000000..99e3e7d40f --- /dev/null +++ b/InvenTree/templates/InvenTree/po_overdue.html @@ -0,0 +1,15 @@ +{% extends "collapse_index.html" %} + +{% load i18n %} + +{% block collapse_title %} + +{% trans "Overdue Purchase Orders" %} +{% endblock %} + +{% block collapse_content %} + + +
    + +{% endblock %} \ No newline at end of file From 02132fa495342dbb2eb4d83c5e9ede31b97103df Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Thu, 14 Jan 2021 17:55:00 +1100 Subject: [PATCH 21/25] Updated translation files --- InvenTree/locale/de/LC_MESSAGES/django.po | 606 ++++++++++++---------- InvenTree/locale/en/LC_MESSAGES/django.po | 592 +++++++++++---------- InvenTree/locale/es/LC_MESSAGES/django.po | 592 +++++++++++---------- 3 files changed, 1000 insertions(+), 790 deletions(-) diff --git a/InvenTree/locale/de/LC_MESSAGES/django.po b/InvenTree/locale/de/LC_MESSAGES/django.po index 31e3f80413..dd0eb2089c 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: 2021-01-07 23:48+1100\n" +"POT-Creation-Date: 2021-01-14 17:54+1100\n" "PO-Revision-Date: 2020-05-03 11:32+0200\n" "Last-Translator: Christian Schlüter \n" "Language-Team: C \n" @@ -61,7 +61,7 @@ msgstr "" msgid "Select Category" msgstr "Teilkategorie auswählen" -#: InvenTree/helpers.py:361 order/models.py:216 order/models.py:298 +#: InvenTree/helpers.py:361 order/models.py:233 order/models.py:331 #: stock/views.py:1660 msgid "Invalid quantity provided" msgstr "Keine gültige Menge" @@ -105,7 +105,7 @@ msgstr "Datei zum Anhängen auswählen" msgid "File comment" msgstr "Datei-Kommentar" -#: InvenTree/models.py:68 templates/js/stock.js:759 +#: InvenTree/models.py:68 templates/js/stock.js:861 msgid "User" msgstr "Benutzer" @@ -338,7 +338,7 @@ msgstr "" #: build/forms.py:78 build/templates/build/auto_allocate.html:17 #: build/templates/build/build_base.html:83 -#: build/templates/build/detail.html:29 common/models.py:589 +#: build/templates/build/detail.html:29 common/models.py:596 #: company/forms.py:112 company/templates/company/supplier_part_pricing.html:75 #: order/templates/order/order_wizard/select_parts.html:32 #: order/templates/order/purchase_order_detail.html:179 @@ -351,8 +351,8 @@ msgstr "" #: stock/templates/stock/item_base.html:46 #: stock/templates/stock/item_base.html:214 #: stock/templates/stock/stock_adjust.html:18 templates/js/barcode.js:338 -#: templates/js/bom.js:195 templates/js/build.js:420 templates/js/stock.js:750 -#: templates/js/stock.js:989 +#: templates/js/bom.js:195 templates/js/build.js:420 templates/js/stock.js:852 +#: templates/js/stock.js:1091 msgid "Quantity" msgstr "Anzahl" @@ -437,7 +437,7 @@ msgstr "Bauauftrag" #: build/models.py:62 build/templates/build/index.html:8 #: build/templates/build/index.html:15 order/templates/order/so_builds.html:11 #: order/templates/order/so_tabs.html:9 part/templates/part/tabs.html:31 -#: templates/InvenTree/settings/tabs.html:28 users/models.py:30 +#: templates/InvenTree/settings/tabs.html:28 users/models.py:32 msgid "Build Orders" msgstr "Bauaufträge" @@ -460,10 +460,10 @@ msgstr "Referenz" #: part/templates/part/detail.html:51 part/templates/part/set_category.html:14 #: templates/InvenTree/search.html:147 #: templates/InvenTree/settings/header.html:9 templates/js/bom.js:180 -#: templates/js/bom.js:517 templates/js/build.js:664 templates/js/company.js:56 -#: templates/js/order.js:175 templates/js/order.js:263 templates/js/part.js:188 +#: templates/js/bom.js:549 templates/js/build.js:664 templates/js/company.js:56 +#: templates/js/order.js:180 templates/js/order.js:274 templates/js/part.js:188 #: templates/js/part.js:271 templates/js/part.js:391 templates/js/part.js:572 -#: templates/js/stock.js:501 templates/js/stock.js:731 +#: templates/js/stock.js:511 templates/js/stock.js:833 msgid "Description" msgstr "Beschreibung" @@ -484,16 +484,16 @@ msgstr "Bestellung, die diesem Bau zugwiesen ist" #: build/models.py:134 build/templates/build/auto_allocate.html:16 #: build/templates/build/build_base.html:78 -#: build/templates/build/detail.html:24 order/models.py:623 +#: build/templates/build/detail.html:24 order/models.py:652 #: order/templates/order/order_wizard/select_parts.html:30 #: order/templates/order/purchase_order_detail.html:148 #: order/templates/order/receive_parts.html:19 part/models.py:316 #: part/templates/part/part_app_base.html:7 part/templates/part/related.html:26 #: part/templates/part/set_category.html:13 templates/InvenTree/search.html:133 -#: templates/js/barcode.js:336 templates/js/bom.js:153 templates/js/bom.js:502 +#: templates/js/barcode.js:336 templates/js/bom.js:153 templates/js/bom.js:534 #: templates/js/build.js:669 templates/js/company.js:138 -#: templates/js/part.js:252 templates/js/part.js:357 templates/js/stock.js:475 -#: templates/js/stock.js:1061 +#: templates/js/part.js:252 templates/js/part.js:357 templates/js/stock.js:485 +#: templates/js/stock.js:1163 msgid "Part" msgstr "Teil" @@ -569,7 +569,7 @@ msgstr "Losnummer" msgid "Batch code for this build output" msgstr "Chargennummer für diese Bau-Ausgabe" -#: build/models.py:205 order/models.py:404 +#: build/models.py:205 order/models.py:437 msgid "Target completion date" msgstr "" @@ -592,7 +592,7 @@ msgstr "Link zu einer externen URL" #: part/templates/part/tabs.html:73 stock/forms.py:313 stock/forms.py:345 #: stock/forms.py:373 stock/models.py:463 stock/models.py:1512 #: stock/templates/stock/tabs.html:26 templates/js/barcode.js:391 -#: templates/js/bom.js:263 templates/js/stock.js:117 templates/js/stock.js:603 +#: templates/js/bom.js:295 templates/js/stock.js:127 templates/js/stock.js:618 msgid "Notes" msgstr "Notizen" @@ -643,11 +643,11 @@ 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:971 order/models.py:707 +#: build/models.py:971 order/models.py:736 msgid "StockItem is over-allocated" msgstr "Zu viele Lagerobjekte zugewiesen" -#: build/models.py:975 order/models.py:710 +#: build/models.py:975 order/models.py:739 msgid "Allocation quantity must be greater than zero" msgstr "Anzahl muss größer null sein" @@ -758,7 +758,7 @@ msgstr "Lagerobjekt dem Bau zuweisen" #: stock/templates/stock/item_base.html:244 #: stock/templates/stock/stock_adjust.html:17 #: templates/InvenTree/search.html:183 templates/js/barcode.js:337 -#: templates/js/build.js:434 templates/js/stock.js:587 +#: templates/js/build.js:434 templates/js/stock.js:597 msgid "Location" msgstr "Standort" @@ -800,9 +800,12 @@ msgstr "Admin" #: build/templates/build/build_base.html:43 #: build/templates/build/build_base.html:100 +#: order/templates/order/order_base.html:32 +#: order/templates/order/order_base.html:83 #: order/templates/order/sales_order_base.html:41 #: order/templates/order/sales_order_base.html:83 -#: templates/js/table_filters.js:200 templates/js/table_filters.js:232 +#: templates/js/table_filters.js:200 templates/js/table_filters.js:219 +#: templates/js/table_filters.js:236 msgid "Overdue" msgstr "" @@ -833,15 +836,16 @@ msgstr "Bau-Status" #: order/templates/order/receive_parts.html:24 #: stock/templates/stock/item_base.html:343 templates/InvenTree/search.html:175 #: templates/js/barcode.js:42 templates/js/build.js:697 -#: templates/js/order.js:180 templates/js/order.js:268 -#: templates/js/stock.js:574 templates/js/stock.js:997 +#: templates/js/order.js:185 templates/js/order.js:279 +#: templates/js/stock.js:584 templates/js/stock.js:1099 msgid "Status" msgstr "Status" #: build/templates/build/build_base.html:96 #: build/templates/build/detail.html:100 +#: order/templates/order/order_base.html:121 #: order/templates/order/sales_order_base.html:114 templates/js/build.js:710 -#: templates/js/order.js:281 +#: templates/js/order.js:198 templates/js/order.js:292 #, fuzzy #| msgid "Shipment Date" msgid "Target Date" @@ -857,13 +861,13 @@ msgid "Progress" msgstr "" #: build/templates/build/build_base.html:120 -#: build/templates/build/detail.html:82 order/models.py:621 +#: build/templates/build/detail.html:82 order/models.py:650 #: order/templates/order/sales_order_base.html:9 #: order/templates/order/sales_order_base.html:33 #: order/templates/order/sales_order_notes.html:10 #: order/templates/order/sales_order_ship.html:25 #: part/templates/part/allocation.html:27 -#: stock/templates/stock/item_base.html:238 templates/js/order.js:229 +#: stock/templates/stock/item_base.html:238 templates/js/order.js:240 msgid "Sales Order" msgstr "Bestellung" @@ -997,14 +1001,14 @@ msgid "Destination location not specified" msgstr "Hat dieses Teil Tracking für einzelne Objekte?" #: build/templates/build/detail.html:68 -#: stock/templates/stock/item_base.html:262 templates/js/stock.js:582 -#: templates/js/stock.js:1004 templates/js/table_filters.js:80 +#: stock/templates/stock/item_base.html:262 templates/js/stock.js:592 +#: templates/js/stock.js:1106 templates/js/table_filters.js:80 #: templates/js/table_filters.js:161 msgid "Batch" msgstr "Los" #: build/templates/build/detail.html:95 -#: order/templates/order/order_base.html:98 +#: order/templates/order/order_base.html:108 #: order/templates/order/sales_order_base.html:108 templates/js/build.js:705 msgid "Created" msgstr "Erstellt" @@ -1375,7 +1379,7 @@ msgid "Copy category parameter templates when creating a part" msgstr "" #: common/models.py:115 part/templates/part/detail.html:155 stock/forms.py:255 -#: templates/js/table_filters.js:23 templates/js/table_filters.js:266 +#: templates/js/table_filters.js:23 templates/js/table_filters.js:270 msgid "Template" msgstr "Vorlage" @@ -1386,7 +1390,7 @@ msgid "Parts are templates by default" msgstr "Teil ist nicht virtuell" #: common/models.py:122 part/models.py:794 part/templates/part/detail.html:165 -#: templates/js/table_filters.js:278 +#: templates/js/table_filters.js:282 msgid "Assembly" msgstr "Baugruppe" @@ -1397,7 +1401,7 @@ msgid "Parts can be assembled from other components by default" msgstr "Teil kann aus anderen Teilen angefertigt werden" #: common/models.py:129 part/models.py:800 part/templates/part/detail.html:175 -#: templates/js/table_filters.js:282 +#: templates/js/table_filters.js:286 msgid "Component" msgstr "Komponente" @@ -1416,7 +1420,7 @@ msgid "Parts are purchaseable by default" msgstr "" #: common/models.py:143 part/models.py:816 part/templates/part/detail.html:205 -#: templates/js/table_filters.js:290 +#: templates/js/table_filters.js:294 msgid "Salable" msgstr "Verkäuflich" @@ -1425,7 +1429,7 @@ msgid "Parts are salable by default" msgstr "" #: common/models.py:150 part/models.py:806 part/templates/part/detail.html:185 -#: templates/js/table_filters.js:31 templates/js/table_filters.js:294 +#: templates/js/table_filters.js:31 templates/js/table_filters.js:298 msgid "Trackable" msgstr "nachverfolgbar" @@ -1446,136 +1450,146 @@ msgstr "Teil ist nicht virtuell" #: common/models.py:164 #, fuzzy +#| msgid "Stock Quantity" +msgid "Show Quantity in Forms" +msgstr "Bestand" + +#: common/models.py:165 +msgid "Display available part quantity in some forms" +msgstr "" + +#: common/models.py:171 +#, fuzzy #| msgid "Stock Export Options" msgid "Stock Expiry" msgstr "Lagerbestandsexportoptionen" -#: common/models.py:165 +#: common/models.py:172 msgid "Enable stock expiry functionality" msgstr "" -#: common/models.py:171 +#: common/models.py:178 #, fuzzy #| msgid "Serialize Stock" msgid "Sell Expired Stock" msgstr "Lagerbestand erfassen" -#: common/models.py:172 +#: common/models.py:179 msgid "Allow sale of expired stock" msgstr "" -#: common/models.py:178 +#: common/models.py:185 #, fuzzy #| msgid "Stock Item" msgid "Stock Stale Time" msgstr "Lagerobjekt" -#: common/models.py:179 +#: common/models.py:186 msgid "Number of days stock items are considered stale before expiring" msgstr "" -#: common/models.py:181 part/templates/part/detail.html:116 +#: common/models.py:188 part/templates/part/detail.html:116 msgid "days" msgstr "" -#: common/models.py:186 +#: common/models.py:193 #, fuzzy #| msgid "Builds" msgid "Build Expired Stock" msgstr "Baue" -#: common/models.py:187 +#: common/models.py:194 msgid "Allow building with expired stock" msgstr "" -#: common/models.py:193 +#: common/models.py:200 #, fuzzy #| msgid "Order Reference" msgid "Build Order Reference Prefix" msgstr "Bestellreferenz" -#: common/models.py:194 +#: common/models.py:201 #, fuzzy #| msgid "Order reference" msgid "Prefix value for build order reference" msgstr "Bestell-Referenz" -#: common/models.py:199 +#: common/models.py:206 #, fuzzy #| msgid "Order Reference" msgid "Build Order Reference Regex" msgstr "Bestellreferenz" -#: common/models.py:200 +#: common/models.py:207 msgid "Regular expression pattern for matching build order reference" msgstr "" -#: common/models.py:204 +#: common/models.py:211 #, fuzzy #| msgid "Sales Order Reference" msgid "Sales Order Reference Prefix" msgstr "Bestellungsreferenz" -#: common/models.py:205 +#: common/models.py:212 #, fuzzy #| msgid "Order reference" msgid "Prefix value for sales order reference" msgstr "Bestell-Referenz" -#: common/models.py:210 +#: common/models.py:217 #, fuzzy #| msgid "Order reference" msgid "Purchase Order Reference Prefix" msgstr "Bestell-Referenz" -#: common/models.py:211 +#: common/models.py:218 #, fuzzy #| msgid "Order reference" msgid "Prefix value for purchase order reference" msgstr "Bestell-Referenz" -#: common/models.py:434 +#: common/models.py:441 msgid "Settings key (must be unique - case insensitive" msgstr "" "Einstellungs-Schlüssel (muss einzigartig sein, Groß-/ Kleinschreibung wird " "nicht beachtet)" -#: common/models.py:436 +#: common/models.py:443 msgid "Settings value" msgstr "Einstellungs-Wert" -#: common/models.py:493 +#: common/models.py:500 msgid "Value must be a boolean value" msgstr "" -#: common/models.py:503 +#: common/models.py:510 #, fuzzy #| msgid "Must enter integer value" msgid "Value must be an integer value" msgstr "Nur Ganzzahl eingeben" -#: common/models.py:517 +#: common/models.py:524 msgid "Key string must be unique" msgstr "Schlüsseltext muss eindeutig sein" -#: common/models.py:590 company/forms.py:113 +#: common/models.py:597 company/forms.py:113 #, fuzzy #| msgid "Price Breaks" msgid "Price break quantity" msgstr "Preisstaffelung" -#: common/models.py:598 company/templates/company/supplier_part_pricing.html:80 +#: common/models.py:605 company/templates/company/supplier_part_pricing.html:80 #: part/templates/part/sale_prices.html:87 templates/js/bom.js:246 msgid "Price" msgstr "Preis" -#: common/models.py:599 +#: common/models.py:606 #, fuzzy #| msgid "Enter a valid quantity" msgid "Unit price at specified quantity" msgstr "Bitte eine gültige Anzahl eingeben" -#: common/models.py:622 +#: common/models.py:629 #, fuzzy #| msgid "Default Location" msgid "Default" @@ -1708,10 +1722,10 @@ msgstr "Teil auswählen" #: company/models.py:323 company/templates/company/detail.html:57 #: company/templates/company/supplier_part_base.html:74 #: company/templates/company/supplier_part_detail.html:21 -#: order/templates/order/order_base.html:79 +#: order/templates/order/order_base.html:89 #: order/templates/order/order_wizard/select_pos.html:30 part/bom.py:170 #: stock/templates/stock/item_base.html:304 templates/js/company.js:48 -#: templates/js/company.js:164 templates/js/order.js:162 +#: templates/js/company.js:164 templates/js/order.js:167 msgid "Supplier" msgstr "Zulieferer" @@ -1816,7 +1830,7 @@ msgstr "Währung entfernen" #: company/templates/company/detail.html:62 #: order/templates/order/sales_order_base.html:89 stock/models.py:380 #: stock/models.py:381 stock/templates/stock/item_base.html:221 -#: templates/js/company.js:40 templates/js/order.js:250 +#: templates/js/company.js:40 templates/js/order.js:261 msgid "Customer" msgstr "Kunde" @@ -1831,7 +1845,7 @@ msgstr "Neues Zuliefererteil anlegen" #: company/templates/company/detail_part.html:18 #: order/templates/order/purchase_order_detail.html:68 -#: part/templates/part/supplier.html:14 templates/js/stock.js:881 +#: part/templates/part/supplier.html:14 templates/js/stock.js:983 msgid "New Supplier Part" msgstr "Neues Zulieferer-Teil" @@ -1859,7 +1873,7 @@ msgid "Delete Parts" msgstr "Teile löschen" #: company/templates/company/detail_part.html:63 -#: part/templates/part/category.html:116 templates/js/stock.js:875 +#: part/templates/part/category.html:116 templates/js/stock.js:977 msgid "New Part" msgstr "Neues Teil" @@ -1917,7 +1931,7 @@ msgstr "" #: order/templates/order/purchase_orders.html:13 #: part/templates/part/orders.html:9 part/templates/part/tabs.html:48 #: templates/InvenTree/settings/tabs.html:31 templates/navbar.html:33 -#: users/models.py:31 +#: users/models.py:33 msgid "Purchase Orders" msgstr "Bestellungen" @@ -1937,7 +1951,7 @@ msgstr "Neue Bestellung" #: order/templates/order/sales_orders.html:13 #: part/templates/part/sales_orders.html:9 part/templates/part/tabs.html:56 #: templates/InvenTree/settings/tabs.html:34 templates/navbar.html:42 -#: users/models.py:32 +#: users/models.py:34 msgid "Sales Orders" msgstr "Bestellungen" @@ -2031,8 +2045,7 @@ msgstr "Bepreisung" #: company/templates/company/tabs.html:12 part/templates/part/tabs.html:18 #: stock/templates/stock/location.html:17 templates/InvenTree/search.html:155 #: templates/InvenTree/settings/tabs.html:25 templates/js/part.js:192 -#: templates/js/part.js:418 templates/js/stock.js:509 templates/navbar.html:22 -#: users/models.py:29 +#: templates/js/part.js:418 templates/js/stock.js:519 templates/navbar.html:22 msgid "Stock" msgstr "Lagerbestand" @@ -2045,7 +2058,7 @@ msgstr "Bestellungen" #: part/templates/part/cat_link.html:7 part/templates/part/category.html:94 #: part/templates/part/category_tabs.html:6 #: templates/InvenTree/settings/tabs.html:22 templates/navbar.html:19 -#: templates/stats.html:35 templates/stats.html:44 users/models.py:28 +#: templates/stats.html:35 templates/stats.html:44 users/models.py:29 msgid "Parts" msgstr "Teile" @@ -2114,7 +2127,7 @@ msgstr "Firma gelöscht" msgid "Edit Supplier Part" msgstr "Zuliefererteil bearbeiten" -#: company/views.py:295 templates/js/stock.js:882 +#: company/views.py:295 templates/js/stock.js:984 msgid "Create new Supplier Part" msgstr "Neues Zuliefererteil anlegen" @@ -2164,15 +2177,15 @@ msgstr "" msgid "Enabled" msgstr "" -#: order/forms.py:25 order/templates/order/order_base.html:39 +#: order/forms.py:25 order/templates/order/order_base.html:44 msgid "Place order" msgstr "Bestellung aufgeben" -#: order/forms.py:36 order/templates/order/order_base.html:46 +#: order/forms.py:36 order/templates/order/order_base.html:51 msgid "Mark order as complete" msgstr "Bestellung als vollständig markieren" -#: order/forms.py:47 order/forms.py:58 order/templates/order/order_base.html:51 +#: order/forms.py:47 order/forms.py:58 order/templates/order/order_base.html:56 #: order/templates/order/sales_order_base.html:56 msgid "Cancel order" msgstr "Bestellung stornieren" @@ -2185,19 +2198,23 @@ msgstr "Bestellung versenden" msgid "Receive parts to this location" msgstr "Teile in diesen Ort empfangen" -#: order/forms.py:100 +#: order/forms.py:101 #, fuzzy #| msgid "Order reference" msgid "Purchase Order reference" msgstr "Bestell-Referenz" -#: order/forms.py:128 +#: order/forms.py:107 +msgid "Target date for order delivery. Order will be overdue after this date." +msgstr "" + +#: order/forms.py:134 #, fuzzy #| msgid "Cancel sales order" msgid "Enter sales order number" msgstr "Auftrag stornieren" -#: order/forms.py:134 order/models.py:405 +#: order/forms.py:140 order/models.py:438 msgid "" "Target date for order completion. Order will be overdue after this date." msgstr "" @@ -2218,115 +2235,138 @@ msgstr "Link auf externe Seite" msgid "Order notes" msgstr "Bestell-Notizen" -#: order/models.py:169 order/models.py:398 +#: order/models.py:172 order/models.py:431 #, fuzzy #| msgid "Purchase Order Details" msgid "Purchase order status" msgstr "Bestelldetails" -#: order/models.py:177 +#: order/models.py:180 msgid "Company from which the items are being ordered" msgstr "" -#: order/models.py:180 +#: order/models.py:183 msgid "Supplier order reference code" msgstr "Bestellreferenz" -#: order/models.py:189 +#: order/models.py:194 +#, fuzzy +#| msgid "Issue Order" +msgid "Issue Date" +msgstr "Bestellung aufgeben" + +#: order/models.py:195 msgid "Date order was issued" msgstr "" -#: order/models.py:191 +#: order/models.py:200 +#, fuzzy +#| msgid "Shipment Date" +msgid "Target Delivery Date" +msgstr "Versanddatum" + +#: order/models.py:201 +msgid "" +"Expected date for order delivery. Order will be overdue after this date." +msgstr "" + +#: order/models.py:206 +#, fuzzy +#| msgid "Creation Date" +msgid "Completion Date" +msgstr "Erstelldatum" + +#: order/models.py:207 #, fuzzy #| msgid "Mark order as complete" msgid "Date order was completed" msgstr "Bestellung als vollständig markieren" -#: order/models.py:214 order/models.py:296 part/views.py:1504 +#: order/models.py:231 order/models.py:329 part/views.py:1504 #: stock/models.py:251 stock/models.py:856 msgid "Quantity must be greater than zero" msgstr "Anzahl muss größer Null sein" -#: order/models.py:219 +#: order/models.py:236 msgid "Part supplier must match PO supplier" msgstr "Teile-Zulieferer muss dem Zulieferer des Kaufvertrags entsprechen" -#: order/models.py:291 +#: order/models.py:324 msgid "Lines can only be received against an order marked as 'Placed'" msgstr "Nur Teile aufgegebener Bestllungen können empfangen werden" -#: order/models.py:394 +#: order/models.py:427 msgid "Company to which the items are being sold" msgstr "" -#: order/models.py:400 +#: order/models.py:433 msgid "Customer order reference code" msgstr "Bestellreferenz" -#: order/models.py:462 +#: order/models.py:491 msgid "SalesOrder cannot be shipped as it is not currently pending" msgstr "Bestellung kann nicht versendet werden weil sie nicht anhängig ist" -#: order/models.py:549 +#: order/models.py:578 msgid "Item quantity" msgstr "Anzahl" -#: order/models.py:551 +#: order/models.py:580 msgid "Line item reference" msgstr "Position - Referenz" -#: order/models.py:553 +#: order/models.py:582 msgid "Line item notes" msgstr "Position - Notizen" -#: order/models.py:579 order/templates/order/order_base.html:9 +#: order/models.py:608 order/templates/order/order_base.html:9 #: order/templates/order/order_base.html:24 -#: stock/templates/stock/item_base.html:276 templates/js/order.js:146 +#: stock/templates/stock/item_base.html:276 templates/js/order.js:145 msgid "Purchase Order" msgstr "Kaufvertrag" -#: order/models.py:592 +#: order/models.py:621 msgid "Supplier part" msgstr "Zulieferer-Teil" -#: order/models.py:595 +#: order/models.py:624 msgid "Number of items received" msgstr "Empfangene Objekt-Anzahl" -#: order/models.py:602 stock/models.py:473 +#: order/models.py:631 stock/models.py:473 #: stock/templates/stock/item_base.html:283 #, fuzzy #| msgid "Purchase Order" msgid "Purchase Price" msgstr "Kaufvertrag" -#: order/models.py:603 +#: order/models.py:632 #, fuzzy #| msgid "Purchase Order" msgid "Unit purchase price" msgstr "Kaufvertrag" -#: order/models.py:698 +#: order/models.py:727 msgid "Cannot allocate stock item to a line with a different part" msgstr "Kann Lagerobjekt keiner Zeile mit einem anderen Teil hinzufügen" -#: order/models.py:700 +#: order/models.py:729 msgid "Cannot allocate stock to a line without a part" msgstr "Kann Lagerobjekt keiner Zeile ohne Teil hinzufügen" -#: order/models.py:703 +#: order/models.py:732 msgid "Allocation quantity cannot exceed stock quantity" msgstr "zugewiesene Anzahl darf nicht die verfügbare Anzahl überschreiten" -#: order/models.py:713 +#: order/models.py:742 msgid "Quantity must be 1 for serialized stock item" msgstr "Anzahl muss 1 für Objekte mit Seriennummer sein" -#: order/models.py:729 +#: order/models.py:758 msgid "Select stock item to allocate" msgstr "Lagerobjekt für Zuordnung auswählen" -#: order/models.py:732 +#: order/models.py:761 msgid "Enter stock allocation quantity" msgstr "Zuordnungsanzahl eingeben" @@ -2336,45 +2376,45 @@ msgstr "Zuordnungsanzahl eingeben" msgid "Are you sure you want to delete this attachment?" msgstr "Sind Sie sicher, dass Sie diesen Anhang löschen wollen?" -#: order/templates/order/order_base.html:35 +#: order/templates/order/order_base.html:40 #, fuzzy #| msgid "Edited company information" msgid "Edit order information" msgstr "Firmeninformation bearbeitet" -#: order/templates/order/order_base.html:43 +#: order/templates/order/order_base.html:48 #, fuzzy #| msgid "Receive line item" msgid "Receive items" msgstr "Position empfangen" -#: order/templates/order/order_base.html:56 +#: order/templates/order/order_base.html:61 msgid "Export order to file" msgstr "" -#: order/templates/order/order_base.html:64 +#: order/templates/order/order_base.html:69 msgid "Purchase Order Details" msgstr "Bestelldetails" -#: order/templates/order/order_base.html:69 +#: order/templates/order/order_base.html:74 #: order/templates/order/sales_order_base.html:74 msgid "Order Reference" msgstr "Bestellreferenz" -#: order/templates/order/order_base.html:74 +#: order/templates/order/order_base.html:79 #: order/templates/order/sales_order_base.html:79 msgid "Order Status" msgstr "Bestellstatus" -#: order/templates/order/order_base.html:85 templates/js/order.js:169 +#: order/templates/order/order_base.html:95 templates/js/order.js:175 msgid "Supplier Reference" msgstr "Zuliefererreferenz" -#: order/templates/order/order_base.html:104 +#: order/templates/order/order_base.html:114 msgid "Issued" msgstr "Aufgegeben" -#: order/templates/order/order_base.html:111 +#: order/templates/order/order_base.html:128 #: order/templates/order/purchase_order_detail.html:193 #: order/templates/order/receive_parts.html:22 #: order/templates/order/sales_order_base.html:128 @@ -2427,7 +2467,7 @@ msgid "Select existing purchase orders, or create new orders." msgstr "Bestellungen auswählen oder anlegen." #: order/templates/order/order_wizard/select_pos.html:31 -#: templates/js/order.js:193 templates/js/order.js:291 +#: templates/js/order.js:203 templates/js/order.js:302 msgid "Items" msgstr "Positionen" @@ -2469,7 +2509,7 @@ msgstr "Bestellpositionen" #: order/templates/order/purchase_order_detail.html:39 #: order/templates/order/purchase_order_detail.html:119 #: part/templates/part/category.html:173 part/templates/part/category.html:215 -#: templates/js/stock.js:627 templates/js/stock.js:887 +#: templates/js/stock.js:642 templates/js/stock.js:989 msgid "New Location" msgstr "Neuer Standort" @@ -2542,7 +2582,7 @@ msgstr "Packliste" msgid "Sales Order Details" msgstr "Auftragsdetails" -#: order/templates/order/sales_order_base.html:95 templates/js/order.js:257 +#: order/templates/order/sales_order_base.html:95 templates/js/order.js:268 msgid "Customer Reference" msgstr "Kundenreferenz" @@ -2673,18 +2713,14 @@ msgstr "Bestellung stornieren" msgid "Confirm order cancellation" msgstr "Bestellstornierung bestätigen" -#: order/views.py:435 -msgid "Order cannot be cancelled as either pending or placed" +#: order/views.py:435 order/views.py:462 +msgid "Order cannot be cancelled" msgstr "" #: order/views.py:449 msgid "Cancel sales order" msgstr "Auftrag stornieren" -#: order/views.py:462 -msgid "Order cannot be cancelled" -msgstr "" - #: order/views.py:476 msgid "Issue Order" msgstr "Bestellung aufgeben" @@ -2807,103 +2843,103 @@ msgstr "Fehler beim Lesen der Stückliste (ungültige Daten)" msgid "Error reading BOM file (incorrect row size)" msgstr "Fehler beim Lesen der Stückliste (ungültige Zeilengröße)" -#: part/forms.py:61 stock/forms.py:261 +#: part/forms.py:71 stock/forms.py:261 msgid "File Format" msgstr "Dateiformat" -#: part/forms.py:61 stock/forms.py:261 +#: part/forms.py:71 stock/forms.py:261 msgid "Select output file format" msgstr "Ausgabe-Dateiformat auswählen" -#: part/forms.py:63 +#: part/forms.py:73 msgid "Cascading" msgstr "Kaskadierend" -#: part/forms.py:63 +#: part/forms.py:73 msgid "Download cascading / multi-level BOM" msgstr "Kaskadierende Stückliste herunterladen" -#: part/forms.py:65 +#: part/forms.py:75 msgid "Levels" msgstr "" -#: part/forms.py:65 +#: part/forms.py:75 msgid "Select maximum number of BOM levels to export (0 = all levels)" msgstr "" -#: part/forms.py:67 +#: part/forms.py:77 #, fuzzy #| msgid "New Parameter" msgid "Include Parameter Data" msgstr "Neuer Parameter" -#: part/forms.py:67 +#: part/forms.py:77 msgid "Include part parameters data in exported BOM" msgstr "" -#: part/forms.py:69 +#: part/forms.py:79 #, fuzzy #| msgid "Include stock in sublocations" msgid "Include Stock Data" msgstr "Bestand in Unterlagerorten einschließen" -#: part/forms.py:69 +#: part/forms.py:79 #, fuzzy #| msgid "Include parts in subcategories" msgid "Include part stock data in exported BOM" msgstr "Teile in Unterkategorien einschließen" -#: part/forms.py:71 +#: part/forms.py:81 #, fuzzy #| msgid "New Supplier Part" msgid "Include Supplier Data" msgstr "Neues Zulieferer-Teil" -#: part/forms.py:71 +#: part/forms.py:81 msgid "Include part supplier data in exported BOM" msgstr "" -#: part/forms.py:92 part/models.py:1781 +#: part/forms.py:102 part/models.py:1781 msgid "Parent Part" msgstr "Ausgangsteil" -#: part/forms.py:93 part/templates/part/bom_duplicate.html:7 +#: part/forms.py:103 part/templates/part/bom_duplicate.html:7 #, fuzzy #| msgid "Select parent part" msgid "Select parent part to copy BOM from" msgstr "Ausgangsteil auswählen" -#: part/forms.py:99 +#: part/forms.py:109 #, fuzzy #| msgid "Select from existing images" msgid "Clear existing BOM items" msgstr "Aus vorhandenen Bildern auswählen" -#: part/forms.py:104 +#: part/forms.py:114 #, fuzzy #| msgid "Confim BOM item deletion" msgid "Confirm BOM duplication" msgstr "Löschung von BOM-Position bestätigen" -#: part/forms.py:122 +#: part/forms.py:132 msgid "Confirm that the BOM is correct" msgstr "Bestätigen, dass die Stückliste korrekt ist" -#: part/forms.py:134 +#: part/forms.py:144 msgid "Select BOM file to upload" msgstr "Stücklisten-Datei zum Upload auswählen" -#: part/forms.py:153 +#: part/forms.py:163 #, fuzzy #| msgid "Delete Parts" msgid "Related Part" msgstr "Teile löschen" -#: part/forms.py:172 +#: part/forms.py:182 msgid "Select part category" msgstr "Teilekategorie wählen" -#: part/forms.py:189 +#: part/forms.py:199 #, fuzzy #| msgid "Perform 'deep copy' which will duplicate all BOM data for this part" msgid "Duplicate all BOM data for this part" @@ -2911,49 +2947,49 @@ msgstr "" "Tiefe Kopie ausführen. Dies wird alle Daten der Stückliste für dieses Teil " "duplizieren" -#: part/forms.py:190 +#: part/forms.py:200 msgid "Copy BOM" msgstr "" -#: part/forms.py:195 +#: part/forms.py:205 msgid "Duplicate all parameter data for this part" msgstr "" -#: part/forms.py:196 +#: part/forms.py:206 #, fuzzy #| msgid "Parameters" msgid "Copy Parameters" msgstr "Parameter" -#: part/forms.py:201 +#: part/forms.py:211 msgid "Confirm part creation" msgstr "Erstellen des Teils bestätigen" -#: part/forms.py:206 +#: part/forms.py:216 #, fuzzy #| msgid "No part parameter templates found" msgid "Include category parameter templates" msgstr "Keine Teilparametervorlagen gefunden" -#: part/forms.py:211 +#: part/forms.py:221 #, fuzzy #| msgid "No part parameter templates found" msgid "Include parent categories parameter templates" msgstr "Keine Teilparametervorlagen gefunden" -#: part/forms.py:291 +#: part/forms.py:301 #, fuzzy #| msgid "Parameter template name must be unique" msgid "Add parameter template to same level categories" msgstr "Vorlagen-Name des Parameters muss eindeutig sein" -#: part/forms.py:295 +#: part/forms.py:305 #, fuzzy #| msgid "Parameter template name must be unique" msgid "Add parameter template to all categories" msgstr "Vorlagen-Name des Parameters muss eindeutig sein" -#: part/forms.py:339 +#: part/forms.py:349 msgid "Input quantity for price calculation" msgstr "Eintragsmenge zur Preisberechnung" @@ -2972,6 +3008,7 @@ msgstr "Teilkategorie" #: part/models.py:78 part/templates/part/category.html:18 #: part/templates/part/category.html:89 templates/stats.html:39 +#: users/models.py:28 msgid "Part Categories" msgstr "Teile-Kategorien" @@ -3127,7 +3164,7 @@ msgstr "Kann dieses Teil an Kunden verkauft werden?" #: part/models.py:821 part/templates/part/detail.html:222 #: templates/js/table_filters.js:19 templates/js/table_filters.js:55 -#: templates/js/table_filters.js:196 templates/js/table_filters.js:261 +#: templates/js/table_filters.js:196 templates/js/table_filters.js:265 msgid "Active" msgstr "Aktiv" @@ -3163,7 +3200,7 @@ msgstr "" "Ein Teil mit dieser Seriennummer existiert bereits für die Teilevorlage " "{part}" -#: part/models.py:1690 templates/js/part.js:567 templates/js/stock.js:93 +#: part/models.py:1690 templates/js/part.js:567 templates/js/stock.js:103 #, fuzzy #| msgid "Instance Name" msgid "Test Name" @@ -3296,13 +3333,13 @@ msgstr "Zuliefererbeschreibung des Teils" msgid "BOM Item" msgstr "Neue Stücklistenposition" -#: part/models.py:2092 +#: part/models.py:2098 #, fuzzy #| msgid "Select a part" msgid "Select Related Part" msgstr "Teil auswählen" -#: part/models.py:2124 +#: part/models.py:2130 msgid "" "Error creating relationship: check that the part is not related to itself " "and that the relationship is unique" @@ -3325,7 +3362,7 @@ msgstr "Bestellung" #: stock/templates/stock/item_base.html:72 #: stock/templates/stock/item_base.html:291 #: stock/templates/stock/stock_adjust.html:16 templates/js/build.js:751 -#: templates/js/stock.js:720 templates/js/stock.js:980 +#: templates/js/stock.js:822 templates/js/stock.js:1082 msgid "Stock Item" msgstr "Lagerobjekt" @@ -3588,7 +3625,7 @@ msgstr "Teilkategorie auswählen" msgid "Export Data" msgstr "Exportieren" -#: part/templates/part/category.html:174 templates/js/stock.js:628 +#: part/templates/part/category.html:174 templates/js/stock.js:643 #, fuzzy #| msgid "Create New Location" msgid "Create new location" @@ -3660,7 +3697,7 @@ msgstr "Keine Seriennummern gefunden" msgid "Stock Expiry Time" msgstr "Lagerbestandsexportoptionen" -#: part/templates/part/detail.html:121 templates/js/order.js:276 +#: part/templates/part/detail.html:121 templates/js/order.js:287 msgid "Creation Date" msgstr "Erstelldatum" @@ -3754,17 +3791,17 @@ msgstr "Parameter hinzufügen" #: part/templates/part/params.html:15 #: templates/InvenTree/settings/category.html:29 -#: templates/InvenTree/settings/part.html:41 +#: templates/InvenTree/settings/part.html:42 msgid "New Parameter" msgstr "Neuer Parameter" #: part/templates/part/params.html:25 stock/models.py:1499 -#: templates/InvenTree/settings/header.html:8 templates/js/stock.js:113 +#: templates/InvenTree/settings/header.html:8 templates/js/stock.js:123 msgid "Value" msgstr "Wert" #: part/templates/part/params.html:41 part/templates/part/related.html:41 -#: part/templates/part/supplier.html:19 users/models.py:152 +#: part/templates/part/supplier.html:19 users/models.py:158 msgid "Delete" msgstr "Löschen" @@ -3863,7 +3900,7 @@ msgstr "Zu Bauaufträgen zugeordnet" msgid "Allocated to Sales Orders" msgstr "Zu Aufträgen zugeordnet" -#: part/templates/part/part_base.html:160 +#: part/templates/part/part_base.html:160 templates/js/bom.js:262 msgid "Can Build" msgstr "Herstellbar?" @@ -4089,7 +4126,7 @@ msgstr "Teil kopiert" msgid "Possible matches exist - confirm creation of new part" msgstr "" -#: part/views.py:594 templates/js/stock.js:876 +#: part/views.py:594 templates/js/stock.js:978 msgid "Create New Part" msgstr "Neues Teil anlegen" @@ -4480,7 +4517,7 @@ msgid "Destination Sales Order" msgstr "Zielauftrag" #: stock/models.py:440 stock/templates/stock/item_base.html:316 -#: templates/js/stock.js:597 +#: templates/js/stock.js:612 #, fuzzy #| msgid "Export" msgid "Expiry Date" @@ -4784,7 +4821,7 @@ msgstr "Ist dieses Objekt einem Kunden zugeteilt?" msgid "Return to stock" msgstr "Bestand zählen" -#: stock/templates/stock/item_base.html:158 templates/js/stock.js:1017 +#: stock/templates/stock/item_base.html:158 templates/js/stock.js:1119 #, fuzzy #| msgid "Installed in Stock Item" msgid "Uninstall stock item" @@ -4948,53 +4985,54 @@ msgstr "Alle Lagerobjekte" msgid "Check-in Items" msgstr "Kind-Lagerobjekte" -#: stock/templates/stock/location.html:45 +#: stock/templates/stock/location.html:47 #, fuzzy #| msgid "Location Description" msgid "Location actions" msgstr "Standort-Beschreibung" -#: stock/templates/stock/location.html:47 +#: stock/templates/stock/location.html:49 #, fuzzy #| msgid "Edit stock location" msgid "Edit location" msgstr "Lagerort bearbeiten" -#: stock/templates/stock/location.html:49 +#: stock/templates/stock/location.html:51 #, fuzzy #| msgid "Delete stock location" msgid "Delete location" msgstr "Lagerort löschen" -#: stock/templates/stock/location.html:59 +#: stock/templates/stock/location.html:61 msgid "Location Details" msgstr "Standort-Details" -#: stock/templates/stock/location.html:64 +#: stock/templates/stock/location.html:66 msgid "Location Path" msgstr "Standord-Pfad" -#: stock/templates/stock/location.html:69 +#: stock/templates/stock/location.html:71 msgid "Location Description" msgstr "Standort-Beschreibung" -#: stock/templates/stock/location.html:74 +#: stock/templates/stock/location.html:76 msgid "Sublocations" msgstr "Sub-Standorte" -#: stock/templates/stock/location.html:79 -#: stock/templates/stock/location.html:94 +#: stock/templates/stock/location.html:81 +#: stock/templates/stock/location.html:96 #: templates/InvenTree/search_stock_items.html:6 templates/stats.html:48 -#: templates/stats.html:57 +#: templates/stats.html:57 users/models.py:31 msgid "Stock Items" msgstr "Lagerobjekte" -#: stock/templates/stock/location.html:84 +#: stock/templates/stock/location.html:86 msgid "Stock Details" msgstr "Objekt-Details" -#: stock/templates/stock/location.html:89 +#: stock/templates/stock/location.html:91 #: templates/InvenTree/search_stock_location.html:6 templates/stats.html:52 +#: users/models.py:30 msgid "Stock Locations" msgstr "Lagerobjekt-Standorte" @@ -5346,6 +5384,12 @@ msgstr "Ausgangsteil" msgid "Outstanding Purchase Orders" msgstr "Bestellung bearbeiten" +#: templates/InvenTree/po_overdue.html:7 +#, fuzzy +#| msgid "Sales Orders" +msgid "Overdue Purchase Orders" +msgstr "Bestellungen" + #: templates/InvenTree/required_stock_build.html:7 #, fuzzy #| msgid "Complete Build" @@ -5368,13 +5412,13 @@ msgstr "Keine Ergebnisse gefunden" msgid "Enter a search query" msgstr "Auftrag stornieren" -#: templates/InvenTree/search.html:191 templates/js/stock.js:290 +#: templates/InvenTree/search.html:191 templates/js/stock.js:300 #, fuzzy #| msgid "Item assigned to customer?" msgid "Shipped to customer" msgstr "Ist dieses Objekt einem Kunden zugeteilt?" -#: templates/InvenTree/search.html:194 templates/js/stock.js:300 +#: templates/InvenTree/search.html:194 templates/js/stock.js:310 msgid "No stock location set" msgstr "Kein Lagerort gesetzt" @@ -5415,12 +5459,12 @@ msgid "Default Value" msgstr "Standard-Lagerort" #: templates/InvenTree/settings/category.html:70 -#: templates/InvenTree/settings/part.html:78 +#: templates/InvenTree/settings/part.html:79 msgid "Edit Template" msgstr "Vorlage bearbeiten" #: templates/InvenTree/settings/category.html:71 -#: templates/InvenTree/settings/part.html:79 +#: templates/InvenTree/settings/part.html:80 msgid "Delete Template" msgstr "Vorlage löschen" @@ -5448,13 +5492,13 @@ msgstr "Einstellungen" msgid "Part Options" msgstr "Quell-Standort" -#: templates/InvenTree/settings/part.html:37 +#: templates/InvenTree/settings/part.html:38 #, fuzzy #| msgid "Edit Part Parameter Template" msgid "Part Parameter Templates" msgstr "Teilparametervorlage bearbeiten" -#: templates/InvenTree/settings/part.html:58 +#: templates/InvenTree/settings/part.html:59 msgid "No part parameter templates found" msgstr "Keine Teilparametervorlagen gefunden" @@ -5775,41 +5819,41 @@ msgstr "Optionen" msgid "No pricing available" msgstr "Keine Preisinformation verfügbar" -#: templates/js/bom.js:272 templates/js/build.js:571 +#: templates/js/bom.js:304 templates/js/build.js:571 #, fuzzy #| msgid "Options" msgid "Actions" msgstr "Optionen" -#: templates/js/bom.js:280 +#: templates/js/bom.js:312 msgid "Validate BOM Item" msgstr "BOM-Position validieren" -#: templates/js/bom.js:282 +#: templates/js/bom.js:314 msgid "This line has been validated" msgstr "Diese Position wurde validiert" -#: templates/js/bom.js:284 +#: templates/js/bom.js:316 msgid "Edit BOM Item" msgstr "BOM-Position bearbeiten" -#: templates/js/bom.js:286 +#: templates/js/bom.js:318 msgid "Delete BOM Item" msgstr "BOM-Position löschen" -#: templates/js/bom.js:363 templates/js/build.js:305 +#: templates/js/bom.js:395 templates/js/build.js:305 msgid "No BOM items found" msgstr "Keine BOM-Einträge gefunden" -#: templates/js/bom.js:509 +#: templates/js/bom.js:541 msgid "INACTIVE" msgstr "INAKTIV" -#: templates/js/bom.js:523 +#: templates/js/bom.js:555 msgid "Uses" msgstr "" -#: templates/js/bom.js:534 +#: templates/js/bom.js:566 #, fuzzy #| msgid "No matching action found" msgid "No matching parts found" @@ -5915,21 +5959,21 @@ msgstr "Baugruppe" msgid "No purchase orders found" msgstr "Keine Bestellungen gefunden" -#: templates/js/order.js:188 templates/js/stock.js:702 -msgid "Date" -msgstr "Datum" - -#: templates/js/order.js:218 -msgid "No sales orders found" -msgstr "Keine Aufträge gefunden" - -#: templates/js/order.js:241 +#: templates/js/order.js:159 templates/js/order.js:252 #, fuzzy #| msgid "Build order allocation is complete" msgid "Order is overdue" msgstr "Bau-Zuweisung ist vollständig" -#: templates/js/order.js:286 +#: templates/js/order.js:193 templates/js/stock.js:804 +msgid "Date" +msgstr "Datum" + +#: templates/js/order.js:229 +msgid "No sales orders found" +msgstr "Keine Aufträge gefunden" + +#: templates/js/order.js:297 msgid "Shipment Date" msgstr "Versanddatum" @@ -5963,8 +6007,8 @@ msgstr "Keine Teile gefunden" msgid "No parts found" msgstr "Keine Teile gefunden" -#: templates/js/part.js:343 templates/js/stock.js:463 -#: templates/js/stock.js:1049 +#: templates/js/part.js:343 templates/js/stock.js:473 +#: templates/js/stock.js:1151 msgid "Select" msgstr "Auswählen" @@ -5972,7 +6016,7 @@ msgstr "Auswählen" msgid "No category" msgstr "Keine Kategorie" -#: templates/js/part.js:429 templates/js/table_filters.js:274 +#: templates/js/part.js:429 templates/js/table_filters.js:278 msgid "Low stock" msgstr "Bestand niedrig" @@ -5994,13 +6038,13 @@ msgstr "" msgid "No test templates matching query" msgstr "Keine zur Anfrage passenden Lagerobjekte" -#: templates/js/part.js:604 templates/js/stock.js:64 +#: templates/js/part.js:604 templates/js/stock.js:74 #, fuzzy #| msgid "Edit Sales Order" msgid "Edit test result" msgstr "Auftrag bearbeiten" -#: templates/js/part.js:605 templates/js/stock.js:65 +#: templates/js/part.js:605 templates/js/stock.js:75 #, fuzzy #| msgid "Delete attachment" msgid "Delete test result" @@ -6010,149 +6054,179 @@ msgstr "Anhang löschen" msgid "This test is defined for a parent part" msgstr "" -#: templates/js/stock.js:27 +#: templates/js/stock.js:37 msgid "PASS" msgstr "" -#: templates/js/stock.js:29 +#: templates/js/stock.js:39 msgid "FAIL" msgstr "" -#: templates/js/stock.js:34 +#: templates/js/stock.js:44 msgid "NO RESULT" msgstr "" -#: templates/js/stock.js:60 +#: templates/js/stock.js:70 #, fuzzy #| msgid "Edit Sales Order" msgid "Add test result" msgstr "Auftrag bearbeiten" -#: templates/js/stock.js:79 +#: templates/js/stock.js:89 #, fuzzy #| msgid "No results found" msgid "No test results found" msgstr "Keine Ergebnisse gefunden" -#: templates/js/stock.js:121 +#: templates/js/stock.js:131 #, fuzzy #| msgid "Shipment Date" msgid "Test Date" msgstr "Versanddatum" -#: templates/js/stock.js:282 +#: templates/js/stock.js:292 msgid "In production" msgstr "" -#: templates/js/stock.js:286 +#: templates/js/stock.js:296 #, fuzzy #| msgid "Installed in Stock Item" msgid "Installed in Stock Item" msgstr "In Lagerobjekt installiert" -#: templates/js/stock.js:294 +#: templates/js/stock.js:304 #, fuzzy #| msgid "Item assigned to customer?" msgid "Assigned to Sales Order" msgstr "Ist dieses Objekt einem Kunden zugeteilt?" -#: templates/js/stock.js:314 +#: templates/js/stock.js:324 msgid "No stock items matching query" msgstr "Keine zur Anfrage passenden Lagerobjekte" -#: templates/js/stock.js:431 +#: templates/js/stock.js:441 #, fuzzy #| msgid "Include sublocations" msgid "Undefined location" msgstr "Unterlagerorte einschließen" -#: templates/js/stock.js:525 +#: templates/js/stock.js:535 #, fuzzy #| msgid "StockItem is lost" msgid "Stock item is in production" msgstr "Lagerobjekt verloren" -#: templates/js/stock.js:530 +#: templates/js/stock.js:540 #, fuzzy #| msgid "This stock item is allocated to Sales Order" msgid "Stock item assigned to sales order" msgstr "Dieses Lagerobjekt ist dem Auftrag zugewiesen" -#: templates/js/stock.js:533 +#: templates/js/stock.js:543 #, fuzzy #| msgid "StockItem has been allocated" msgid "Stock item assigned to customer" msgstr "Lagerobjekt wurde zugewiesen" -#: templates/js/stock.js:537 +#: templates/js/stock.js:547 #, fuzzy #| msgid "StockItem has been allocated" msgid "Stock item has expired" msgstr "Lagerobjekt wurde zugewiesen" -#: templates/js/stock.js:539 +#: templates/js/stock.js:549 #, fuzzy #| msgid "StockItem is lost" msgid "Stock item will expire soon" msgstr "Lagerobjekt verloren" -#: templates/js/stock.js:543 +#: templates/js/stock.js:553 #, fuzzy #| msgid "StockItem has been allocated" msgid "Stock item has been allocated" msgstr "Lagerobjekt wurde zugewiesen" -#: templates/js/stock.js:547 +#: templates/js/stock.js:557 #, fuzzy #| msgid "Is this item installed in another item?" msgid "Stock item has been installed in another item" msgstr "Ist dieses Teil in einem anderen verbaut?" -#: templates/js/stock.js:555 +#: templates/js/stock.js:565 #, fuzzy #| msgid "StockItem has been allocated" msgid "Stock item has been rejected" msgstr "Lagerobjekt wurde zugewiesen" -#: templates/js/stock.js:559 +#: templates/js/stock.js:569 #, fuzzy #| msgid "StockItem is lost" msgid "Stock item is lost" msgstr "Lagerobjekt verloren" -#: templates/js/stock.js:562 +#: templates/js/stock.js:572 #, fuzzy #| msgid "StockItem is lost" msgid "Stock item is destroyed" msgstr "Lagerobjekt verloren" -#: templates/js/stock.js:566 templates/js/table_filters.js:106 +#: templates/js/stock.js:576 templates/js/table_filters.js:106 #, fuzzy #| msgid "Delete" msgid "Depleted" msgstr "Löschen" -#: templates/js/stock.js:768 +#: templates/js/stock.js:605 +#, fuzzy +#| msgid "Last Stocktake" +msgid "Stocktake" +msgstr "Letzte Inventur" + +#: templates/js/stock.js:720 +#, fuzzy +#| msgid "Stock status" +msgid "Stock Status" +msgstr "Bestandsstatus" + +#: templates/js/stock.js:735 +#, fuzzy +#| msgid "Stock status" +msgid "Set Stock Status" +msgstr "Bestandsstatus" + +#: templates/js/stock.js:749 +#, fuzzy +#| msgid "Select part to build" +msgid "Select Status Code" +msgstr "Teil für den Bau wählen" + +#: templates/js/stock.js:750 +#, fuzzy +#| msgid "StockItem has been allocated" +msgid "Status code must be selected" +msgstr "Lagerobjekt wurde zugewiesen" + +#: templates/js/stock.js:870 msgid "No user information" msgstr "Keine Benutzerinformation" -#: templates/js/stock.js:888 +#: templates/js/stock.js:990 msgid "Create New Location" msgstr "Neuen Standort anlegen" -#: templates/js/stock.js:987 +#: templates/js/stock.js:1089 #, fuzzy #| msgid "Serial Number" msgid "Serial" msgstr "Seriennummer" -#: templates/js/stock.js:1080 templates/js/table_filters.js:131 +#: templates/js/stock.js:1182 templates/js/table_filters.js:131 #, fuzzy #| msgid "Installed In" msgid "Installed" msgstr "Installiert in" -#: templates/js/stock.js:1105 +#: templates/js/stock.js:1207 #, fuzzy #| msgid "Installed In" msgid "Install item" @@ -6213,7 +6287,7 @@ msgstr "Seriennummer" msgid "Batch code" msgstr "Losnummer" -#: templates/js/table_filters.js:91 templates/js/table_filters.js:241 +#: templates/js/table_filters.js:91 templates/js/table_filters.js:245 msgid "Active parts" msgstr "Aktive Teile" @@ -6293,47 +6367,47 @@ msgstr "Bestandsstatus" msgid "Build status" msgstr "Bau-Status" -#: templates/js/table_filters.js:210 templates/js/table_filters.js:223 +#: templates/js/table_filters.js:210 templates/js/table_filters.js:227 msgid "Order status" msgstr "Bestellstatus" -#: templates/js/table_filters.js:215 templates/js/table_filters.js:228 +#: templates/js/table_filters.js:215 templates/js/table_filters.js:232 #, fuzzy #| msgid "Cascading" msgid "Outstanding" msgstr "Kaskadierend" -#: templates/js/table_filters.js:251 +#: templates/js/table_filters.js:255 msgid "Include subcategories" msgstr "Unterkategorien einschließen" -#: templates/js/table_filters.js:252 +#: templates/js/table_filters.js:256 msgid "Include parts in subcategories" msgstr "Teile in Unterkategorien einschließen" -#: templates/js/table_filters.js:256 +#: templates/js/table_filters.js:260 msgid "Has IPN" msgstr "" -#: templates/js/table_filters.js:257 +#: templates/js/table_filters.js:261 #, fuzzy #| msgid "Internal Part Number" msgid "Part has internal part number" msgstr "Interne Teilenummer" -#: templates/js/table_filters.js:262 +#: templates/js/table_filters.js:266 msgid "Show active parts" msgstr "Aktive Teile anzeigen" -#: templates/js/table_filters.js:270 +#: templates/js/table_filters.js:274 msgid "Stock available" msgstr "Bestand verfügbar" -#: templates/js/table_filters.js:286 +#: templates/js/table_filters.js:290 msgid "Starred" msgstr "Favorit" -#: templates/js/table_filters.js:298 +#: templates/js/table_filters.js:302 msgid "Purchasable" msgstr "Käuflich" @@ -6451,83 +6525,95 @@ msgstr "Bestand bewegen" msgid "Order selected items" msgstr "Ausgewählte Stücklistenpositionen entfernen" -#: templates/stock_table.html:28 +#: templates/stock_table.html:26 +#, fuzzy +#| msgid "Settings" +msgid "Change status" +msgstr "Einstellungen" + +#: templates/stock_table.html:26 +#, fuzzy +#| msgid "Stock status" +msgid "Change stock status" +msgstr "Bestandsstatus" + +#: templates/stock_table.html:29 #, fuzzy #| msgid "Delete line item" msgid "Delete selected items" msgstr "Position löschen" -#: templates/stock_table.html:28 +#: templates/stock_table.html:29 msgid "Delete Stock" msgstr "Bestand löschen" -#: users/admin.py:62 +#: users/admin.py:64 #, fuzzy #| msgid "User" msgid "Users" msgstr "Benutzer" -#: users/admin.py:63 +#: users/admin.py:65 msgid "Select which users are assigned to this group" msgstr "" -#: users/admin.py:178 +#: users/admin.py:187 msgid "The following users are members of multiple groups:" msgstr "" -#: users/admin.py:201 +#: users/admin.py:210 #, fuzzy #| msgid "External Link" msgid "Personal info" msgstr "Externer Link" -#: users/admin.py:202 +#: users/admin.py:211 #, fuzzy #| msgid "Revision" msgid "Permissions" msgstr "Revision" -#: users/admin.py:205 +#: users/admin.py:214 #, fuzzy #| msgid "Import BOM data" msgid "Important dates" msgstr "Stückliste importieren" -#: users/models.py:135 +#: users/models.py:141 msgid "Permission set" msgstr "" -#: users/models.py:143 +#: users/models.py:149 msgid "Group" msgstr "" -#: users/models.py:146 +#: users/models.py:152 msgid "View" msgstr "" -#: users/models.py:146 +#: users/models.py:152 msgid "Permission to view items" msgstr "" -#: users/models.py:148 +#: users/models.py:154 #, fuzzy #| msgid "Address" msgid "Add" msgstr "Adresse" -#: users/models.py:148 +#: users/models.py:154 msgid "Permission to add items" msgstr "" -#: users/models.py:150 +#: users/models.py:156 msgid "Change" msgstr "" -#: users/models.py:150 +#: users/models.py:156 msgid "Permissions to edit items" msgstr "" -#: users/models.py:152 +#: users/models.py:158 #, fuzzy #| msgid "Remove selected BOM items" msgid "Permission to delete items" diff --git a/InvenTree/locale/en/LC_MESSAGES/django.po b/InvenTree/locale/en/LC_MESSAGES/django.po index 18f86b6972..e5967684a0 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: 2021-01-07 23:48+1100\n" +"POT-Creation-Date: 2021-01-14 17:54+1100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -54,7 +54,7 @@ msgstr "" msgid "Select Category" msgstr "" -#: InvenTree/helpers.py:361 order/models.py:216 order/models.py:298 +#: InvenTree/helpers.py:361 order/models.py:233 order/models.py:331 #: stock/views.py:1660 msgid "Invalid quantity provided" msgstr "" @@ -95,7 +95,7 @@ msgstr "" msgid "File comment" msgstr "" -#: InvenTree/models.py:68 templates/js/stock.js:759 +#: InvenTree/models.py:68 templates/js/stock.js:861 msgid "User" msgstr "" @@ -302,7 +302,7 @@ msgstr "" #: build/forms.py:78 build/templates/build/auto_allocate.html:17 #: build/templates/build/build_base.html:83 -#: build/templates/build/detail.html:29 common/models.py:589 +#: build/templates/build/detail.html:29 common/models.py:596 #: company/forms.py:112 company/templates/company/supplier_part_pricing.html:75 #: order/templates/order/order_wizard/select_parts.html:32 #: order/templates/order/purchase_order_detail.html:179 @@ -315,8 +315,8 @@ msgstr "" #: stock/templates/stock/item_base.html:46 #: stock/templates/stock/item_base.html:214 #: stock/templates/stock/stock_adjust.html:18 templates/js/barcode.js:338 -#: templates/js/bom.js:195 templates/js/build.js:420 templates/js/stock.js:750 -#: templates/js/stock.js:989 +#: templates/js/bom.js:195 templates/js/build.js:420 templates/js/stock.js:852 +#: templates/js/stock.js:1091 msgid "Quantity" msgstr "" @@ -381,7 +381,7 @@ msgstr "" #: build/models.py:62 build/templates/build/index.html:8 #: build/templates/build/index.html:15 order/templates/order/so_builds.html:11 #: order/templates/order/so_tabs.html:9 part/templates/part/tabs.html:31 -#: templates/InvenTree/settings/tabs.html:28 users/models.py:30 +#: templates/InvenTree/settings/tabs.html:28 users/models.py:32 msgid "Build Orders" msgstr "" @@ -402,10 +402,10 @@ msgstr "" #: part/templates/part/detail.html:51 part/templates/part/set_category.html:14 #: templates/InvenTree/search.html:147 #: templates/InvenTree/settings/header.html:9 templates/js/bom.js:180 -#: templates/js/bom.js:517 templates/js/build.js:664 templates/js/company.js:56 -#: templates/js/order.js:175 templates/js/order.js:263 templates/js/part.js:188 +#: templates/js/bom.js:549 templates/js/build.js:664 templates/js/company.js:56 +#: templates/js/order.js:180 templates/js/order.js:274 templates/js/part.js:188 #: templates/js/part.js:271 templates/js/part.js:391 templates/js/part.js:572 -#: templates/js/stock.js:501 templates/js/stock.js:731 +#: templates/js/stock.js:511 templates/js/stock.js:833 msgid "Description" msgstr "" @@ -424,16 +424,16 @@ msgstr "" #: build/models.py:134 build/templates/build/auto_allocate.html:16 #: build/templates/build/build_base.html:78 -#: build/templates/build/detail.html:24 order/models.py:623 +#: build/templates/build/detail.html:24 order/models.py:652 #: order/templates/order/order_wizard/select_parts.html:30 #: order/templates/order/purchase_order_detail.html:148 #: order/templates/order/receive_parts.html:19 part/models.py:316 #: part/templates/part/part_app_base.html:7 part/templates/part/related.html:26 #: part/templates/part/set_category.html:13 templates/InvenTree/search.html:133 -#: templates/js/barcode.js:336 templates/js/bom.js:153 templates/js/bom.js:502 +#: templates/js/barcode.js:336 templates/js/bom.js:153 templates/js/bom.js:534 #: templates/js/build.js:669 templates/js/company.js:138 -#: templates/js/part.js:252 templates/js/part.js:357 templates/js/stock.js:475 -#: templates/js/stock.js:1061 +#: templates/js/part.js:252 templates/js/part.js:357 templates/js/stock.js:485 +#: templates/js/stock.js:1163 msgid "Part" msgstr "" @@ -499,7 +499,7 @@ msgstr "" msgid "Batch code for this build output" msgstr "" -#: build/models.py:205 order/models.py:404 +#: build/models.py:205 order/models.py:437 msgid "Target completion date" msgstr "" @@ -522,7 +522,7 @@ msgstr "" #: part/templates/part/tabs.html:73 stock/forms.py:313 stock/forms.py:345 #: stock/forms.py:373 stock/models.py:463 stock/models.py:1512 #: stock/templates/stock/tabs.html:26 templates/js/barcode.js:391 -#: templates/js/bom.js:263 templates/js/stock.js:117 templates/js/stock.js:603 +#: templates/js/bom.js:295 templates/js/stock.js:127 templates/js/stock.js:618 msgid "Notes" msgstr "" @@ -564,11 +564,11 @@ msgstr "" msgid "Allocated quantity ({n}) must not exceed available quantity ({q})" msgstr "" -#: build/models.py:971 order/models.py:707 +#: build/models.py:971 order/models.py:736 msgid "StockItem is over-allocated" msgstr "" -#: build/models.py:975 order/models.py:710 +#: build/models.py:975 order/models.py:739 msgid "Allocation quantity must be greater than zero" msgstr "" @@ -657,7 +657,7 @@ msgstr "" #: stock/templates/stock/item_base.html:244 #: stock/templates/stock/stock_adjust.html:17 #: templates/InvenTree/search.html:183 templates/js/barcode.js:337 -#: templates/js/build.js:434 templates/js/stock.js:587 +#: templates/js/build.js:434 templates/js/stock.js:597 msgid "Location" msgstr "" @@ -689,9 +689,12 @@ msgstr "" #: build/templates/build/build_base.html:43 #: build/templates/build/build_base.html:100 +#: order/templates/order/order_base.html:32 +#: order/templates/order/order_base.html:83 #: order/templates/order/sales_order_base.html:41 #: order/templates/order/sales_order_base.html:83 -#: templates/js/table_filters.js:200 templates/js/table_filters.js:232 +#: templates/js/table_filters.js:200 templates/js/table_filters.js:219 +#: templates/js/table_filters.js:236 msgid "Overdue" msgstr "" @@ -720,15 +723,16 @@ msgstr "" #: order/templates/order/receive_parts.html:24 #: stock/templates/stock/item_base.html:343 templates/InvenTree/search.html:175 #: templates/js/barcode.js:42 templates/js/build.js:697 -#: templates/js/order.js:180 templates/js/order.js:268 -#: templates/js/stock.js:574 templates/js/stock.js:997 +#: templates/js/order.js:185 templates/js/order.js:279 +#: templates/js/stock.js:584 templates/js/stock.js:1099 msgid "Status" msgstr "" #: build/templates/build/build_base.html:96 #: build/templates/build/detail.html:100 +#: order/templates/order/order_base.html:121 #: order/templates/order/sales_order_base.html:114 templates/js/build.js:710 -#: templates/js/order.js:281 +#: templates/js/order.js:198 templates/js/order.js:292 msgid "Target Date" msgstr "" @@ -742,13 +746,13 @@ msgid "Progress" msgstr "" #: build/templates/build/build_base.html:120 -#: build/templates/build/detail.html:82 order/models.py:621 +#: build/templates/build/detail.html:82 order/models.py:650 #: order/templates/order/sales_order_base.html:9 #: order/templates/order/sales_order_base.html:33 #: order/templates/order/sales_order_notes.html:10 #: order/templates/order/sales_order_ship.html:25 #: part/templates/part/allocation.html:27 -#: stock/templates/stock/item_base.html:238 templates/js/order.js:229 +#: stock/templates/stock/item_base.html:238 templates/js/order.js:240 msgid "Sales Order" msgstr "" @@ -849,14 +853,14 @@ msgid "Destination location not specified" msgstr "" #: build/templates/build/detail.html:68 -#: stock/templates/stock/item_base.html:262 templates/js/stock.js:582 -#: templates/js/stock.js:1004 templates/js/table_filters.js:80 +#: stock/templates/stock/item_base.html:262 templates/js/stock.js:592 +#: templates/js/stock.js:1106 templates/js/table_filters.js:80 #: templates/js/table_filters.js:161 msgid "Batch" msgstr "" #: build/templates/build/detail.html:95 -#: order/templates/order/order_base.html:98 +#: order/templates/order/order_base.html:108 #: order/templates/order/sales_order_base.html:108 templates/js/build.js:705 msgid "Created" msgstr "" @@ -1152,7 +1156,7 @@ msgid "Copy category parameter templates when creating a part" msgstr "" #: common/models.py:115 part/templates/part/detail.html:155 stock/forms.py:255 -#: templates/js/table_filters.js:23 templates/js/table_filters.js:266 +#: templates/js/table_filters.js:23 templates/js/table_filters.js:270 msgid "Template" msgstr "" @@ -1161,7 +1165,7 @@ msgid "Parts are templates by default" msgstr "" #: common/models.py:122 part/models.py:794 part/templates/part/detail.html:165 -#: templates/js/table_filters.js:278 +#: templates/js/table_filters.js:282 msgid "Assembly" msgstr "" @@ -1170,7 +1174,7 @@ msgid "Parts can be assembled from other components by default" msgstr "" #: common/models.py:129 part/models.py:800 part/templates/part/detail.html:175 -#: templates/js/table_filters.js:282 +#: templates/js/table_filters.js:286 msgid "Component" msgstr "" @@ -1187,7 +1191,7 @@ msgid "Parts are purchaseable by default" msgstr "" #: common/models.py:143 part/models.py:816 part/templates/part/detail.html:205 -#: templates/js/table_filters.js:290 +#: templates/js/table_filters.js:294 msgid "Salable" msgstr "" @@ -1196,7 +1200,7 @@ msgid "Parts are salable by default" msgstr "" #: common/models.py:150 part/models.py:806 part/templates/part/detail.html:185 -#: templates/js/table_filters.js:31 templates/js/table_filters.js:294 +#: templates/js/table_filters.js:31 templates/js/table_filters.js:298 msgid "Trackable" msgstr "" @@ -1214,107 +1218,115 @@ msgid "Parts are virtual by default" msgstr "" #: common/models.py:164 -msgid "Stock Expiry" +msgid "Show Quantity in Forms" msgstr "" #: common/models.py:165 -msgid "Enable stock expiry functionality" +msgid "Display available part quantity in some forms" msgstr "" #: common/models.py:171 -msgid "Sell Expired Stock" +msgid "Stock Expiry" msgstr "" #: common/models.py:172 -msgid "Allow sale of expired stock" +msgid "Enable stock expiry functionality" msgstr "" #: common/models.py:178 -msgid "Stock Stale Time" +msgid "Sell Expired Stock" msgstr "" #: common/models.py:179 -msgid "Number of days stock items are considered stale before expiring" +msgid "Allow sale of expired stock" msgstr "" -#: common/models.py:181 part/templates/part/detail.html:116 -msgid "days" +#: common/models.py:185 +msgid "Stock Stale Time" msgstr "" #: common/models.py:186 -msgid "Build Expired Stock" +msgid "Number of days stock items are considered stale before expiring" msgstr "" -#: common/models.py:187 -msgid "Allow building with expired stock" +#: common/models.py:188 part/templates/part/detail.html:116 +msgid "days" msgstr "" #: common/models.py:193 -msgid "Build Order Reference Prefix" +msgid "Build Expired Stock" msgstr "" #: common/models.py:194 -msgid "Prefix value for build order reference" -msgstr "" - -#: common/models.py:199 -msgid "Build Order Reference Regex" +msgid "Allow building with expired stock" msgstr "" #: common/models.py:200 +msgid "Build Order Reference Prefix" +msgstr "" + +#: common/models.py:201 +msgid "Prefix value for build order reference" +msgstr "" + +#: common/models.py:206 +msgid "Build Order Reference Regex" +msgstr "" + +#: common/models.py:207 msgid "Regular expression pattern for matching build order reference" msgstr "" -#: common/models.py:204 +#: common/models.py:211 msgid "Sales Order Reference Prefix" msgstr "" -#: common/models.py:205 +#: common/models.py:212 msgid "Prefix value for sales order reference" msgstr "" -#: common/models.py:210 +#: common/models.py:217 msgid "Purchase Order Reference Prefix" msgstr "" -#: common/models.py:211 +#: common/models.py:218 msgid "Prefix value for purchase order reference" msgstr "" -#: common/models.py:434 +#: common/models.py:441 msgid "Settings key (must be unique - case insensitive" msgstr "" -#: common/models.py:436 +#: common/models.py:443 msgid "Settings value" msgstr "" -#: common/models.py:493 +#: common/models.py:500 msgid "Value must be a boolean value" msgstr "" -#: common/models.py:503 +#: common/models.py:510 msgid "Value must be an integer value" msgstr "" -#: common/models.py:517 +#: common/models.py:524 msgid "Key string must be unique" msgstr "" -#: common/models.py:590 company/forms.py:113 +#: common/models.py:597 company/forms.py:113 msgid "Price break quantity" msgstr "" -#: common/models.py:598 company/templates/company/supplier_part_pricing.html:80 +#: common/models.py:605 company/templates/company/supplier_part_pricing.html:80 #: part/templates/part/sale_prices.html:87 templates/js/bom.js:246 msgid "Price" msgstr "" -#: common/models.py:599 +#: common/models.py:606 msgid "Unit price at specified quantity" msgstr "" -#: common/models.py:622 +#: common/models.py:629 msgid "Default" msgstr "" @@ -1427,10 +1439,10 @@ msgstr "" #: company/models.py:323 company/templates/company/detail.html:57 #: company/templates/company/supplier_part_base.html:74 #: company/templates/company/supplier_part_detail.html:21 -#: order/templates/order/order_base.html:79 +#: order/templates/order/order_base.html:89 #: order/templates/order/order_wizard/select_pos.html:30 part/bom.py:170 #: stock/templates/stock/item_base.html:304 templates/js/company.js:48 -#: templates/js/company.js:164 templates/js/order.js:162 +#: templates/js/company.js:164 templates/js/order.js:167 msgid "Supplier" msgstr "" @@ -1527,7 +1539,7 @@ msgstr "" #: company/templates/company/detail.html:62 #: order/templates/order/sales_order_base.html:89 stock/models.py:380 #: stock/models.py:381 stock/templates/stock/item_base.html:221 -#: templates/js/company.js:40 templates/js/order.js:250 +#: templates/js/company.js:40 templates/js/order.js:261 msgid "Customer" msgstr "" @@ -1542,7 +1554,7 @@ msgstr "" #: company/templates/company/detail_part.html:18 #: order/templates/order/purchase_order_detail.html:68 -#: part/templates/part/supplier.html:14 templates/js/stock.js:881 +#: part/templates/part/supplier.html:14 templates/js/stock.js:983 msgid "New Supplier Part" msgstr "" @@ -1566,7 +1578,7 @@ msgid "Delete Parts" msgstr "" #: company/templates/company/detail_part.html:63 -#: part/templates/part/category.html:116 templates/js/stock.js:875 +#: part/templates/part/category.html:116 templates/js/stock.js:977 msgid "New Part" msgstr "" @@ -1623,7 +1635,7 @@ msgstr "" #: order/templates/order/purchase_orders.html:13 #: part/templates/part/orders.html:9 part/templates/part/tabs.html:48 #: templates/InvenTree/settings/tabs.html:31 templates/navbar.html:33 -#: users/models.py:31 +#: users/models.py:33 msgid "Purchase Orders" msgstr "" @@ -1643,7 +1655,7 @@ msgstr "" #: order/templates/order/sales_orders.html:13 #: part/templates/part/sales_orders.html:9 part/templates/part/tabs.html:56 #: templates/InvenTree/settings/tabs.html:34 templates/navbar.html:42 -#: users/models.py:32 +#: users/models.py:34 msgid "Sales Orders" msgstr "" @@ -1731,8 +1743,7 @@ msgstr "" #: company/templates/company/tabs.html:12 part/templates/part/tabs.html:18 #: stock/templates/stock/location.html:17 templates/InvenTree/search.html:155 #: templates/InvenTree/settings/tabs.html:25 templates/js/part.js:192 -#: templates/js/part.js:418 templates/js/stock.js:509 templates/navbar.html:22 -#: users/models.py:29 +#: templates/js/part.js:418 templates/js/stock.js:519 templates/navbar.html:22 msgid "Stock" msgstr "" @@ -1745,7 +1756,7 @@ msgstr "" #: part/templates/part/cat_link.html:7 part/templates/part/category.html:94 #: part/templates/part/category_tabs.html:6 #: templates/InvenTree/settings/tabs.html:22 templates/navbar.html:19 -#: templates/stats.html:35 templates/stats.html:44 users/models.py:28 +#: templates/stats.html:35 templates/stats.html:44 users/models.py:29 msgid "Parts" msgstr "" @@ -1814,7 +1825,7 @@ msgstr "" msgid "Edit Supplier Part" msgstr "" -#: company/views.py:295 templates/js/stock.js:882 +#: company/views.py:295 templates/js/stock.js:984 msgid "Create new Supplier Part" msgstr "" @@ -1858,15 +1869,15 @@ msgstr "" msgid "Enabled" msgstr "" -#: order/forms.py:25 order/templates/order/order_base.html:39 +#: order/forms.py:25 order/templates/order/order_base.html:44 msgid "Place order" msgstr "" -#: order/forms.py:36 order/templates/order/order_base.html:46 +#: order/forms.py:36 order/templates/order/order_base.html:51 msgid "Mark order as complete" msgstr "" -#: order/forms.py:47 order/forms.py:58 order/templates/order/order_base.html:51 +#: order/forms.py:47 order/forms.py:58 order/templates/order/order_base.html:56 #: order/templates/order/sales_order_base.html:56 msgid "Cancel order" msgstr "" @@ -1879,15 +1890,19 @@ msgstr "" msgid "Receive parts to this location" msgstr "" -#: order/forms.py:100 +#: order/forms.py:101 msgid "Purchase Order reference" msgstr "" -#: order/forms.py:128 +#: order/forms.py:107 +msgid "Target date for order delivery. Order will be overdue after this date." +msgstr "" + +#: order/forms.py:134 msgid "Enter sales order number" msgstr "" -#: order/forms.py:134 order/models.py:405 +#: order/forms.py:140 order/models.py:438 msgid "" "Target date for order completion. Order will be overdue after this date." msgstr "" @@ -1908,107 +1923,124 @@ msgstr "" msgid "Order notes" msgstr "" -#: order/models.py:169 order/models.py:398 +#: order/models.py:172 order/models.py:431 msgid "Purchase order status" msgstr "" -#: order/models.py:177 +#: order/models.py:180 msgid "Company from which the items are being ordered" msgstr "" -#: order/models.py:180 +#: order/models.py:183 msgid "Supplier order reference code" msgstr "" -#: order/models.py:189 +#: order/models.py:194 +msgid "Issue Date" +msgstr "" + +#: order/models.py:195 msgid "Date order was issued" msgstr "" -#: order/models.py:191 +#: order/models.py:200 +msgid "Target Delivery Date" +msgstr "" + +#: order/models.py:201 +msgid "" +"Expected date for order delivery. Order will be overdue after this date." +msgstr "" + +#: order/models.py:206 +msgid "Completion Date" +msgstr "" + +#: order/models.py:207 msgid "Date order was completed" msgstr "" -#: order/models.py:214 order/models.py:296 part/views.py:1504 +#: order/models.py:231 order/models.py:329 part/views.py:1504 #: stock/models.py:251 stock/models.py:856 msgid "Quantity must be greater than zero" msgstr "" -#: order/models.py:219 +#: order/models.py:236 msgid "Part supplier must match PO supplier" msgstr "" -#: order/models.py:291 +#: order/models.py:324 msgid "Lines can only be received against an order marked as 'Placed'" msgstr "" -#: order/models.py:394 +#: order/models.py:427 msgid "Company to which the items are being sold" msgstr "" -#: order/models.py:400 +#: order/models.py:433 msgid "Customer order reference code" msgstr "" -#: order/models.py:462 +#: order/models.py:491 msgid "SalesOrder cannot be shipped as it is not currently pending" msgstr "" -#: order/models.py:549 +#: order/models.py:578 msgid "Item quantity" msgstr "" -#: order/models.py:551 +#: order/models.py:580 msgid "Line item reference" msgstr "" -#: order/models.py:553 +#: order/models.py:582 msgid "Line item notes" msgstr "" -#: order/models.py:579 order/templates/order/order_base.html:9 +#: order/models.py:608 order/templates/order/order_base.html:9 #: order/templates/order/order_base.html:24 -#: stock/templates/stock/item_base.html:276 templates/js/order.js:146 +#: stock/templates/stock/item_base.html:276 templates/js/order.js:145 msgid "Purchase Order" msgstr "" -#: order/models.py:592 +#: order/models.py:621 msgid "Supplier part" msgstr "" -#: order/models.py:595 +#: order/models.py:624 msgid "Number of items received" msgstr "" -#: order/models.py:602 stock/models.py:473 +#: order/models.py:631 stock/models.py:473 #: stock/templates/stock/item_base.html:283 msgid "Purchase Price" msgstr "" -#: order/models.py:603 +#: order/models.py:632 msgid "Unit purchase price" msgstr "" -#: order/models.py:698 +#: order/models.py:727 msgid "Cannot allocate stock item to a line with a different part" msgstr "" -#: order/models.py:700 +#: order/models.py:729 msgid "Cannot allocate stock to a line without a part" msgstr "" -#: order/models.py:703 +#: order/models.py:732 msgid "Allocation quantity cannot exceed stock quantity" msgstr "" -#: order/models.py:713 +#: order/models.py:742 msgid "Quantity must be 1 for serialized stock item" msgstr "" -#: order/models.py:729 +#: order/models.py:758 msgid "Select stock item to allocate" msgstr "" -#: order/models.py:732 +#: order/models.py:761 msgid "Enter stock allocation quantity" msgstr "" @@ -2018,41 +2050,41 @@ msgstr "" msgid "Are you sure you want to delete this attachment?" msgstr "" -#: order/templates/order/order_base.html:35 +#: order/templates/order/order_base.html:40 msgid "Edit order information" msgstr "" -#: order/templates/order/order_base.html:43 +#: order/templates/order/order_base.html:48 msgid "Receive items" msgstr "" -#: order/templates/order/order_base.html:56 +#: order/templates/order/order_base.html:61 msgid "Export order to file" msgstr "" -#: order/templates/order/order_base.html:64 +#: order/templates/order/order_base.html:69 msgid "Purchase Order Details" msgstr "" -#: order/templates/order/order_base.html:69 +#: order/templates/order/order_base.html:74 #: order/templates/order/sales_order_base.html:74 msgid "Order Reference" msgstr "" -#: order/templates/order/order_base.html:74 +#: order/templates/order/order_base.html:79 #: order/templates/order/sales_order_base.html:79 msgid "Order Status" msgstr "" -#: order/templates/order/order_base.html:85 templates/js/order.js:169 +#: order/templates/order/order_base.html:95 templates/js/order.js:175 msgid "Supplier Reference" msgstr "" -#: order/templates/order/order_base.html:104 +#: order/templates/order/order_base.html:114 msgid "Issued" msgstr "" -#: order/templates/order/order_base.html:111 +#: order/templates/order/order_base.html:128 #: order/templates/order/purchase_order_detail.html:193 #: order/templates/order/receive_parts.html:22 #: order/templates/order/sales_order_base.html:128 @@ -2100,7 +2132,7 @@ msgid "Select existing purchase orders, or create new orders." msgstr "" #: order/templates/order/order_wizard/select_pos.html:31 -#: templates/js/order.js:193 templates/js/order.js:291 +#: templates/js/order.js:203 templates/js/order.js:302 msgid "Items" msgstr "" @@ -2138,7 +2170,7 @@ msgstr "" #: order/templates/order/purchase_order_detail.html:39 #: order/templates/order/purchase_order_detail.html:119 #: part/templates/part/category.html:173 part/templates/part/category.html:215 -#: templates/js/stock.js:627 templates/js/stock.js:887 +#: templates/js/stock.js:642 templates/js/stock.js:989 msgid "New Location" msgstr "" @@ -2207,7 +2239,7 @@ msgstr "" msgid "Sales Order Details" msgstr "" -#: order/templates/order/sales_order_base.html:95 templates/js/order.js:257 +#: order/templates/order/sales_order_base.html:95 templates/js/order.js:268 msgid "Customer Reference" msgstr "" @@ -2334,18 +2366,14 @@ msgstr "" msgid "Confirm order cancellation" msgstr "" -#: order/views.py:435 -msgid "Order cannot be cancelled as either pending or placed" +#: order/views.py:435 order/views.py:462 +msgid "Order cannot be cancelled" msgstr "" #: order/views.py:449 msgid "Cancel sales order" msgstr "" -#: order/views.py:462 -msgid "Order cannot be cancelled" -msgstr "" - #: order/views.py:476 msgid "Issue Order" msgstr "" @@ -2460,123 +2488,123 @@ msgstr "" msgid "Error reading BOM file (incorrect row size)" msgstr "" -#: part/forms.py:61 stock/forms.py:261 +#: part/forms.py:71 stock/forms.py:261 msgid "File Format" msgstr "" -#: part/forms.py:61 stock/forms.py:261 +#: part/forms.py:71 stock/forms.py:261 msgid "Select output file format" msgstr "" -#: part/forms.py:63 +#: part/forms.py:73 msgid "Cascading" msgstr "" -#: part/forms.py:63 +#: part/forms.py:73 msgid "Download cascading / multi-level BOM" msgstr "" -#: part/forms.py:65 +#: part/forms.py:75 msgid "Levels" msgstr "" -#: part/forms.py:65 +#: part/forms.py:75 msgid "Select maximum number of BOM levels to export (0 = all levels)" msgstr "" -#: part/forms.py:67 +#: part/forms.py:77 msgid "Include Parameter Data" msgstr "" -#: part/forms.py:67 +#: part/forms.py:77 msgid "Include part parameters data in exported BOM" msgstr "" -#: part/forms.py:69 +#: part/forms.py:79 msgid "Include Stock Data" msgstr "" -#: part/forms.py:69 +#: part/forms.py:79 msgid "Include part stock data in exported BOM" msgstr "" -#: part/forms.py:71 +#: part/forms.py:81 msgid "Include Supplier Data" msgstr "" -#: part/forms.py:71 +#: part/forms.py:81 msgid "Include part supplier data in exported BOM" msgstr "" -#: part/forms.py:92 part/models.py:1781 +#: part/forms.py:102 part/models.py:1781 msgid "Parent Part" msgstr "" -#: part/forms.py:93 part/templates/part/bom_duplicate.html:7 +#: part/forms.py:103 part/templates/part/bom_duplicate.html:7 msgid "Select parent part to copy BOM from" msgstr "" -#: part/forms.py:99 +#: part/forms.py:109 msgid "Clear existing BOM items" msgstr "" -#: part/forms.py:104 +#: part/forms.py:114 msgid "Confirm BOM duplication" msgstr "" -#: part/forms.py:122 +#: part/forms.py:132 msgid "Confirm that the BOM is correct" msgstr "" -#: part/forms.py:134 +#: part/forms.py:144 msgid "Select BOM file to upload" msgstr "" -#: part/forms.py:153 +#: part/forms.py:163 msgid "Related Part" msgstr "" -#: part/forms.py:172 +#: part/forms.py:182 msgid "Select part category" msgstr "" -#: part/forms.py:189 +#: part/forms.py:199 msgid "Duplicate all BOM data for this part" msgstr "" -#: part/forms.py:190 +#: part/forms.py:200 msgid "Copy BOM" msgstr "" -#: part/forms.py:195 +#: part/forms.py:205 msgid "Duplicate all parameter data for this part" msgstr "" -#: part/forms.py:196 +#: part/forms.py:206 msgid "Copy Parameters" msgstr "" -#: part/forms.py:201 +#: part/forms.py:211 msgid "Confirm part creation" msgstr "" -#: part/forms.py:206 +#: part/forms.py:216 msgid "Include category parameter templates" msgstr "" -#: part/forms.py:211 +#: part/forms.py:221 msgid "Include parent categories parameter templates" msgstr "" -#: part/forms.py:291 +#: part/forms.py:301 msgid "Add parameter template to same level categories" msgstr "" -#: part/forms.py:295 +#: part/forms.py:305 msgid "Add parameter template to all categories" msgstr "" -#: part/forms.py:339 +#: part/forms.py:349 msgid "Input quantity for price calculation" msgstr "" @@ -2595,6 +2623,7 @@ msgstr "" #: part/models.py:78 part/templates/part/category.html:18 #: part/templates/part/category.html:89 templates/stats.html:39 +#: users/models.py:28 msgid "Part Categories" msgstr "" @@ -2742,7 +2771,7 @@ msgstr "" #: part/models.py:821 part/templates/part/detail.html:222 #: templates/js/table_filters.js:19 templates/js/table_filters.js:55 -#: templates/js/table_filters.js:196 templates/js/table_filters.js:261 +#: templates/js/table_filters.js:196 templates/js/table_filters.js:265 msgid "Active" msgstr "" @@ -2770,7 +2799,7 @@ msgstr "" msgid "Test with this name already exists for this part" msgstr "" -#: part/models.py:1690 templates/js/part.js:567 templates/js/stock.js:93 +#: part/models.py:1690 templates/js/part.js:567 templates/js/stock.js:103 msgid "Test Name" msgstr "" @@ -2881,11 +2910,11 @@ msgstr "" msgid "BOM Item" msgstr "" -#: part/models.py:2092 +#: part/models.py:2098 msgid "Select Related Part" msgstr "" -#: part/models.py:2124 +#: part/models.py:2130 msgid "" "Error creating relationship: check that the part is not related to itself " "and that the relationship is unique" @@ -2908,7 +2937,7 @@ msgstr "" #: stock/templates/stock/item_base.html:72 #: stock/templates/stock/item_base.html:291 #: stock/templates/stock/stock_adjust.html:16 templates/js/build.js:751 -#: templates/js/stock.js:720 templates/js/stock.js:980 +#: templates/js/stock.js:822 templates/js/stock.js:1082 msgid "Stock Item" msgstr "" @@ -3125,7 +3154,7 @@ msgstr "" msgid "Export Data" msgstr "" -#: part/templates/part/category.html:174 templates/js/stock.js:628 +#: part/templates/part/category.html:174 templates/js/stock.js:643 msgid "Create new location" msgstr "" @@ -3177,7 +3206,7 @@ msgstr "" msgid "Stock Expiry Time" msgstr "" -#: part/templates/part/detail.html:121 templates/js/order.js:276 +#: part/templates/part/detail.html:121 templates/js/order.js:287 msgid "Creation Date" msgstr "" @@ -3263,17 +3292,17 @@ msgstr "" #: part/templates/part/params.html:15 #: templates/InvenTree/settings/category.html:29 -#: templates/InvenTree/settings/part.html:41 +#: templates/InvenTree/settings/part.html:42 msgid "New Parameter" msgstr "" #: part/templates/part/params.html:25 stock/models.py:1499 -#: templates/InvenTree/settings/header.html:8 templates/js/stock.js:113 +#: templates/InvenTree/settings/header.html:8 templates/js/stock.js:123 msgid "Value" msgstr "" #: part/templates/part/params.html:41 part/templates/part/related.html:41 -#: part/templates/part/supplier.html:19 users/models.py:152 +#: part/templates/part/supplier.html:19 users/models.py:158 msgid "Delete" msgstr "" @@ -3356,7 +3385,7 @@ msgstr "" msgid "Allocated to Sales Orders" msgstr "" -#: part/templates/part/part_base.html:160 +#: part/templates/part/part_base.html:160 templates/js/bom.js:262 msgid "Can Build" msgstr "" @@ -3546,7 +3575,7 @@ msgstr "" msgid "Possible matches exist - confirm creation of new part" msgstr "" -#: part/views.py:594 templates/js/stock.js:876 +#: part/views.py:594 templates/js/stock.js:978 msgid "Create New Part" msgstr "" @@ -3888,7 +3917,7 @@ msgid "Destination Sales Order" msgstr "" #: stock/models.py:440 stock/templates/stock/item_base.html:316 -#: templates/js/stock.js:597 +#: templates/js/stock.js:612 msgid "Expiry Date" msgstr "" @@ -4136,7 +4165,7 @@ msgstr "" msgid "Return to stock" msgstr "" -#: stock/templates/stock/item_base.html:158 templates/js/stock.js:1017 +#: stock/templates/stock/item_base.html:158 templates/js/stock.js:1119 msgid "Uninstall stock item" msgstr "" @@ -4266,47 +4295,48 @@ msgstr "" msgid "Check-in Items" msgstr "" -#: stock/templates/stock/location.html:45 +#: stock/templates/stock/location.html:47 msgid "Location actions" msgstr "" -#: stock/templates/stock/location.html:47 +#: stock/templates/stock/location.html:49 msgid "Edit location" msgstr "" -#: stock/templates/stock/location.html:49 +#: stock/templates/stock/location.html:51 msgid "Delete location" msgstr "" -#: stock/templates/stock/location.html:59 +#: stock/templates/stock/location.html:61 msgid "Location Details" msgstr "" -#: stock/templates/stock/location.html:64 +#: stock/templates/stock/location.html:66 msgid "Location Path" msgstr "" -#: stock/templates/stock/location.html:69 +#: stock/templates/stock/location.html:71 msgid "Location Description" msgstr "" -#: stock/templates/stock/location.html:74 +#: stock/templates/stock/location.html:76 msgid "Sublocations" msgstr "" -#: stock/templates/stock/location.html:79 -#: stock/templates/stock/location.html:94 +#: stock/templates/stock/location.html:81 +#: stock/templates/stock/location.html:96 #: templates/InvenTree/search_stock_items.html:6 templates/stats.html:48 -#: templates/stats.html:57 +#: templates/stats.html:57 users/models.py:31 msgid "Stock Items" msgstr "" -#: stock/templates/stock/location.html:84 +#: stock/templates/stock/location.html:86 msgid "Stock Details" msgstr "" -#: stock/templates/stock/location.html:89 +#: stock/templates/stock/location.html:91 #: templates/InvenTree/search_stock_location.html:6 templates/stats.html:52 +#: users/models.py:30 msgid "Stock Locations" msgstr "" @@ -4596,6 +4626,10 @@ msgstr "" msgid "Outstanding Purchase Orders" msgstr "" +#: templates/InvenTree/po_overdue.html:7 +msgid "Overdue Purchase Orders" +msgstr "" + #: templates/InvenTree/required_stock_build.html:7 msgid "Require Stock To Complete Build" msgstr "" @@ -4612,11 +4646,11 @@ msgstr "" msgid "Enter a search query" msgstr "" -#: templates/InvenTree/search.html:191 templates/js/stock.js:290 +#: templates/InvenTree/search.html:191 templates/js/stock.js:300 msgid "Shipped to customer" msgstr "" -#: templates/InvenTree/search.html:194 templates/js/stock.js:300 +#: templates/InvenTree/search.html:194 templates/js/stock.js:310 msgid "No stock location set" msgstr "" @@ -4645,12 +4679,12 @@ msgid "Default Value" msgstr "" #: templates/InvenTree/settings/category.html:70 -#: templates/InvenTree/settings/part.html:78 +#: templates/InvenTree/settings/part.html:79 msgid "Edit Template" msgstr "" #: templates/InvenTree/settings/category.html:71 -#: templates/InvenTree/settings/part.html:79 +#: templates/InvenTree/settings/part.html:80 msgid "Delete Template" msgstr "" @@ -4670,11 +4704,11 @@ msgstr "" msgid "Part Options" msgstr "" -#: templates/InvenTree/settings/part.html:37 +#: templates/InvenTree/settings/part.html:38 msgid "Part Parameter Templates" msgstr "" -#: templates/InvenTree/settings/part.html:58 +#: templates/InvenTree/settings/part.html:59 msgid "No part parameter templates found" msgstr "" @@ -4931,39 +4965,39 @@ msgstr "" msgid "No pricing available" msgstr "" -#: templates/js/bom.js:272 templates/js/build.js:571 +#: templates/js/bom.js:304 templates/js/build.js:571 msgid "Actions" msgstr "" -#: templates/js/bom.js:280 +#: templates/js/bom.js:312 msgid "Validate BOM Item" msgstr "" -#: templates/js/bom.js:282 +#: templates/js/bom.js:314 msgid "This line has been validated" msgstr "" -#: templates/js/bom.js:284 +#: templates/js/bom.js:316 msgid "Edit BOM Item" msgstr "" -#: templates/js/bom.js:286 +#: templates/js/bom.js:318 msgid "Delete BOM Item" msgstr "" -#: templates/js/bom.js:363 templates/js/build.js:305 +#: templates/js/bom.js:395 templates/js/build.js:305 msgid "No BOM items found" msgstr "" -#: templates/js/bom.js:509 +#: templates/js/bom.js:541 msgid "INACTIVE" msgstr "" -#: templates/js/bom.js:523 +#: templates/js/bom.js:555 msgid "Uses" msgstr "" -#: templates/js/bom.js:534 +#: templates/js/bom.js:566 msgid "No matching parts found" msgstr "" @@ -5047,19 +5081,19 @@ msgstr "" msgid "No purchase orders found" msgstr "" -#: templates/js/order.js:188 templates/js/stock.js:702 -msgid "Date" -msgstr "" - -#: templates/js/order.js:218 -msgid "No sales orders found" -msgstr "" - -#: templates/js/order.js:241 +#: templates/js/order.js:159 templates/js/order.js:252 msgid "Order is overdue" msgstr "" -#: templates/js/order.js:286 +#: templates/js/order.js:193 templates/js/stock.js:804 +msgid "Date" +msgstr "" + +#: templates/js/order.js:229 +msgid "No sales orders found" +msgstr "" + +#: templates/js/order.js:297 msgid "Shipment Date" msgstr "" @@ -5087,8 +5121,8 @@ msgstr "" msgid "No parts found" msgstr "" -#: templates/js/part.js:343 templates/js/stock.js:463 -#: templates/js/stock.js:1049 +#: templates/js/part.js:343 templates/js/stock.js:473 +#: templates/js/stock.js:1151 msgid "Select" msgstr "" @@ -5096,7 +5130,7 @@ msgstr "" msgid "No category" msgstr "" -#: templates/js/part.js:429 templates/js/table_filters.js:274 +#: templates/js/part.js:429 templates/js/table_filters.js:278 msgid "Low stock" msgstr "" @@ -5116,11 +5150,11 @@ msgstr "" msgid "No test templates matching query" msgstr "" -#: templates/js/part.js:604 templates/js/stock.js:64 +#: templates/js/part.js:604 templates/js/stock.js:74 msgid "Edit test result" msgstr "" -#: templates/js/part.js:605 templates/js/stock.js:65 +#: templates/js/part.js:605 templates/js/stock.js:75 msgid "Delete test result" msgstr "" @@ -5128,111 +5162,131 @@ msgstr "" msgid "This test is defined for a parent part" msgstr "" -#: templates/js/stock.js:27 +#: templates/js/stock.js:37 msgid "PASS" msgstr "" -#: templates/js/stock.js:29 +#: templates/js/stock.js:39 msgid "FAIL" msgstr "" -#: templates/js/stock.js:34 +#: templates/js/stock.js:44 msgid "NO RESULT" msgstr "" -#: templates/js/stock.js:60 +#: templates/js/stock.js:70 msgid "Add test result" msgstr "" -#: templates/js/stock.js:79 +#: templates/js/stock.js:89 msgid "No test results found" msgstr "" -#: templates/js/stock.js:121 +#: templates/js/stock.js:131 msgid "Test Date" msgstr "" -#: templates/js/stock.js:282 +#: templates/js/stock.js:292 msgid "In production" msgstr "" -#: templates/js/stock.js:286 +#: templates/js/stock.js:296 msgid "Installed in Stock Item" msgstr "" -#: templates/js/stock.js:294 +#: templates/js/stock.js:304 msgid "Assigned to Sales Order" msgstr "" -#: templates/js/stock.js:314 +#: templates/js/stock.js:324 msgid "No stock items matching query" msgstr "" -#: templates/js/stock.js:431 +#: templates/js/stock.js:441 msgid "Undefined location" msgstr "" -#: templates/js/stock.js:525 +#: templates/js/stock.js:535 msgid "Stock item is in production" msgstr "" -#: templates/js/stock.js:530 +#: templates/js/stock.js:540 msgid "Stock item assigned to sales order" msgstr "" -#: templates/js/stock.js:533 +#: templates/js/stock.js:543 msgid "Stock item assigned to customer" msgstr "" -#: templates/js/stock.js:537 +#: templates/js/stock.js:547 msgid "Stock item has expired" msgstr "" -#: templates/js/stock.js:539 +#: templates/js/stock.js:549 msgid "Stock item will expire soon" msgstr "" -#: templates/js/stock.js:543 +#: templates/js/stock.js:553 msgid "Stock item has been allocated" msgstr "" -#: templates/js/stock.js:547 +#: templates/js/stock.js:557 msgid "Stock item has been installed in another item" msgstr "" -#: templates/js/stock.js:555 +#: templates/js/stock.js:565 msgid "Stock item has been rejected" msgstr "" -#: templates/js/stock.js:559 +#: templates/js/stock.js:569 msgid "Stock item is lost" msgstr "" -#: templates/js/stock.js:562 +#: templates/js/stock.js:572 msgid "Stock item is destroyed" msgstr "" -#: templates/js/stock.js:566 templates/js/table_filters.js:106 +#: templates/js/stock.js:576 templates/js/table_filters.js:106 msgid "Depleted" msgstr "" -#: templates/js/stock.js:768 +#: templates/js/stock.js:605 +msgid "Stocktake" +msgstr "" + +#: templates/js/stock.js:720 +msgid "Stock Status" +msgstr "" + +#: templates/js/stock.js:735 +msgid "Set Stock Status" +msgstr "" + +#: templates/js/stock.js:749 +msgid "Select Status Code" +msgstr "" + +#: templates/js/stock.js:750 +msgid "Status code must be selected" +msgstr "" + +#: templates/js/stock.js:870 msgid "No user information" msgstr "" -#: templates/js/stock.js:888 +#: templates/js/stock.js:990 msgid "Create New Location" msgstr "" -#: templates/js/stock.js:987 +#: templates/js/stock.js:1089 msgid "Serial" msgstr "" -#: templates/js/stock.js:1080 templates/js/table_filters.js:131 +#: templates/js/stock.js:1182 templates/js/table_filters.js:131 msgid "Installed" msgstr "" -#: templates/js/stock.js:1105 +#: templates/js/stock.js:1207 msgid "Install item" msgstr "" @@ -5273,7 +5327,7 @@ msgstr "" msgid "Batch code" msgstr "" -#: templates/js/table_filters.js:91 templates/js/table_filters.js:241 +#: templates/js/table_filters.js:91 templates/js/table_filters.js:245 msgid "Active parts" msgstr "" @@ -5341,43 +5395,43 @@ msgstr "" msgid "Build status" msgstr "" -#: templates/js/table_filters.js:210 templates/js/table_filters.js:223 +#: templates/js/table_filters.js:210 templates/js/table_filters.js:227 msgid "Order status" msgstr "" -#: templates/js/table_filters.js:215 templates/js/table_filters.js:228 +#: templates/js/table_filters.js:215 templates/js/table_filters.js:232 msgid "Outstanding" msgstr "" -#: templates/js/table_filters.js:251 +#: templates/js/table_filters.js:255 msgid "Include subcategories" msgstr "" -#: templates/js/table_filters.js:252 +#: templates/js/table_filters.js:256 msgid "Include parts in subcategories" msgstr "" -#: templates/js/table_filters.js:256 +#: templates/js/table_filters.js:260 msgid "Has IPN" msgstr "" -#: templates/js/table_filters.js:257 +#: templates/js/table_filters.js:261 msgid "Part has internal part number" msgstr "" -#: templates/js/table_filters.js:262 +#: templates/js/table_filters.js:266 msgid "Show active parts" msgstr "" -#: templates/js/table_filters.js:270 +#: templates/js/table_filters.js:274 msgid "Stock available" msgstr "" -#: templates/js/table_filters.js:286 +#: templates/js/table_filters.js:290 msgid "Starred" msgstr "" -#: templates/js/table_filters.js:298 +#: templates/js/table_filters.js:302 msgid "Purchasable" msgstr "" @@ -5477,70 +5531,78 @@ msgstr "" msgid "Order selected items" msgstr "" -#: templates/stock_table.html:28 +#: templates/stock_table.html:26 +msgid "Change status" +msgstr "" + +#: templates/stock_table.html:26 +msgid "Change stock status" +msgstr "" + +#: templates/stock_table.html:29 msgid "Delete selected items" msgstr "" -#: templates/stock_table.html:28 +#: templates/stock_table.html:29 msgid "Delete Stock" msgstr "" -#: users/admin.py:62 +#: users/admin.py:64 msgid "Users" msgstr "" -#: users/admin.py:63 +#: users/admin.py:65 msgid "Select which users are assigned to this group" msgstr "" -#: users/admin.py:178 +#: users/admin.py:187 msgid "The following users are members of multiple groups:" msgstr "" -#: users/admin.py:201 +#: users/admin.py:210 msgid "Personal info" msgstr "" -#: users/admin.py:202 +#: users/admin.py:211 msgid "Permissions" msgstr "" -#: users/admin.py:205 +#: users/admin.py:214 msgid "Important dates" msgstr "" -#: users/models.py:135 +#: users/models.py:141 msgid "Permission set" msgstr "" -#: users/models.py:143 +#: users/models.py:149 msgid "Group" msgstr "" -#: users/models.py:146 +#: users/models.py:152 msgid "View" msgstr "" -#: users/models.py:146 +#: users/models.py:152 msgid "Permission to view items" msgstr "" -#: users/models.py:148 +#: users/models.py:154 msgid "Add" msgstr "" -#: users/models.py:148 +#: users/models.py:154 msgid "Permission to add items" msgstr "" -#: users/models.py:150 +#: users/models.py:156 msgid "Change" msgstr "" -#: users/models.py:150 +#: users/models.py:156 msgid "Permissions to edit items" msgstr "" -#: users/models.py:152 +#: users/models.py:158 msgid "Permission to delete items" msgstr "" diff --git a/InvenTree/locale/es/LC_MESSAGES/django.po b/InvenTree/locale/es/LC_MESSAGES/django.po index 18f86b6972..e5967684a0 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: 2021-01-07 23:48+1100\n" +"POT-Creation-Date: 2021-01-14 17:54+1100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -54,7 +54,7 @@ msgstr "" msgid "Select Category" msgstr "" -#: InvenTree/helpers.py:361 order/models.py:216 order/models.py:298 +#: InvenTree/helpers.py:361 order/models.py:233 order/models.py:331 #: stock/views.py:1660 msgid "Invalid quantity provided" msgstr "" @@ -95,7 +95,7 @@ msgstr "" msgid "File comment" msgstr "" -#: InvenTree/models.py:68 templates/js/stock.js:759 +#: InvenTree/models.py:68 templates/js/stock.js:861 msgid "User" msgstr "" @@ -302,7 +302,7 @@ msgstr "" #: build/forms.py:78 build/templates/build/auto_allocate.html:17 #: build/templates/build/build_base.html:83 -#: build/templates/build/detail.html:29 common/models.py:589 +#: build/templates/build/detail.html:29 common/models.py:596 #: company/forms.py:112 company/templates/company/supplier_part_pricing.html:75 #: order/templates/order/order_wizard/select_parts.html:32 #: order/templates/order/purchase_order_detail.html:179 @@ -315,8 +315,8 @@ msgstr "" #: stock/templates/stock/item_base.html:46 #: stock/templates/stock/item_base.html:214 #: stock/templates/stock/stock_adjust.html:18 templates/js/barcode.js:338 -#: templates/js/bom.js:195 templates/js/build.js:420 templates/js/stock.js:750 -#: templates/js/stock.js:989 +#: templates/js/bom.js:195 templates/js/build.js:420 templates/js/stock.js:852 +#: templates/js/stock.js:1091 msgid "Quantity" msgstr "" @@ -381,7 +381,7 @@ msgstr "" #: build/models.py:62 build/templates/build/index.html:8 #: build/templates/build/index.html:15 order/templates/order/so_builds.html:11 #: order/templates/order/so_tabs.html:9 part/templates/part/tabs.html:31 -#: templates/InvenTree/settings/tabs.html:28 users/models.py:30 +#: templates/InvenTree/settings/tabs.html:28 users/models.py:32 msgid "Build Orders" msgstr "" @@ -402,10 +402,10 @@ msgstr "" #: part/templates/part/detail.html:51 part/templates/part/set_category.html:14 #: templates/InvenTree/search.html:147 #: templates/InvenTree/settings/header.html:9 templates/js/bom.js:180 -#: templates/js/bom.js:517 templates/js/build.js:664 templates/js/company.js:56 -#: templates/js/order.js:175 templates/js/order.js:263 templates/js/part.js:188 +#: templates/js/bom.js:549 templates/js/build.js:664 templates/js/company.js:56 +#: templates/js/order.js:180 templates/js/order.js:274 templates/js/part.js:188 #: templates/js/part.js:271 templates/js/part.js:391 templates/js/part.js:572 -#: templates/js/stock.js:501 templates/js/stock.js:731 +#: templates/js/stock.js:511 templates/js/stock.js:833 msgid "Description" msgstr "" @@ -424,16 +424,16 @@ msgstr "" #: build/models.py:134 build/templates/build/auto_allocate.html:16 #: build/templates/build/build_base.html:78 -#: build/templates/build/detail.html:24 order/models.py:623 +#: build/templates/build/detail.html:24 order/models.py:652 #: order/templates/order/order_wizard/select_parts.html:30 #: order/templates/order/purchase_order_detail.html:148 #: order/templates/order/receive_parts.html:19 part/models.py:316 #: part/templates/part/part_app_base.html:7 part/templates/part/related.html:26 #: part/templates/part/set_category.html:13 templates/InvenTree/search.html:133 -#: templates/js/barcode.js:336 templates/js/bom.js:153 templates/js/bom.js:502 +#: templates/js/barcode.js:336 templates/js/bom.js:153 templates/js/bom.js:534 #: templates/js/build.js:669 templates/js/company.js:138 -#: templates/js/part.js:252 templates/js/part.js:357 templates/js/stock.js:475 -#: templates/js/stock.js:1061 +#: templates/js/part.js:252 templates/js/part.js:357 templates/js/stock.js:485 +#: templates/js/stock.js:1163 msgid "Part" msgstr "" @@ -499,7 +499,7 @@ msgstr "" msgid "Batch code for this build output" msgstr "" -#: build/models.py:205 order/models.py:404 +#: build/models.py:205 order/models.py:437 msgid "Target completion date" msgstr "" @@ -522,7 +522,7 @@ msgstr "" #: part/templates/part/tabs.html:73 stock/forms.py:313 stock/forms.py:345 #: stock/forms.py:373 stock/models.py:463 stock/models.py:1512 #: stock/templates/stock/tabs.html:26 templates/js/barcode.js:391 -#: templates/js/bom.js:263 templates/js/stock.js:117 templates/js/stock.js:603 +#: templates/js/bom.js:295 templates/js/stock.js:127 templates/js/stock.js:618 msgid "Notes" msgstr "" @@ -564,11 +564,11 @@ msgstr "" msgid "Allocated quantity ({n}) must not exceed available quantity ({q})" msgstr "" -#: build/models.py:971 order/models.py:707 +#: build/models.py:971 order/models.py:736 msgid "StockItem is over-allocated" msgstr "" -#: build/models.py:975 order/models.py:710 +#: build/models.py:975 order/models.py:739 msgid "Allocation quantity must be greater than zero" msgstr "" @@ -657,7 +657,7 @@ msgstr "" #: stock/templates/stock/item_base.html:244 #: stock/templates/stock/stock_adjust.html:17 #: templates/InvenTree/search.html:183 templates/js/barcode.js:337 -#: templates/js/build.js:434 templates/js/stock.js:587 +#: templates/js/build.js:434 templates/js/stock.js:597 msgid "Location" msgstr "" @@ -689,9 +689,12 @@ msgstr "" #: build/templates/build/build_base.html:43 #: build/templates/build/build_base.html:100 +#: order/templates/order/order_base.html:32 +#: order/templates/order/order_base.html:83 #: order/templates/order/sales_order_base.html:41 #: order/templates/order/sales_order_base.html:83 -#: templates/js/table_filters.js:200 templates/js/table_filters.js:232 +#: templates/js/table_filters.js:200 templates/js/table_filters.js:219 +#: templates/js/table_filters.js:236 msgid "Overdue" msgstr "" @@ -720,15 +723,16 @@ msgstr "" #: order/templates/order/receive_parts.html:24 #: stock/templates/stock/item_base.html:343 templates/InvenTree/search.html:175 #: templates/js/barcode.js:42 templates/js/build.js:697 -#: templates/js/order.js:180 templates/js/order.js:268 -#: templates/js/stock.js:574 templates/js/stock.js:997 +#: templates/js/order.js:185 templates/js/order.js:279 +#: templates/js/stock.js:584 templates/js/stock.js:1099 msgid "Status" msgstr "" #: build/templates/build/build_base.html:96 #: build/templates/build/detail.html:100 +#: order/templates/order/order_base.html:121 #: order/templates/order/sales_order_base.html:114 templates/js/build.js:710 -#: templates/js/order.js:281 +#: templates/js/order.js:198 templates/js/order.js:292 msgid "Target Date" msgstr "" @@ -742,13 +746,13 @@ msgid "Progress" msgstr "" #: build/templates/build/build_base.html:120 -#: build/templates/build/detail.html:82 order/models.py:621 +#: build/templates/build/detail.html:82 order/models.py:650 #: order/templates/order/sales_order_base.html:9 #: order/templates/order/sales_order_base.html:33 #: order/templates/order/sales_order_notes.html:10 #: order/templates/order/sales_order_ship.html:25 #: part/templates/part/allocation.html:27 -#: stock/templates/stock/item_base.html:238 templates/js/order.js:229 +#: stock/templates/stock/item_base.html:238 templates/js/order.js:240 msgid "Sales Order" msgstr "" @@ -849,14 +853,14 @@ msgid "Destination location not specified" msgstr "" #: build/templates/build/detail.html:68 -#: stock/templates/stock/item_base.html:262 templates/js/stock.js:582 -#: templates/js/stock.js:1004 templates/js/table_filters.js:80 +#: stock/templates/stock/item_base.html:262 templates/js/stock.js:592 +#: templates/js/stock.js:1106 templates/js/table_filters.js:80 #: templates/js/table_filters.js:161 msgid "Batch" msgstr "" #: build/templates/build/detail.html:95 -#: order/templates/order/order_base.html:98 +#: order/templates/order/order_base.html:108 #: order/templates/order/sales_order_base.html:108 templates/js/build.js:705 msgid "Created" msgstr "" @@ -1152,7 +1156,7 @@ msgid "Copy category parameter templates when creating a part" msgstr "" #: common/models.py:115 part/templates/part/detail.html:155 stock/forms.py:255 -#: templates/js/table_filters.js:23 templates/js/table_filters.js:266 +#: templates/js/table_filters.js:23 templates/js/table_filters.js:270 msgid "Template" msgstr "" @@ -1161,7 +1165,7 @@ msgid "Parts are templates by default" msgstr "" #: common/models.py:122 part/models.py:794 part/templates/part/detail.html:165 -#: templates/js/table_filters.js:278 +#: templates/js/table_filters.js:282 msgid "Assembly" msgstr "" @@ -1170,7 +1174,7 @@ msgid "Parts can be assembled from other components by default" msgstr "" #: common/models.py:129 part/models.py:800 part/templates/part/detail.html:175 -#: templates/js/table_filters.js:282 +#: templates/js/table_filters.js:286 msgid "Component" msgstr "" @@ -1187,7 +1191,7 @@ msgid "Parts are purchaseable by default" msgstr "" #: common/models.py:143 part/models.py:816 part/templates/part/detail.html:205 -#: templates/js/table_filters.js:290 +#: templates/js/table_filters.js:294 msgid "Salable" msgstr "" @@ -1196,7 +1200,7 @@ msgid "Parts are salable by default" msgstr "" #: common/models.py:150 part/models.py:806 part/templates/part/detail.html:185 -#: templates/js/table_filters.js:31 templates/js/table_filters.js:294 +#: templates/js/table_filters.js:31 templates/js/table_filters.js:298 msgid "Trackable" msgstr "" @@ -1214,107 +1218,115 @@ msgid "Parts are virtual by default" msgstr "" #: common/models.py:164 -msgid "Stock Expiry" +msgid "Show Quantity in Forms" msgstr "" #: common/models.py:165 -msgid "Enable stock expiry functionality" +msgid "Display available part quantity in some forms" msgstr "" #: common/models.py:171 -msgid "Sell Expired Stock" +msgid "Stock Expiry" msgstr "" #: common/models.py:172 -msgid "Allow sale of expired stock" +msgid "Enable stock expiry functionality" msgstr "" #: common/models.py:178 -msgid "Stock Stale Time" +msgid "Sell Expired Stock" msgstr "" #: common/models.py:179 -msgid "Number of days stock items are considered stale before expiring" +msgid "Allow sale of expired stock" msgstr "" -#: common/models.py:181 part/templates/part/detail.html:116 -msgid "days" +#: common/models.py:185 +msgid "Stock Stale Time" msgstr "" #: common/models.py:186 -msgid "Build Expired Stock" +msgid "Number of days stock items are considered stale before expiring" msgstr "" -#: common/models.py:187 -msgid "Allow building with expired stock" +#: common/models.py:188 part/templates/part/detail.html:116 +msgid "days" msgstr "" #: common/models.py:193 -msgid "Build Order Reference Prefix" +msgid "Build Expired Stock" msgstr "" #: common/models.py:194 -msgid "Prefix value for build order reference" -msgstr "" - -#: common/models.py:199 -msgid "Build Order Reference Regex" +msgid "Allow building with expired stock" msgstr "" #: common/models.py:200 +msgid "Build Order Reference Prefix" +msgstr "" + +#: common/models.py:201 +msgid "Prefix value for build order reference" +msgstr "" + +#: common/models.py:206 +msgid "Build Order Reference Regex" +msgstr "" + +#: common/models.py:207 msgid "Regular expression pattern for matching build order reference" msgstr "" -#: common/models.py:204 +#: common/models.py:211 msgid "Sales Order Reference Prefix" msgstr "" -#: common/models.py:205 +#: common/models.py:212 msgid "Prefix value for sales order reference" msgstr "" -#: common/models.py:210 +#: common/models.py:217 msgid "Purchase Order Reference Prefix" msgstr "" -#: common/models.py:211 +#: common/models.py:218 msgid "Prefix value for purchase order reference" msgstr "" -#: common/models.py:434 +#: common/models.py:441 msgid "Settings key (must be unique - case insensitive" msgstr "" -#: common/models.py:436 +#: common/models.py:443 msgid "Settings value" msgstr "" -#: common/models.py:493 +#: common/models.py:500 msgid "Value must be a boolean value" msgstr "" -#: common/models.py:503 +#: common/models.py:510 msgid "Value must be an integer value" msgstr "" -#: common/models.py:517 +#: common/models.py:524 msgid "Key string must be unique" msgstr "" -#: common/models.py:590 company/forms.py:113 +#: common/models.py:597 company/forms.py:113 msgid "Price break quantity" msgstr "" -#: common/models.py:598 company/templates/company/supplier_part_pricing.html:80 +#: common/models.py:605 company/templates/company/supplier_part_pricing.html:80 #: part/templates/part/sale_prices.html:87 templates/js/bom.js:246 msgid "Price" msgstr "" -#: common/models.py:599 +#: common/models.py:606 msgid "Unit price at specified quantity" msgstr "" -#: common/models.py:622 +#: common/models.py:629 msgid "Default" msgstr "" @@ -1427,10 +1439,10 @@ msgstr "" #: company/models.py:323 company/templates/company/detail.html:57 #: company/templates/company/supplier_part_base.html:74 #: company/templates/company/supplier_part_detail.html:21 -#: order/templates/order/order_base.html:79 +#: order/templates/order/order_base.html:89 #: order/templates/order/order_wizard/select_pos.html:30 part/bom.py:170 #: stock/templates/stock/item_base.html:304 templates/js/company.js:48 -#: templates/js/company.js:164 templates/js/order.js:162 +#: templates/js/company.js:164 templates/js/order.js:167 msgid "Supplier" msgstr "" @@ -1527,7 +1539,7 @@ msgstr "" #: company/templates/company/detail.html:62 #: order/templates/order/sales_order_base.html:89 stock/models.py:380 #: stock/models.py:381 stock/templates/stock/item_base.html:221 -#: templates/js/company.js:40 templates/js/order.js:250 +#: templates/js/company.js:40 templates/js/order.js:261 msgid "Customer" msgstr "" @@ -1542,7 +1554,7 @@ msgstr "" #: company/templates/company/detail_part.html:18 #: order/templates/order/purchase_order_detail.html:68 -#: part/templates/part/supplier.html:14 templates/js/stock.js:881 +#: part/templates/part/supplier.html:14 templates/js/stock.js:983 msgid "New Supplier Part" msgstr "" @@ -1566,7 +1578,7 @@ msgid "Delete Parts" msgstr "" #: company/templates/company/detail_part.html:63 -#: part/templates/part/category.html:116 templates/js/stock.js:875 +#: part/templates/part/category.html:116 templates/js/stock.js:977 msgid "New Part" msgstr "" @@ -1623,7 +1635,7 @@ msgstr "" #: order/templates/order/purchase_orders.html:13 #: part/templates/part/orders.html:9 part/templates/part/tabs.html:48 #: templates/InvenTree/settings/tabs.html:31 templates/navbar.html:33 -#: users/models.py:31 +#: users/models.py:33 msgid "Purchase Orders" msgstr "" @@ -1643,7 +1655,7 @@ msgstr "" #: order/templates/order/sales_orders.html:13 #: part/templates/part/sales_orders.html:9 part/templates/part/tabs.html:56 #: templates/InvenTree/settings/tabs.html:34 templates/navbar.html:42 -#: users/models.py:32 +#: users/models.py:34 msgid "Sales Orders" msgstr "" @@ -1731,8 +1743,7 @@ msgstr "" #: company/templates/company/tabs.html:12 part/templates/part/tabs.html:18 #: stock/templates/stock/location.html:17 templates/InvenTree/search.html:155 #: templates/InvenTree/settings/tabs.html:25 templates/js/part.js:192 -#: templates/js/part.js:418 templates/js/stock.js:509 templates/navbar.html:22 -#: users/models.py:29 +#: templates/js/part.js:418 templates/js/stock.js:519 templates/navbar.html:22 msgid "Stock" msgstr "" @@ -1745,7 +1756,7 @@ msgstr "" #: part/templates/part/cat_link.html:7 part/templates/part/category.html:94 #: part/templates/part/category_tabs.html:6 #: templates/InvenTree/settings/tabs.html:22 templates/navbar.html:19 -#: templates/stats.html:35 templates/stats.html:44 users/models.py:28 +#: templates/stats.html:35 templates/stats.html:44 users/models.py:29 msgid "Parts" msgstr "" @@ -1814,7 +1825,7 @@ msgstr "" msgid "Edit Supplier Part" msgstr "" -#: company/views.py:295 templates/js/stock.js:882 +#: company/views.py:295 templates/js/stock.js:984 msgid "Create new Supplier Part" msgstr "" @@ -1858,15 +1869,15 @@ msgstr "" msgid "Enabled" msgstr "" -#: order/forms.py:25 order/templates/order/order_base.html:39 +#: order/forms.py:25 order/templates/order/order_base.html:44 msgid "Place order" msgstr "" -#: order/forms.py:36 order/templates/order/order_base.html:46 +#: order/forms.py:36 order/templates/order/order_base.html:51 msgid "Mark order as complete" msgstr "" -#: order/forms.py:47 order/forms.py:58 order/templates/order/order_base.html:51 +#: order/forms.py:47 order/forms.py:58 order/templates/order/order_base.html:56 #: order/templates/order/sales_order_base.html:56 msgid "Cancel order" msgstr "" @@ -1879,15 +1890,19 @@ msgstr "" msgid "Receive parts to this location" msgstr "" -#: order/forms.py:100 +#: order/forms.py:101 msgid "Purchase Order reference" msgstr "" -#: order/forms.py:128 +#: order/forms.py:107 +msgid "Target date for order delivery. Order will be overdue after this date." +msgstr "" + +#: order/forms.py:134 msgid "Enter sales order number" msgstr "" -#: order/forms.py:134 order/models.py:405 +#: order/forms.py:140 order/models.py:438 msgid "" "Target date for order completion. Order will be overdue after this date." msgstr "" @@ -1908,107 +1923,124 @@ msgstr "" msgid "Order notes" msgstr "" -#: order/models.py:169 order/models.py:398 +#: order/models.py:172 order/models.py:431 msgid "Purchase order status" msgstr "" -#: order/models.py:177 +#: order/models.py:180 msgid "Company from which the items are being ordered" msgstr "" -#: order/models.py:180 +#: order/models.py:183 msgid "Supplier order reference code" msgstr "" -#: order/models.py:189 +#: order/models.py:194 +msgid "Issue Date" +msgstr "" + +#: order/models.py:195 msgid "Date order was issued" msgstr "" -#: order/models.py:191 +#: order/models.py:200 +msgid "Target Delivery Date" +msgstr "" + +#: order/models.py:201 +msgid "" +"Expected date for order delivery. Order will be overdue after this date." +msgstr "" + +#: order/models.py:206 +msgid "Completion Date" +msgstr "" + +#: order/models.py:207 msgid "Date order was completed" msgstr "" -#: order/models.py:214 order/models.py:296 part/views.py:1504 +#: order/models.py:231 order/models.py:329 part/views.py:1504 #: stock/models.py:251 stock/models.py:856 msgid "Quantity must be greater than zero" msgstr "" -#: order/models.py:219 +#: order/models.py:236 msgid "Part supplier must match PO supplier" msgstr "" -#: order/models.py:291 +#: order/models.py:324 msgid "Lines can only be received against an order marked as 'Placed'" msgstr "" -#: order/models.py:394 +#: order/models.py:427 msgid "Company to which the items are being sold" msgstr "" -#: order/models.py:400 +#: order/models.py:433 msgid "Customer order reference code" msgstr "" -#: order/models.py:462 +#: order/models.py:491 msgid "SalesOrder cannot be shipped as it is not currently pending" msgstr "" -#: order/models.py:549 +#: order/models.py:578 msgid "Item quantity" msgstr "" -#: order/models.py:551 +#: order/models.py:580 msgid "Line item reference" msgstr "" -#: order/models.py:553 +#: order/models.py:582 msgid "Line item notes" msgstr "" -#: order/models.py:579 order/templates/order/order_base.html:9 +#: order/models.py:608 order/templates/order/order_base.html:9 #: order/templates/order/order_base.html:24 -#: stock/templates/stock/item_base.html:276 templates/js/order.js:146 +#: stock/templates/stock/item_base.html:276 templates/js/order.js:145 msgid "Purchase Order" msgstr "" -#: order/models.py:592 +#: order/models.py:621 msgid "Supplier part" msgstr "" -#: order/models.py:595 +#: order/models.py:624 msgid "Number of items received" msgstr "" -#: order/models.py:602 stock/models.py:473 +#: order/models.py:631 stock/models.py:473 #: stock/templates/stock/item_base.html:283 msgid "Purchase Price" msgstr "" -#: order/models.py:603 +#: order/models.py:632 msgid "Unit purchase price" msgstr "" -#: order/models.py:698 +#: order/models.py:727 msgid "Cannot allocate stock item to a line with a different part" msgstr "" -#: order/models.py:700 +#: order/models.py:729 msgid "Cannot allocate stock to a line without a part" msgstr "" -#: order/models.py:703 +#: order/models.py:732 msgid "Allocation quantity cannot exceed stock quantity" msgstr "" -#: order/models.py:713 +#: order/models.py:742 msgid "Quantity must be 1 for serialized stock item" msgstr "" -#: order/models.py:729 +#: order/models.py:758 msgid "Select stock item to allocate" msgstr "" -#: order/models.py:732 +#: order/models.py:761 msgid "Enter stock allocation quantity" msgstr "" @@ -2018,41 +2050,41 @@ msgstr "" msgid "Are you sure you want to delete this attachment?" msgstr "" -#: order/templates/order/order_base.html:35 +#: order/templates/order/order_base.html:40 msgid "Edit order information" msgstr "" -#: order/templates/order/order_base.html:43 +#: order/templates/order/order_base.html:48 msgid "Receive items" msgstr "" -#: order/templates/order/order_base.html:56 +#: order/templates/order/order_base.html:61 msgid "Export order to file" msgstr "" -#: order/templates/order/order_base.html:64 +#: order/templates/order/order_base.html:69 msgid "Purchase Order Details" msgstr "" -#: order/templates/order/order_base.html:69 +#: order/templates/order/order_base.html:74 #: order/templates/order/sales_order_base.html:74 msgid "Order Reference" msgstr "" -#: order/templates/order/order_base.html:74 +#: order/templates/order/order_base.html:79 #: order/templates/order/sales_order_base.html:79 msgid "Order Status" msgstr "" -#: order/templates/order/order_base.html:85 templates/js/order.js:169 +#: order/templates/order/order_base.html:95 templates/js/order.js:175 msgid "Supplier Reference" msgstr "" -#: order/templates/order/order_base.html:104 +#: order/templates/order/order_base.html:114 msgid "Issued" msgstr "" -#: order/templates/order/order_base.html:111 +#: order/templates/order/order_base.html:128 #: order/templates/order/purchase_order_detail.html:193 #: order/templates/order/receive_parts.html:22 #: order/templates/order/sales_order_base.html:128 @@ -2100,7 +2132,7 @@ msgid "Select existing purchase orders, or create new orders." msgstr "" #: order/templates/order/order_wizard/select_pos.html:31 -#: templates/js/order.js:193 templates/js/order.js:291 +#: templates/js/order.js:203 templates/js/order.js:302 msgid "Items" msgstr "" @@ -2138,7 +2170,7 @@ msgstr "" #: order/templates/order/purchase_order_detail.html:39 #: order/templates/order/purchase_order_detail.html:119 #: part/templates/part/category.html:173 part/templates/part/category.html:215 -#: templates/js/stock.js:627 templates/js/stock.js:887 +#: templates/js/stock.js:642 templates/js/stock.js:989 msgid "New Location" msgstr "" @@ -2207,7 +2239,7 @@ msgstr "" msgid "Sales Order Details" msgstr "" -#: order/templates/order/sales_order_base.html:95 templates/js/order.js:257 +#: order/templates/order/sales_order_base.html:95 templates/js/order.js:268 msgid "Customer Reference" msgstr "" @@ -2334,18 +2366,14 @@ msgstr "" msgid "Confirm order cancellation" msgstr "" -#: order/views.py:435 -msgid "Order cannot be cancelled as either pending or placed" +#: order/views.py:435 order/views.py:462 +msgid "Order cannot be cancelled" msgstr "" #: order/views.py:449 msgid "Cancel sales order" msgstr "" -#: order/views.py:462 -msgid "Order cannot be cancelled" -msgstr "" - #: order/views.py:476 msgid "Issue Order" msgstr "" @@ -2460,123 +2488,123 @@ msgstr "" msgid "Error reading BOM file (incorrect row size)" msgstr "" -#: part/forms.py:61 stock/forms.py:261 +#: part/forms.py:71 stock/forms.py:261 msgid "File Format" msgstr "" -#: part/forms.py:61 stock/forms.py:261 +#: part/forms.py:71 stock/forms.py:261 msgid "Select output file format" msgstr "" -#: part/forms.py:63 +#: part/forms.py:73 msgid "Cascading" msgstr "" -#: part/forms.py:63 +#: part/forms.py:73 msgid "Download cascading / multi-level BOM" msgstr "" -#: part/forms.py:65 +#: part/forms.py:75 msgid "Levels" msgstr "" -#: part/forms.py:65 +#: part/forms.py:75 msgid "Select maximum number of BOM levels to export (0 = all levels)" msgstr "" -#: part/forms.py:67 +#: part/forms.py:77 msgid "Include Parameter Data" msgstr "" -#: part/forms.py:67 +#: part/forms.py:77 msgid "Include part parameters data in exported BOM" msgstr "" -#: part/forms.py:69 +#: part/forms.py:79 msgid "Include Stock Data" msgstr "" -#: part/forms.py:69 +#: part/forms.py:79 msgid "Include part stock data in exported BOM" msgstr "" -#: part/forms.py:71 +#: part/forms.py:81 msgid "Include Supplier Data" msgstr "" -#: part/forms.py:71 +#: part/forms.py:81 msgid "Include part supplier data in exported BOM" msgstr "" -#: part/forms.py:92 part/models.py:1781 +#: part/forms.py:102 part/models.py:1781 msgid "Parent Part" msgstr "" -#: part/forms.py:93 part/templates/part/bom_duplicate.html:7 +#: part/forms.py:103 part/templates/part/bom_duplicate.html:7 msgid "Select parent part to copy BOM from" msgstr "" -#: part/forms.py:99 +#: part/forms.py:109 msgid "Clear existing BOM items" msgstr "" -#: part/forms.py:104 +#: part/forms.py:114 msgid "Confirm BOM duplication" msgstr "" -#: part/forms.py:122 +#: part/forms.py:132 msgid "Confirm that the BOM is correct" msgstr "" -#: part/forms.py:134 +#: part/forms.py:144 msgid "Select BOM file to upload" msgstr "" -#: part/forms.py:153 +#: part/forms.py:163 msgid "Related Part" msgstr "" -#: part/forms.py:172 +#: part/forms.py:182 msgid "Select part category" msgstr "" -#: part/forms.py:189 +#: part/forms.py:199 msgid "Duplicate all BOM data for this part" msgstr "" -#: part/forms.py:190 +#: part/forms.py:200 msgid "Copy BOM" msgstr "" -#: part/forms.py:195 +#: part/forms.py:205 msgid "Duplicate all parameter data for this part" msgstr "" -#: part/forms.py:196 +#: part/forms.py:206 msgid "Copy Parameters" msgstr "" -#: part/forms.py:201 +#: part/forms.py:211 msgid "Confirm part creation" msgstr "" -#: part/forms.py:206 +#: part/forms.py:216 msgid "Include category parameter templates" msgstr "" -#: part/forms.py:211 +#: part/forms.py:221 msgid "Include parent categories parameter templates" msgstr "" -#: part/forms.py:291 +#: part/forms.py:301 msgid "Add parameter template to same level categories" msgstr "" -#: part/forms.py:295 +#: part/forms.py:305 msgid "Add parameter template to all categories" msgstr "" -#: part/forms.py:339 +#: part/forms.py:349 msgid "Input quantity for price calculation" msgstr "" @@ -2595,6 +2623,7 @@ msgstr "" #: part/models.py:78 part/templates/part/category.html:18 #: part/templates/part/category.html:89 templates/stats.html:39 +#: users/models.py:28 msgid "Part Categories" msgstr "" @@ -2742,7 +2771,7 @@ msgstr "" #: part/models.py:821 part/templates/part/detail.html:222 #: templates/js/table_filters.js:19 templates/js/table_filters.js:55 -#: templates/js/table_filters.js:196 templates/js/table_filters.js:261 +#: templates/js/table_filters.js:196 templates/js/table_filters.js:265 msgid "Active" msgstr "" @@ -2770,7 +2799,7 @@ msgstr "" msgid "Test with this name already exists for this part" msgstr "" -#: part/models.py:1690 templates/js/part.js:567 templates/js/stock.js:93 +#: part/models.py:1690 templates/js/part.js:567 templates/js/stock.js:103 msgid "Test Name" msgstr "" @@ -2881,11 +2910,11 @@ msgstr "" msgid "BOM Item" msgstr "" -#: part/models.py:2092 +#: part/models.py:2098 msgid "Select Related Part" msgstr "" -#: part/models.py:2124 +#: part/models.py:2130 msgid "" "Error creating relationship: check that the part is not related to itself " "and that the relationship is unique" @@ -2908,7 +2937,7 @@ msgstr "" #: stock/templates/stock/item_base.html:72 #: stock/templates/stock/item_base.html:291 #: stock/templates/stock/stock_adjust.html:16 templates/js/build.js:751 -#: templates/js/stock.js:720 templates/js/stock.js:980 +#: templates/js/stock.js:822 templates/js/stock.js:1082 msgid "Stock Item" msgstr "" @@ -3125,7 +3154,7 @@ msgstr "" msgid "Export Data" msgstr "" -#: part/templates/part/category.html:174 templates/js/stock.js:628 +#: part/templates/part/category.html:174 templates/js/stock.js:643 msgid "Create new location" msgstr "" @@ -3177,7 +3206,7 @@ msgstr "" msgid "Stock Expiry Time" msgstr "" -#: part/templates/part/detail.html:121 templates/js/order.js:276 +#: part/templates/part/detail.html:121 templates/js/order.js:287 msgid "Creation Date" msgstr "" @@ -3263,17 +3292,17 @@ msgstr "" #: part/templates/part/params.html:15 #: templates/InvenTree/settings/category.html:29 -#: templates/InvenTree/settings/part.html:41 +#: templates/InvenTree/settings/part.html:42 msgid "New Parameter" msgstr "" #: part/templates/part/params.html:25 stock/models.py:1499 -#: templates/InvenTree/settings/header.html:8 templates/js/stock.js:113 +#: templates/InvenTree/settings/header.html:8 templates/js/stock.js:123 msgid "Value" msgstr "" #: part/templates/part/params.html:41 part/templates/part/related.html:41 -#: part/templates/part/supplier.html:19 users/models.py:152 +#: part/templates/part/supplier.html:19 users/models.py:158 msgid "Delete" msgstr "" @@ -3356,7 +3385,7 @@ msgstr "" msgid "Allocated to Sales Orders" msgstr "" -#: part/templates/part/part_base.html:160 +#: part/templates/part/part_base.html:160 templates/js/bom.js:262 msgid "Can Build" msgstr "" @@ -3546,7 +3575,7 @@ msgstr "" msgid "Possible matches exist - confirm creation of new part" msgstr "" -#: part/views.py:594 templates/js/stock.js:876 +#: part/views.py:594 templates/js/stock.js:978 msgid "Create New Part" msgstr "" @@ -3888,7 +3917,7 @@ msgid "Destination Sales Order" msgstr "" #: stock/models.py:440 stock/templates/stock/item_base.html:316 -#: templates/js/stock.js:597 +#: templates/js/stock.js:612 msgid "Expiry Date" msgstr "" @@ -4136,7 +4165,7 @@ msgstr "" msgid "Return to stock" msgstr "" -#: stock/templates/stock/item_base.html:158 templates/js/stock.js:1017 +#: stock/templates/stock/item_base.html:158 templates/js/stock.js:1119 msgid "Uninstall stock item" msgstr "" @@ -4266,47 +4295,48 @@ msgstr "" msgid "Check-in Items" msgstr "" -#: stock/templates/stock/location.html:45 +#: stock/templates/stock/location.html:47 msgid "Location actions" msgstr "" -#: stock/templates/stock/location.html:47 +#: stock/templates/stock/location.html:49 msgid "Edit location" msgstr "" -#: stock/templates/stock/location.html:49 +#: stock/templates/stock/location.html:51 msgid "Delete location" msgstr "" -#: stock/templates/stock/location.html:59 +#: stock/templates/stock/location.html:61 msgid "Location Details" msgstr "" -#: stock/templates/stock/location.html:64 +#: stock/templates/stock/location.html:66 msgid "Location Path" msgstr "" -#: stock/templates/stock/location.html:69 +#: stock/templates/stock/location.html:71 msgid "Location Description" msgstr "" -#: stock/templates/stock/location.html:74 +#: stock/templates/stock/location.html:76 msgid "Sublocations" msgstr "" -#: stock/templates/stock/location.html:79 -#: stock/templates/stock/location.html:94 +#: stock/templates/stock/location.html:81 +#: stock/templates/stock/location.html:96 #: templates/InvenTree/search_stock_items.html:6 templates/stats.html:48 -#: templates/stats.html:57 +#: templates/stats.html:57 users/models.py:31 msgid "Stock Items" msgstr "" -#: stock/templates/stock/location.html:84 +#: stock/templates/stock/location.html:86 msgid "Stock Details" msgstr "" -#: stock/templates/stock/location.html:89 +#: stock/templates/stock/location.html:91 #: templates/InvenTree/search_stock_location.html:6 templates/stats.html:52 +#: users/models.py:30 msgid "Stock Locations" msgstr "" @@ -4596,6 +4626,10 @@ msgstr "" msgid "Outstanding Purchase Orders" msgstr "" +#: templates/InvenTree/po_overdue.html:7 +msgid "Overdue Purchase Orders" +msgstr "" + #: templates/InvenTree/required_stock_build.html:7 msgid "Require Stock To Complete Build" msgstr "" @@ -4612,11 +4646,11 @@ msgstr "" msgid "Enter a search query" msgstr "" -#: templates/InvenTree/search.html:191 templates/js/stock.js:290 +#: templates/InvenTree/search.html:191 templates/js/stock.js:300 msgid "Shipped to customer" msgstr "" -#: templates/InvenTree/search.html:194 templates/js/stock.js:300 +#: templates/InvenTree/search.html:194 templates/js/stock.js:310 msgid "No stock location set" msgstr "" @@ -4645,12 +4679,12 @@ msgid "Default Value" msgstr "" #: templates/InvenTree/settings/category.html:70 -#: templates/InvenTree/settings/part.html:78 +#: templates/InvenTree/settings/part.html:79 msgid "Edit Template" msgstr "" #: templates/InvenTree/settings/category.html:71 -#: templates/InvenTree/settings/part.html:79 +#: templates/InvenTree/settings/part.html:80 msgid "Delete Template" msgstr "" @@ -4670,11 +4704,11 @@ msgstr "" msgid "Part Options" msgstr "" -#: templates/InvenTree/settings/part.html:37 +#: templates/InvenTree/settings/part.html:38 msgid "Part Parameter Templates" msgstr "" -#: templates/InvenTree/settings/part.html:58 +#: templates/InvenTree/settings/part.html:59 msgid "No part parameter templates found" msgstr "" @@ -4931,39 +4965,39 @@ msgstr "" msgid "No pricing available" msgstr "" -#: templates/js/bom.js:272 templates/js/build.js:571 +#: templates/js/bom.js:304 templates/js/build.js:571 msgid "Actions" msgstr "" -#: templates/js/bom.js:280 +#: templates/js/bom.js:312 msgid "Validate BOM Item" msgstr "" -#: templates/js/bom.js:282 +#: templates/js/bom.js:314 msgid "This line has been validated" msgstr "" -#: templates/js/bom.js:284 +#: templates/js/bom.js:316 msgid "Edit BOM Item" msgstr "" -#: templates/js/bom.js:286 +#: templates/js/bom.js:318 msgid "Delete BOM Item" msgstr "" -#: templates/js/bom.js:363 templates/js/build.js:305 +#: templates/js/bom.js:395 templates/js/build.js:305 msgid "No BOM items found" msgstr "" -#: templates/js/bom.js:509 +#: templates/js/bom.js:541 msgid "INACTIVE" msgstr "" -#: templates/js/bom.js:523 +#: templates/js/bom.js:555 msgid "Uses" msgstr "" -#: templates/js/bom.js:534 +#: templates/js/bom.js:566 msgid "No matching parts found" msgstr "" @@ -5047,19 +5081,19 @@ msgstr "" msgid "No purchase orders found" msgstr "" -#: templates/js/order.js:188 templates/js/stock.js:702 -msgid "Date" -msgstr "" - -#: templates/js/order.js:218 -msgid "No sales orders found" -msgstr "" - -#: templates/js/order.js:241 +#: templates/js/order.js:159 templates/js/order.js:252 msgid "Order is overdue" msgstr "" -#: templates/js/order.js:286 +#: templates/js/order.js:193 templates/js/stock.js:804 +msgid "Date" +msgstr "" + +#: templates/js/order.js:229 +msgid "No sales orders found" +msgstr "" + +#: templates/js/order.js:297 msgid "Shipment Date" msgstr "" @@ -5087,8 +5121,8 @@ msgstr "" msgid "No parts found" msgstr "" -#: templates/js/part.js:343 templates/js/stock.js:463 -#: templates/js/stock.js:1049 +#: templates/js/part.js:343 templates/js/stock.js:473 +#: templates/js/stock.js:1151 msgid "Select" msgstr "" @@ -5096,7 +5130,7 @@ msgstr "" msgid "No category" msgstr "" -#: templates/js/part.js:429 templates/js/table_filters.js:274 +#: templates/js/part.js:429 templates/js/table_filters.js:278 msgid "Low stock" msgstr "" @@ -5116,11 +5150,11 @@ msgstr "" msgid "No test templates matching query" msgstr "" -#: templates/js/part.js:604 templates/js/stock.js:64 +#: templates/js/part.js:604 templates/js/stock.js:74 msgid "Edit test result" msgstr "" -#: templates/js/part.js:605 templates/js/stock.js:65 +#: templates/js/part.js:605 templates/js/stock.js:75 msgid "Delete test result" msgstr "" @@ -5128,111 +5162,131 @@ msgstr "" msgid "This test is defined for a parent part" msgstr "" -#: templates/js/stock.js:27 +#: templates/js/stock.js:37 msgid "PASS" msgstr "" -#: templates/js/stock.js:29 +#: templates/js/stock.js:39 msgid "FAIL" msgstr "" -#: templates/js/stock.js:34 +#: templates/js/stock.js:44 msgid "NO RESULT" msgstr "" -#: templates/js/stock.js:60 +#: templates/js/stock.js:70 msgid "Add test result" msgstr "" -#: templates/js/stock.js:79 +#: templates/js/stock.js:89 msgid "No test results found" msgstr "" -#: templates/js/stock.js:121 +#: templates/js/stock.js:131 msgid "Test Date" msgstr "" -#: templates/js/stock.js:282 +#: templates/js/stock.js:292 msgid "In production" msgstr "" -#: templates/js/stock.js:286 +#: templates/js/stock.js:296 msgid "Installed in Stock Item" msgstr "" -#: templates/js/stock.js:294 +#: templates/js/stock.js:304 msgid "Assigned to Sales Order" msgstr "" -#: templates/js/stock.js:314 +#: templates/js/stock.js:324 msgid "No stock items matching query" msgstr "" -#: templates/js/stock.js:431 +#: templates/js/stock.js:441 msgid "Undefined location" msgstr "" -#: templates/js/stock.js:525 +#: templates/js/stock.js:535 msgid "Stock item is in production" msgstr "" -#: templates/js/stock.js:530 +#: templates/js/stock.js:540 msgid "Stock item assigned to sales order" msgstr "" -#: templates/js/stock.js:533 +#: templates/js/stock.js:543 msgid "Stock item assigned to customer" msgstr "" -#: templates/js/stock.js:537 +#: templates/js/stock.js:547 msgid "Stock item has expired" msgstr "" -#: templates/js/stock.js:539 +#: templates/js/stock.js:549 msgid "Stock item will expire soon" msgstr "" -#: templates/js/stock.js:543 +#: templates/js/stock.js:553 msgid "Stock item has been allocated" msgstr "" -#: templates/js/stock.js:547 +#: templates/js/stock.js:557 msgid "Stock item has been installed in another item" msgstr "" -#: templates/js/stock.js:555 +#: templates/js/stock.js:565 msgid "Stock item has been rejected" msgstr "" -#: templates/js/stock.js:559 +#: templates/js/stock.js:569 msgid "Stock item is lost" msgstr "" -#: templates/js/stock.js:562 +#: templates/js/stock.js:572 msgid "Stock item is destroyed" msgstr "" -#: templates/js/stock.js:566 templates/js/table_filters.js:106 +#: templates/js/stock.js:576 templates/js/table_filters.js:106 msgid "Depleted" msgstr "" -#: templates/js/stock.js:768 +#: templates/js/stock.js:605 +msgid "Stocktake" +msgstr "" + +#: templates/js/stock.js:720 +msgid "Stock Status" +msgstr "" + +#: templates/js/stock.js:735 +msgid "Set Stock Status" +msgstr "" + +#: templates/js/stock.js:749 +msgid "Select Status Code" +msgstr "" + +#: templates/js/stock.js:750 +msgid "Status code must be selected" +msgstr "" + +#: templates/js/stock.js:870 msgid "No user information" msgstr "" -#: templates/js/stock.js:888 +#: templates/js/stock.js:990 msgid "Create New Location" msgstr "" -#: templates/js/stock.js:987 +#: templates/js/stock.js:1089 msgid "Serial" msgstr "" -#: templates/js/stock.js:1080 templates/js/table_filters.js:131 +#: templates/js/stock.js:1182 templates/js/table_filters.js:131 msgid "Installed" msgstr "" -#: templates/js/stock.js:1105 +#: templates/js/stock.js:1207 msgid "Install item" msgstr "" @@ -5273,7 +5327,7 @@ msgstr "" msgid "Batch code" msgstr "" -#: templates/js/table_filters.js:91 templates/js/table_filters.js:241 +#: templates/js/table_filters.js:91 templates/js/table_filters.js:245 msgid "Active parts" msgstr "" @@ -5341,43 +5395,43 @@ msgstr "" msgid "Build status" msgstr "" -#: templates/js/table_filters.js:210 templates/js/table_filters.js:223 +#: templates/js/table_filters.js:210 templates/js/table_filters.js:227 msgid "Order status" msgstr "" -#: templates/js/table_filters.js:215 templates/js/table_filters.js:228 +#: templates/js/table_filters.js:215 templates/js/table_filters.js:232 msgid "Outstanding" msgstr "" -#: templates/js/table_filters.js:251 +#: templates/js/table_filters.js:255 msgid "Include subcategories" msgstr "" -#: templates/js/table_filters.js:252 +#: templates/js/table_filters.js:256 msgid "Include parts in subcategories" msgstr "" -#: templates/js/table_filters.js:256 +#: templates/js/table_filters.js:260 msgid "Has IPN" msgstr "" -#: templates/js/table_filters.js:257 +#: templates/js/table_filters.js:261 msgid "Part has internal part number" msgstr "" -#: templates/js/table_filters.js:262 +#: templates/js/table_filters.js:266 msgid "Show active parts" msgstr "" -#: templates/js/table_filters.js:270 +#: templates/js/table_filters.js:274 msgid "Stock available" msgstr "" -#: templates/js/table_filters.js:286 +#: templates/js/table_filters.js:290 msgid "Starred" msgstr "" -#: templates/js/table_filters.js:298 +#: templates/js/table_filters.js:302 msgid "Purchasable" msgstr "" @@ -5477,70 +5531,78 @@ msgstr "" msgid "Order selected items" msgstr "" -#: templates/stock_table.html:28 +#: templates/stock_table.html:26 +msgid "Change status" +msgstr "" + +#: templates/stock_table.html:26 +msgid "Change stock status" +msgstr "" + +#: templates/stock_table.html:29 msgid "Delete selected items" msgstr "" -#: templates/stock_table.html:28 +#: templates/stock_table.html:29 msgid "Delete Stock" msgstr "" -#: users/admin.py:62 +#: users/admin.py:64 msgid "Users" msgstr "" -#: users/admin.py:63 +#: users/admin.py:65 msgid "Select which users are assigned to this group" msgstr "" -#: users/admin.py:178 +#: users/admin.py:187 msgid "The following users are members of multiple groups:" msgstr "" -#: users/admin.py:201 +#: users/admin.py:210 msgid "Personal info" msgstr "" -#: users/admin.py:202 +#: users/admin.py:211 msgid "Permissions" msgstr "" -#: users/admin.py:205 +#: users/admin.py:214 msgid "Important dates" msgstr "" -#: users/models.py:135 +#: users/models.py:141 msgid "Permission set" msgstr "" -#: users/models.py:143 +#: users/models.py:149 msgid "Group" msgstr "" -#: users/models.py:146 +#: users/models.py:152 msgid "View" msgstr "" -#: users/models.py:146 +#: users/models.py:152 msgid "Permission to view items" msgstr "" -#: users/models.py:148 +#: users/models.py:154 msgid "Add" msgstr "" -#: users/models.py:148 +#: users/models.py:154 msgid "Permission to add items" msgstr "" -#: users/models.py:150 +#: users/models.py:156 msgid "Change" msgstr "" -#: users/models.py:150 +#: users/models.py:156 msgid "Permissions to edit items" msgstr "" -#: users/models.py:152 +#: users/models.py:158 msgid "Permission to delete items" msgstr "" From 3cfe358102da29ab4102aa5b630d3a2fa2d8395e Mon Sep 17 00:00:00 2001 From: Rob Ludwick Date: Mon, 11 Jan 2021 23:37:10 -0700 Subject: [PATCH 22/25] Fixes #1215. Allow secret key to come from file. --- InvenTree/InvenTree/settings.py | 57 +++++++++++++++++++++------------ 1 file changed, 37 insertions(+), 20 deletions(-) diff --git a/InvenTree/InvenTree/settings.py b/InvenTree/InvenTree/settings.py index 7247caa8d9..42f4ba4660 100644 --- a/InvenTree/InvenTree/settings.py +++ b/InvenTree/InvenTree/settings.py @@ -11,17 +11,20 @@ database setup in this file. """ -import sys -import os import logging +import os +import sys import tempfile -import yaml - from datetime import datetime +import yaml from django.utils.translation import gettext_lazy as _ +def _is_true(x): + return x in [True, "True", "true", "Y", "y", "1"] + + # Build paths inside the project like this: os.path.join(BASE_DIR, ...) BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) @@ -36,11 +39,14 @@ with open(cfg_filename, 'r') as cfg: # Default action is to run the system in Debug mode # SECURITY WARNING: don't run with debug turned on in production! -DEBUG = CONFIG.get('debug', True) +DEBUG = _is_true(os.getenv("INVENTREE_DEBUG", CONFIG.get("debug", True))) # Configure logging settings - log_level = CONFIG.get('log_level', 'DEBUG').upper() +logging.basicConfig( + level=log_level, + format="%(asctime)s %(levelname)s %(message)s", +) if log_level not in ['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL']: log_level = 'WARNING' @@ -59,20 +65,31 @@ LOGGING = { }, } -logging.basicConfig( - level=log_level, - format='%(asctime)s %(levelname)s %(message)s', -) - # Get a logger instance for this setup file logger = logging.getLogger(__name__) -# Read the autogenerated key-file -key_file_name = os.path.join(BASE_DIR, 'secret_key.txt') -logger.info(f'Loading SECRET_KEY from {key_file_name}') -key_file = open(key_file_name, 'r') - -SECRET_KEY = key_file.read().strip() +if os.getenv("INVENTREE_SECRET_KEY"): + # Secret key passed in directly + SECRET_KEY = os.getenv("INVENTREE_SECRET_KEY").strip() + logger.info("SECRET_KEY loaded by INVENTREE_SECRET_KEY") +else: + # Secret key passed in by file location + key_file = os.getenv("INVENTREE_SECRET_KEY_FILE") + if key_file: + if os.path.isfile(key_file): + logger.info("SECRET_KEY loaded by INVENTREE_SECRET_KEY_FILE") + else: + logger.error(f"Secret key file {key_file} not found") + exit(-1) + else: + # default secret key location + key_file = os.path.join(BASE_DIR, "secret_key.txt") + logger.info(f"SECRET_KEY loaded from {key_file}") + try: + SECRET_KEY = open(key_file, "r").read().strip() + except Exception: + logger.exception(f"Couldn't load keyfile {key_file}") + sys.exit(-1) # List of allowed hosts (default = allow all) ALLOWED_HOSTS = CONFIG.get('allowed_hosts', ['*']) @@ -112,7 +129,7 @@ MEDIA_ROOT = os.path.abspath(CONFIG.get('media_root', os.path.join(BASE_DIR, 'me if DEBUG: logger.info("InvenTree running in DEBUG mode") - + logger.info(f"MEDIA_ROOT: '{MEDIA_ROOT}'") logger.info(f"STATIC_ROOT: '{STATIC_ROOT}'") @@ -315,7 +332,7 @@ else: - However there may be reason to configure the DB via environmental variables - The following code lets the user "mix and match" database configuration """ - + logger.info("Configuring database backend:") # Extract database configuration from the config.yaml file @@ -341,7 +358,7 @@ else: # Check that required database configuration options are specified reqiured_keys = ['ENGINE', 'NAME'] - + for key in reqiured_keys: if key not in db_config: error_msg = f'Missing required database configuration value {key} in config.yaml' From fef5b7548e07acbb7b00ded0d457c8b8ac5f0d18 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Thu, 14 Jan 2021 22:06:53 +1100 Subject: [PATCH 23/25] Increase unit testing for order API --- InvenTree/company/fixtures/company.yaml | 11 +- InvenTree/order/fixtures/order.yaml | 34 ++++++ InvenTree/order/fixtures/sales_order.yaml | 39 ++++++ InvenTree/order/models.py | 2 +- InvenTree/order/test_api.py | 137 ++++++++++++++++++++-- 5 files changed, 212 insertions(+), 11 deletions(-) create mode 100644 InvenTree/order/fixtures/sales_order.yaml diff --git a/InvenTree/company/fixtures/company.yaml b/InvenTree/company/fixtures/company.yaml index 69edee693a..8301eb0f5e 100644 --- a/InvenTree/company/fixtures/company.yaml +++ b/InvenTree/company/fixtures/company.yaml @@ -5,20 +5,29 @@ fields: name: ACME description: A Cool Military Enterprise + - model: company.company pk: 2 fields: name: Appel Computers description: Think more differenter + - model: company.company pk: 3 fields: name: Zerg Corp description: We eat the competition + - model: company.company pk: 4 fields: name: A customer description: A company that we sell things to! is_customer: True - \ No newline at end of file + +- model: company.company + pk: 5 + fields: + name: Another customer! + description: Yet another company + is_customer: True diff --git a/InvenTree/order/fixtures/order.yaml b/InvenTree/order/fixtures/order.yaml index 4ceaf3d482..8943b36061 100644 --- a/InvenTree/order/fixtures/order.yaml +++ b/InvenTree/order/fixtures/order.yaml @@ -7,6 +7,7 @@ reference: '0001' description: "Ordering some screws" supplier: 1 + status: 10 # Pending # Ordering some screws from Zerg Corp - model: order.purchaseorder @@ -15,6 +16,39 @@ reference: '0002' description: "Ordering some more screws" supplier: 3 + status: 10 # Pending + +- model: order.purchaseorder + pk: 3 + fields: + reference: '0003' + description: 'Another PO' + supplier: 3 + status: 20 # Placed + +- model: order.purchaseorder + pk: 4 + fields: + reference: '0004' + description: 'Another PO' + supplier: 3 + status: 20 # Placed + +- model: order.purchaseorder + pk: 5 + fields: + reference: '0005' + description: 'Another PO' + supplier: 3 + status: 30 # Complete + +- model: order.purchaseorder + pk: 6 + fields: + reference: '0006' + description: 'Another PO' + supplier: 3 + status: 40 # Cancelled # Add some line items against PO 0001 diff --git a/InvenTree/order/fixtures/sales_order.yaml b/InvenTree/order/fixtures/sales_order.yaml new file mode 100644 index 0000000000..e80119fa3e --- /dev/null +++ b/InvenTree/order/fixtures/sales_order.yaml @@ -0,0 +1,39 @@ +- model: order.salesorder + pk: 1 + fields: + reference: 'ABC123' + description: "One sales order, please" + customer: 4 + status: 10 # Pending + +- model: order.salesorder + pk: 2 + fields: + reference: 'ABC124' + description: "One sales order, please" + customer: 4 + status: 10 # Pending + +- model: order.salesorder + pk: 3 + fields: + reference: 'ABC125' + description: "One sales order, please" + customer: 4 + status: 10 # Pending + +- model: order.salesorder + pk: 4 + fields: + reference: 'ABC126' + description: "One sales order, please" + customer: 5 + status: 20 # Shipped + +- model: order.salesorder + pk: 5 + fields: + reference: 'ABC127' + description: "One sales order, please" + customer: 5 + status: 60 # Returned diff --git a/InvenTree/order/models.py b/InvenTree/order/models.py index 65729ab993..955859f11a 100644 --- a/InvenTree/order/models.py +++ b/InvenTree/order/models.py @@ -191,7 +191,7 @@ class PurchaseOrder(Order): issue_date = models.DateField( blank=True, null=True, - verbose_name=_('Issue Date'), + verbose_name=_('Issue Date'), help_text=_('Date order was issued') ) diff --git a/InvenTree/order/test_api.py b/InvenTree/order/test_api.py index 46c6f19277..58599f1eb3 100644 --- a/InvenTree/order/test_api.py +++ b/InvenTree/order/test_api.py @@ -2,12 +2,16 @@ Tests for the Order API """ +from datetime import datetime, timedelta + from rest_framework.test import APITestCase from rest_framework import status from django.urls import reverse from django.contrib.auth import get_user_model +from .models import PurchaseOrder, SalesOrder + class OrderTest(APITestCase): @@ -18,6 +22,8 @@ class OrderTest(APITestCase): 'location', 'supplier_part', 'stock', + 'order', + 'sales_order', ] def setUp(self): @@ -26,21 +32,80 @@ class OrderTest(APITestCase): get_user_model().objects.create_user('testuser', 'test@testing.com', 'password') self.client.login(username='testuser', password='password') - def doGet(self, url, options=''): + def doGet(self, url, data={}): - return self.client.get(url + "?" + options, format='json') + return self.client.get(url, data=data, format='json') + + def doPost(self, url, data={}): + return self.client.post(url, data=data, format='json') + + def filter(self, filters, count): + """ + Test API filters + """ + + response = self.doGet( + self.LIST_URL, + filters + ) + + self.assertEqual(response.status_code, 200) + self.assertEqual(len(response.data), count) + + return response + + +class PurchaseOrderTest(OrderTest): + """ + Tests for the PurchaseOrder API + """ + + LIST_URL = reverse('api-po-list') def test_po_list(self): - - url = reverse('api-po-list') - # List all order items + # List *ALL* PO items + self.filter({}, 6) + + # Filter by supplier + self.filter({'supplier': 1}, 1) + self.filter({'supplier': 3}, 5) + + # Filter by "outstanding" + self.filter({'outstanding': True}, 4) + self.filter({'outstanding': False}, 2) + + # Filter by "status" + self.filter({'status': 10}, 2) + self.filter({'status': 40}, 1) + + def test_overdue(self): + """ + Test "overdue" status + """ + + self.filter({'overdue': True}, 0) + self.filter({'overdue': False}, 6) + + order = PurchaseOrder.objects.get(pk=1) + order.target_date = datetime.now().date() - timedelta(days=10) + order.save() + + self.filter({'overdue': True}, 1) + self.filter({'overdue': False}, 5) + + def test_po_detail(self): + + url = '/api/order/po/1/' + response = self.doGet(url) - self.assertEqual(response.status_code, status.HTTP_200_OK) + + self.assertEqual(response.status_code, 200) - # Filter by stuff - response = self.doGet(url, 'status=10&part=1&supplier_part=1') - self.assertEqual(response.status_code, status.HTTP_200_OK) + data = response.data + + self.assertEqual(data['pk'], 1) + self.assertEqual(data['description'], 'Ordering some screws') def test_po_attachments(self): @@ -50,6 +115,60 @@ class OrderTest(APITestCase): self.assertEqual(response.status_code, status.HTTP_200_OK) + +class SalesOrderTest(OrderTest): + """ + Tests for the SalesOrder API + """ + + LIST_URL = reverse('api-so-list') + + def test_so_list(self): + + # All orders + self.filter({}, 5) + + # Filter by customer + self.filter({'customer': 4}, 3) + self.filter({'customer': 5}, 2) + + # Filter by outstanding + self.filter({'outstanding': True}, 3) + self.filter({'outstanding': False}, 2) + + # Filter by status + self.filter({'status': 10}, 3) # PENDING + self.filter({'status': 20}, 1) # SHIPPED + self.filter({'status': 99}, 0) # Invalid + + def test_overdue(self): + """ + Test "overdue" status + """ + + self.filter({'overdue': True}, 0) + self.filter({'overdue': False}, 5) + + for pk in [1, 2]: + order = SalesOrder.objects.get(pk=pk) + order.target_date = datetime.now().date() - timedelta(days=10) + order.save() + + self.filter({'overdue': True}, 2) + self.filter({'overdue': False}, 3) + + def test_so_detail(self): + + url = '/api/order/so/1/' + + response = self.doGet(url) + + self.assertEqual(response.status_code, 200) + + data = response.data + + self.assertEqual(data['pk'], 1) + def test_so_attachments(self): url = reverse('api-so-attachment-list') From 959914c78c59a9bd19b58d69a80b452267b3f0e7 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Thu, 14 Jan 2021 22:19:32 +1100 Subject: [PATCH 24/25] Display overdue purchase orders in the calendar view --- InvenTree/order/models.py | 9 ++++----- InvenTree/order/templates/order/purchase_orders.html | 2 ++ 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/InvenTree/order/models.py b/InvenTree/order/models.py index 955859f11a..84f6aeb6f0 100644 --- a/InvenTree/order/models.py +++ b/InvenTree/order/models.py @@ -135,7 +135,7 @@ class PurchaseOrder(Order): To be "interesting": - A "received" order where the received date lies within the date range - - TODO: A "pending" order where the target date lies within the date range + - A "pending" order where the target date lies within the date range - TODO: An "overdue" order where the target date is in the past """ @@ -152,13 +152,12 @@ class PurchaseOrder(Order): # Construct a queryset for "received" orders within the range received = Q(status=PurchaseOrderStatus.COMPLETE) & Q(complete_date__gte=min_date) & Q(complete_date__lte=max_date) - # TODO - Construct a queryset for "pending" orders within the range + # Construct a queryset for "pending" orders within the range + pending = Q(status__in=PurchaseOrderStatus.OPEN) & ~Q(target_date=None) & Q(target_date__gte=min_date) & Q(target_date__lte=max_date) # TODO - Construct a queryset for "overdue" orders within the range - flt = received - - queryset = queryset.filter(flt) + queryset = queryset.filter(received | pending) return queryset diff --git a/InvenTree/order/templates/order/purchase_orders.html b/InvenTree/order/templates/order/purchase_orders.html index d05e8fbf86..52314df833 100644 --- a/InvenTree/order/templates/order/purchase_orders.html +++ b/InvenTree/order/templates/order/purchase_orders.html @@ -70,6 +70,8 @@ InvenTree | {% trans "Purchase Orders" %} if (order.complete_date) { date = order.complete_date; + } else if (order.target_date) { + date = order.target_date; } var title = `${prefix}${order.reference} - ${order.supplier_detail.name}`; From 4fd0d7d8b5ec6c52ced48ee03afe1a072ad3e812 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Thu, 14 Jan 2021 23:06:49 +1100 Subject: [PATCH 25/25] Unit test fix --- InvenTree/order/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/InvenTree/order/tests.py b/InvenTree/order/tests.py index 47dfe63d0f..7f60b1445b 100644 --- a/InvenTree/order/tests.py +++ b/InvenTree/order/tests.py @@ -41,7 +41,7 @@ class OrderTest(TestCase): next_ref = PurchaseOrder.getNextOrderNumber() - self.assertEqual(next_ref, '0003') + self.assertEqual(next_ref, '0007') def test_on_order(self): """ There should be 3 separate items on order for the M2x4 LPHS part """