diff --git a/InvenTree/InvenTree/settings.py b/InvenTree/InvenTree/settings.py index 2d9090b05e..797924fd36 100644 --- a/InvenTree/InvenTree/settings.py +++ b/InvenTree/InvenTree/settings.py @@ -72,6 +72,27 @@ if DEBUG: format='%(asctime)s %(levelname)s %(message)s', ) +# Does the user wish to use the sentry.io integration? +sentry_opts = CONFIG.get('sentry', {}) + +if sentry_opts.get('enabled', False): + dsn = sentry_opts.get('dsn', None) + + if dsn is not None: + # Try to import required modules (exit if not installed) + try: + import sentry_sdk + from sentry_sdk.integrations.django import DjangoIntegration + + sentry_sdk.init(dsn=dsn, integrations=[DjangoIntegration()], send_default_pii=True) + + except ModuleNotFoundError: + print("sentry_sdk module not found. Install using 'pip install sentry-sdk'") + sys.exit(-1) + + else: + print("Warning: Sentry.io DSN not specified") + # Application definition INSTALLED_APPS = [ diff --git a/InvenTree/company/templates/company/supplier_part_base.html b/InvenTree/company/templates/company/supplier_part_base.html index 5a3d49a10e..383b942346 100644 --- a/InvenTree/company/templates/company/supplier_part_base.html +++ b/InvenTree/company/templates/company/supplier_part_base.html @@ -20,6 +20,9 @@ src="{% static 'img/blank_image.png' %}"

{{ part.supplier.name }} - {{ part.SKU }}

+ @@ -91,6 +94,18 @@ src="{% static 'img/blank_image.png' %}" {% block js_ready %} {{ block.super }} +$('#order-part').click(function() { + launchModalForm( + "{% url 'order-parts' %}", + { + data: { + part: {{ part.part.id }}, + }, + reload: true, + }, + ); +}); + $('#edit-part').click(function () { launchModalForm( "{% url 'supplier-part-edit' part.id %}", diff --git a/InvenTree/config_template.yaml b/InvenTree/config_template.yaml index 0865827d56..64c5db0a06 100644 --- a/InvenTree/config_template.yaml +++ b/InvenTree/config_template.yaml @@ -65,4 +65,11 @@ log_queries: False # Backup options # Set the backup_dir parameter to store backup files in a specific location # If unspecified, the local user's temp directory will be used -#backup_dir: '/home/inventree/backup/' \ No newline at end of file +#backup_dir: '/home/inventree/backup/' + +# Sentry.io integration +# If you have a sentry.io account, it can be used to log server errors +# Ensure sentry_sdk is installed by running 'pip install sentry-sdk' +sentry: + enabled: False + # dsn: add-your-sentry-dsn-here diff --git a/InvenTree/order/views.py b/InvenTree/order/views.py index e68dca16ae..2459f83abf 100644 --- a/InvenTree/order/views.py +++ b/InvenTree/order/views.py @@ -766,6 +766,7 @@ class OrderParts(AjaxView): for supplier in self.suppliers: supplier.order_items = [] + suppliers[supplier.name] = supplier for part in self.parts: @@ -778,7 +779,15 @@ class OrderParts(AjaxView): if supplier.name not in suppliers: supplier.order_items = [] - supplier.selected_purchase_order = None + + # Attempt to auto-select a purchase order + orders = PurchaseOrder.objects.filter(supplier=supplier, status__in=PurchaseOrderStatus.OPEN) + + if orders.count() == 1: + supplier.selected_purchase_order = orders.first().id + else: + supplier.selected_purchase_order = None + suppliers[supplier.name] = supplier suppliers[supplier.name].order_items.append(part) diff --git a/InvenTree/part/models.py b/InvenTree/part/models.py index 6f6b0d7ddf..90383ab26f 100644 --- a/InvenTree/part/models.py +++ b/InvenTree/part/models.py @@ -526,7 +526,7 @@ class Part(models.Model): This number (unlike 'available_stock') can be negative. """ - return self.total_stock - self.allocation_count + self.on_order + return self.total_stock - self.allocation_count() + self.on_order def isStarredBy(self, user): """ Return True if this part has been starred by a particular user """ diff --git a/InvenTree/part/templates/part/part_base.html b/InvenTree/part/templates/part/part_base.html index 4da8ec7ffe..0bb3687fc8 100644 --- a/InvenTree/part/templates/part/part_base.html +++ b/InvenTree/part/templates/part/part_base.html @@ -108,11 +108,18 @@ {% include "part/stock_count.html" %} {% if not part.is_template %} - {% if part.allocation_count > 0 %} + {% if part.build_order_allocation_count > 0 %} - {% trans "Allocated" %} - {% decimal part.allocation_count %} + {% trans "Allocated to Build Orders" %} + {% decimal part.build_order_allocation_count %} + + {% endif %} + {% if part.sales_order_allocation_count > 0 %} + + + {% trans "Allocated to Sales Orders" %} + {% decimal part.sales_order_allocation_count %} {% endif %} {% if part.on_order > 0 %}