diff --git a/InvenTree/InvenTree/api_version.py b/InvenTree/InvenTree/api_version.py
index c1defa567b..203aa09713 100644
--- a/InvenTree/InvenTree/api_version.py
+++ b/InvenTree/InvenTree/api_version.py
@@ -2,11 +2,14 @@
# InvenTree API version
-INVENTREE_API_VERSION = 96
+INVENTREE_API_VERSION = 97
"""
Increment this API version number whenever there is a significant change to the API that any clients need to know about
+v97 -> 2023-02-20 : https://github.com/inventree/InvenTree/pull/4377
+ - Adds "external" attribute to StockLocation model
+
v96 -> 2023-02-16 : https://github.com/inventree/InvenTree/pull/4345
- Adds stocktake report generation functionality
diff --git a/InvenTree/common/models.py b/InvenTree/common/models.py
index 3f251fd0b8..9eac812ae0 100644
--- a/InvenTree/common/models.py
+++ b/InvenTree/common/models.py
@@ -46,6 +46,7 @@ import InvenTree.ready
import InvenTree.tasks
import InvenTree.validators
import order.validators
+from plugin import registry
logger = logging.getLogger('inventree')
@@ -1628,6 +1629,15 @@ class InvenTreeSetting(BaseInvenTreeSetting):
return False
+def label_printer_options():
+ """Build a list of available label printer options."""
+ printers = [('', _('No Printer (Export to PDF)'))]
+ label_printer_plugins = registry.with_mixin('labels')
+ if label_printer_plugins:
+ printers.extend([(p.slug, p.name + ' - ' + p.human_name) for p in label_printer_plugins])
+ return printers
+
+
class InvenTreeUserSetting(BaseInvenTreeSetting):
"""An InvenTreeSetting object with a usercontext."""
@@ -1781,6 +1791,13 @@ class InvenTreeUserSetting(BaseInvenTreeSetting):
'validator': bool,
},
+ "LABEL_DEFAULT_PRINTER": {
+ 'name': _('Default label printer'),
+ 'description': _('Configure which label printer should be selected by default'),
+ 'default': '',
+ 'choices': label_printer_options
+ },
+
"REPORT_INLINE": {
'name': _('Inline report display'),
'description': _('Display PDF reports in the browser, instead of downloading as a file'),
diff --git a/InvenTree/company/templates/company/supplier_part.html b/InvenTree/company/templates/company/supplier_part.html
index 82d0311f96..58ac0fa0eb 100644
--- a/InvenTree/company/templates/company/supplier_part.html
+++ b/InvenTree/company/templates/company/supplier_part.html
@@ -299,27 +299,12 @@ loadSupplierPriceBreakTable({
});
$('#new-price-break').click(function() {
-
- constructForm(
- '{% url "api-part-supplier-price-list" %}',
- {
- method: 'POST',
- fields: {
- quantity: {},
- part: {
- value: {{ part.pk }},
- hidden: true,
- },
- price: {},
- price_currency: {
- },
- },
- title: '{% trans "Add Price Break" %}',
- onSuccess: function() {
- $("#price-break-table").bootstrapTable("refresh");
- }
+ createSupplierPartPriceBreak({{ part.pk }}, {
+ onSuccess: function() {
+ $("#price-break-table").bootstrapTable("refresh");
}
- );
+ });
+
});
loadPurchaseOrderTable($("#purchase-order-table"), {
diff --git a/InvenTree/order/templates/order/sales_order_base.html b/InvenTree/order/templates/order/sales_order_base.html
index b0ab15be67..2521f92bb9 100644
--- a/InvenTree/order/templates/order/sales_order_base.html
+++ b/InvenTree/order/templates/order/sales_order_base.html
@@ -206,28 +206,7 @@ src="{% static 'img/blank_image.png' %}"
$("#edit-order").click(function() {
- constructForm('{% url "api-so-detail" order.pk %}', {
- fields: {
- reference: {
- icon: 'fa-hashtag',
- },
- {% if order.lines.count == 0 and order.status == SalesOrderStatus.PENDING %}
- customer: {
- },
- {% endif %}
- customer_reference: {},
- description: {},
- target_date: {
- icon: 'fa-calendar-alt',
- },
- link: {
- icon: 'fa-link',
- },
- responsible: {
- icon: 'fa-user',
- },
- },
- title: '{% trans "Edit Sales Order" %}',
+ editSalesOrder({{ order.pk }}, {
reload: true,
});
});
diff --git a/InvenTree/part/templates/part/detail.html b/InvenTree/part/templates/part/detail.html
index f064f6a8cb..372eecd076 100644
--- a/InvenTree/part/templates/part/detail.html
+++ b/InvenTree/part/templates/part/detail.html
@@ -793,17 +793,9 @@
constructForm('{% url "api-part-test-template-list" %}', {
method: 'POST',
- fields: {
- test_name: {},
- description: {},
- required: {},
- requires_value: {},
- requires_attachment: {},
- part: {
- value: {{ part.pk }},
- hidden: true,
- }
- },
+ fields: partTestTemplateFields({
+ part: {{ part.pk }}
+ }),
title: '{% trans "Add Test Result Template" %}',
onSuccess: function() {
$("#test-template-table").bootstrapTable("refresh");
diff --git a/InvenTree/stock/api.py b/InvenTree/stock/api.py
index 29177eab0b..88df0a541e 100644
--- a/InvenTree/stock/api.py
+++ b/InvenTree/stock/api.py
@@ -310,7 +310,8 @@ class StockLocationList(APIDownloadMixin, ListCreateAPI):
filterset_fields = [
'name',
- 'structural'
+ 'structural',
+ 'external',
]
search_fields = [
diff --git a/InvenTree/stock/migrations/0095_stocklocation_external.py b/InvenTree/stock/migrations/0095_stocklocation_external.py
new file mode 100644
index 0000000000..3163f4aa17
--- /dev/null
+++ b/InvenTree/stock/migrations/0095_stocklocation_external.py
@@ -0,0 +1,18 @@
+# Generated by Django 3.2.18 on 2023-02-20 12:22
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('stock', '0094_auto_20230220_0025'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='stocklocation',
+ name='external',
+ field=models.BooleanField(default=False, help_text='This is an external stock location', verbose_name='External'),
+ ),
+ ]
diff --git a/InvenTree/stock/models.py b/InvenTree/stock/models.py
index 582151b17f..77928b3fee 100644
--- a/InvenTree/stock/models.py
+++ b/InvenTree/stock/models.py
@@ -122,6 +122,12 @@ class StockLocation(InvenTreeBarcodeMixin, MetadataMixin, InvenTreeTree):
'but may be located to child locations.'),
)
+ external = models.BooleanField(
+ default=False,
+ verbose_name=_('External'),
+ help_text=_('This is an external stock location')
+ )
+
def get_location_owner(self):
"""Get the closest "owner" for this location.
diff --git a/InvenTree/stock/serializers.py b/InvenTree/stock/serializers.py
index 99b0866792..7336a1d15c 100644
--- a/InvenTree/stock/serializers.py
+++ b/InvenTree/stock/serializers.py
@@ -584,6 +584,7 @@ class LocationSerializer(InvenTree.serializers.InvenTreeModelSerializer):
'owner',
'icon',
'structural',
+ 'external',
]
read_only_fields = [
diff --git a/InvenTree/stock/templates/stock/item.html b/InvenTree/stock/templates/stock/item.html
index 22e43be7b6..15e905f96e 100644
--- a/InvenTree/stock/templates/stock/item.html
+++ b/InvenTree/stock/templates/stock/item.html
@@ -313,17 +313,9 @@
constructForm('{% url "api-stock-test-result-list" %}', {
method: 'POST',
- fields: {
- test: {},
- result: {},
- value: {},
- attachment: {},
- notes: {},
- stock_item: {
- value: {{ item.pk }},
- hidden: true,
- }
- },
+ fields: stockItemTestResultFields({
+ stock_item: {{ item.pk }},
+ }),
title: '{% trans "Add Test Result" %}',
onSuccess: reloadTable,
});
diff --git a/InvenTree/stock/templates/stock/item_base.html b/InvenTree/stock/templates/stock/item_base.html
index ffe49237f1..2ec331e233 100644
--- a/InvenTree/stock/templates/stock/item_base.html
+++ b/InvenTree/stock/templates/stock/item_base.html
@@ -640,7 +640,9 @@ $("#stock-return-from-customer").click(function() {
value: {{ item.part.default_location.pk }},
{% endif %}
},
- notes: {},
+ notes: {
+ icon: 'fa-sticky-note',
+ },
},
method: 'POST',
title: '{% trans "Return to Stock" %}',
diff --git a/InvenTree/templates/InvenTree/settings/user_labels.html b/InvenTree/templates/InvenTree/settings/user_labels.html
index 93c7c0b2bc..85492a2b98 100644
--- a/InvenTree/templates/InvenTree/settings/user_labels.html
+++ b/InvenTree/templates/InvenTree/settings/user_labels.html
@@ -15,6 +15,7 @@
{% include "InvenTree/settings/setting.html" with key="LABEL_INLINE" icon='fa-tag' user_setting=True %}
+ {% include "InvenTree/settings/setting.html" with key="LABEL_DEFAULT_PRINTER" icon='fa-tag' user_setting=True %}