From e382f2a57ec1a459086c51ce4faa9b690e7330b9 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 13 May 2021 15:46:27 +0200 Subject: [PATCH 01/12] fixing bug from refactor --- InvenTree/InvenTree/static/script/inventree/inventree.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/InvenTree/InvenTree/static/script/inventree/inventree.js b/InvenTree/InvenTree/static/script/inventree/inventree.js index 4b43b342af..1a6fdec47a 100644 --- a/InvenTree/InvenTree/static/script/inventree/inventree.js +++ b/InvenTree/InvenTree/static/script/inventree/inventree.js @@ -12,7 +12,7 @@ function attachClipboard(selector, containerselector, textElement) { return document.getElementById(textElement).textContent; } } else { - text = function() { + text = function(trigger) { var content = trigger.parentElement.parentElement.textContent;return content.trim(); } } @@ -22,7 +22,6 @@ function attachClipboard(selector, containerselector, textElement) { text: text, container: containerselector }); - console.log(cis); } @@ -81,7 +80,6 @@ function inventreeDocReady() { attachClipboard('.clip-btn'); attachClipboard('.clip-btn', 'modal-about'); // modals attachClipboard('.clip-btn-version', 'modal-about', 'about-copy-text'); // version-text - } function isFileTransfer(transfer) { From 22249206d24206c5073e7d7ba33f9c0ba0d25fd5 Mon Sep 17 00:00:00 2001 From: eeintech Date: Thu, 13 May 2021 16:06:57 -0400 Subject: [PATCH 02/12] Fixed duplicate check --- InvenTree/common/views.py | 5 +++-- .../order/templates/order/order_wizard/match_fields.html | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/InvenTree/common/views.py b/InvenTree/common/views.py index fa605c2b80..99862f5c08 100644 --- a/InvenTree/common/views.py +++ b/InvenTree/common/views.py @@ -209,6 +209,7 @@ class FileManagementFormView(MultiStepFormView): context.update({'columns': self.columns}) # Load extra context data + print(self.extra_context_data) for key, items in self.extra_context_data.items(): context.update({key: items}) @@ -449,8 +450,8 @@ class FileManagementFormView(MultiStepFormView): if guess: n = list(self.column_selections.values()).count(self.column_selections[col]) - if n > 1: - duplicates.append(col) + if n > 1 and self.column_selections[col] not in duplicates: + duplicates.append(self.column_selections[col]) # Store extra context data self.extra_context_data = { diff --git a/InvenTree/order/templates/order/order_wizard/match_fields.html b/InvenTree/order/templates/order/order_wizard/match_fields.html index 4ff7b6a963..cd81142341 100644 --- a/InvenTree/order/templates/order/order_wizard/match_fields.html +++ b/InvenTree/order/templates/order/order_wizard/match_fields.html @@ -55,7 +55,7 @@ {{ col }} {% for duplicate in duplicates %} - {% if duplicate == col.name %} + {% if duplicate == col.value %} From a64ab5956b2a1daec62fc8789ce600250882d78f Mon Sep 17 00:00:00 2001 From: eeintech Date: Thu, 13 May 2021 16:07:57 -0400 Subject: [PATCH 03/12] Removed leftover print --- InvenTree/common/views.py | 1 - 1 file changed, 1 deletion(-) diff --git a/InvenTree/common/views.py b/InvenTree/common/views.py index 99862f5c08..857b6b2c51 100644 --- a/InvenTree/common/views.py +++ b/InvenTree/common/views.py @@ -209,7 +209,6 @@ class FileManagementFormView(MultiStepFormView): context.update({'columns': self.columns}) # Load extra context data - print(self.extra_context_data) for key, items in self.extra_context_data.items(): context.update({key: items}) From bca2f4a07b95c448a21e49ebfe66b600588d8d5d Mon Sep 17 00:00:00 2001 From: Nigel Date: Thu, 15 Apr 2021 15:21:13 -0600 Subject: [PATCH 04/12] feat(sales_order): Stock Items show the PO number Stock items show the PO number that they were purchased on when being viewed in the sales order allocation modal and when viewing the sales order details. --- InvenTree/order/models.py | 3 ++ InvenTree/order/serializers.py | 2 ++ .../templates/order/sales_order_detail.html | 29 +++++++++++++++++-- InvenTree/order/views.py | 2 +- InvenTree/stock/models.py | 6 ++++ 5 files changed, 39 insertions(+), 3 deletions(-) diff --git a/InvenTree/order/models.py b/InvenTree/order/models.py index 5305038b4f..fb169e0536 100644 --- a/InvenTree/order/models.py +++ b/InvenTree/order/models.py @@ -826,6 +826,9 @@ class SalesOrderAllocation(models.Model): else: return "" + def get_po(self): + return self.item.purchase_order + def complete_allocation(self, user): """ Complete this allocation (called when the parent SalesOrder is marked as "shipped"): diff --git a/InvenTree/order/serializers.py b/InvenTree/order/serializers.py index 062e8986b2..6091140313 100644 --- a/InvenTree/order/serializers.py +++ b/InvenTree/order/serializers.py @@ -235,6 +235,7 @@ class SalesOrderAllocationSerializer(InvenTreeModelSerializer): location_path = serializers.CharField(source='get_location_path') location_id = serializers.IntegerField(source='get_location') serial = serializers.CharField(source='get_serial') + po = serializers.CharField(source='get_po') quantity = serializers.FloatField() class Meta: @@ -247,6 +248,7 @@ class SalesOrderAllocationSerializer(InvenTreeModelSerializer): 'quantity', 'location_id', 'location_path', + 'po', 'item', ] diff --git a/InvenTree/order/templates/order/sales_order_detail.html b/InvenTree/order/templates/order/sales_order_detail.html index 72b7d63911..a90e61bff9 100644 --- a/InvenTree/order/templates/order/sales_order_detail.html +++ b/InvenTree/order/templates/order/sales_order_detail.html @@ -87,6 +87,9 @@ function showAllocationSubTable(index, row, element) { return renderLink(row.location_path, `/stock/location/${row.location_id}/`); }, }, + { + field: 'po' + }, { field: 'buttons', title: '{% trans "Actions" %}', @@ -159,9 +162,12 @@ function showFulfilledSubTable(index, row, element) { text = `{% trans "Quantity" %}: ${row.quantity}`; } - return renderLink(text, `/stock/item/${row.pk}/`); + return renderLink(text, `/stock/item/${row.pk}/`); }, - } + }, + { + field: 'po' + }, ], }); } @@ -271,6 +277,25 @@ $("#so-lines-table").inventreeTable({ field: 'notes', title: '{% trans "Notes" %}', }, + { + field: 'po', + title: '{% trans "PO" %}', + formatter: function(value, row, index, field) { + var po_name = ""; + if (row.allocated) { + row.allocations.forEach(function(allocation) { + if (allocation.po != po_name) { + if (po_name) { + po_name = "-"; + } else { + po_name = allocation.po + } + } + }) + } + return `
` + po_name + `
`; + } + }, {% if order.status == SalesOrderStatus.PENDING %} { field: 'buttons', diff --git a/InvenTree/order/views.py b/InvenTree/order/views.py index cf79746f0d..c8ec42d3e7 100644 --- a/InvenTree/order/views.py +++ b/InvenTree/order/views.py @@ -90,7 +90,7 @@ class SalesOrderDetail(InvenTreeRoleMixin, DetailView): """ Detail view for a SalesOrder object """ context_object_name = 'order' - queryset = SalesOrder.objects.all().prefetch_related('lines') + queryset = SalesOrder.objects.all().prefetch_related('lines__allocations__item__purchase_order') template_name = 'order/sales_order_detail.html' diff --git a/InvenTree/stock/models.py b/InvenTree/stock/models.py index 28123ebc41..88f8dd081c 100644 --- a/InvenTree/stock/models.py +++ b/InvenTree/stock/models.py @@ -1370,6 +1370,12 @@ class StockItem(MPTTModel): if self.location: s += ' @ {loc}'.format(loc=self.location.name) + if self.purchase_order: + s += " ({pre}{po})".format( + pre=helpers.getSetting("PURCHASEORDER_REFERENCE_PREFIX"), + po=self.purchase_order, + ) + return s @transaction.atomic From f76bc5a7b8661a371669c21959f65e44b252cb45 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Fri, 14 May 2021 12:38:38 +1000 Subject: [PATCH 05/12] Add debug mode and database backend as info to the "stats" dialog --- .../part/templatetags/inventree_extras.py | 24 +++++++++++++++++++ InvenTree/templates/stats.html | 13 ++++++++++ 2 files changed, 37 insertions(+) diff --git a/InvenTree/part/templatetags/inventree_extras.py b/InvenTree/part/templatetags/inventree_extras.py index 2c588a81e5..799ad8788b 100644 --- a/InvenTree/part/templatetags/inventree_extras.py +++ b/InvenTree/part/templatetags/inventree_extras.py @@ -1,7 +1,14 @@ +# -*- coding: utf-8 -*- + """ This module provides template tags for extra functionality over and above the built-in Django tags. """ + import os +import django + +from django.utils.translation import ugettext_lazy as _ +from django.conf import settings as djangosettings from django import template from django.urls import reverse @@ -67,6 +74,23 @@ def part_allocation_count(build, part, *args, **kwargs): return InvenTree.helpers.decimal2string(build.getAllocatedQuantity(part)) +@register.simple_tag() +def inventree_in_debug_mode(*args, **kwargs): + """ Return True if the server is running in DEBUG mode """ + + return djangosettings.DEBUG + +@register.simple_tag() +def inventree_db_engine(*args, **kwargs): + """ Return the InvenTree database backend e.g. 'postgresql' """ + + db = djangosettings.DATABASES['default'] + + engine = db.get('ENGINE', _('Unknown database')) + + engine = engine.replace('django.db.backends.', '') + + return engine @register.simple_tag() def inventree_instance_name(*args, **kwargs): diff --git a/InvenTree/templates/stats.html b/InvenTree/templates/stats.html index eff9c4504f..1598d45d26 100644 --- a/InvenTree/templates/stats.html +++ b/InvenTree/templates/stats.html @@ -13,6 +13,19 @@ {% trans "Instance Name" %} {% inventree_instance_name %} + + + {% trans "Database" %} + {% inventree_db_engine %} + + {% inventree_in_debug_mode as debug_mode %} + {% if debug_mode %} + + + {% trans "Debug Mode" %} + {% trans "Server is running in debug mode" %} + + {% endif %} {% if user.is_staff %} From 7deea1ec00303d9943bc4185d6ad0a0e1e04dd25 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Fri, 14 May 2021 12:40:42 +1000 Subject: [PATCH 06/12] Style fixes --- InvenTree/part/templatetags/inventree_extras.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/InvenTree/part/templatetags/inventree_extras.py b/InvenTree/part/templatetags/inventree_extras.py index 799ad8788b..e8743028a0 100644 --- a/InvenTree/part/templatetags/inventree_extras.py +++ b/InvenTree/part/templatetags/inventree_extras.py @@ -5,7 +5,6 @@ over and above the built-in Django tags. """ import os -import django from django.utils.translation import ugettext_lazy as _ from django.conf import settings as djangosettings @@ -74,12 +73,14 @@ def part_allocation_count(build, part, *args, **kwargs): return InvenTree.helpers.decimal2string(build.getAllocatedQuantity(part)) + @register.simple_tag() def inventree_in_debug_mode(*args, **kwargs): """ Return True if the server is running in DEBUG mode """ return djangosettings.DEBUG + @register.simple_tag() def inventree_db_engine(*args, **kwargs): """ Return the InvenTree database backend e.g. 'postgresql' """ @@ -92,6 +93,7 @@ def inventree_db_engine(*args, **kwargs): return engine + @register.simple_tag() def inventree_instance_name(*args, **kwargs): """ Return the InstanceName associated with the current database """ From 30a2194fe1b121c5f64345a8c245a31614d424ba Mon Sep 17 00:00:00 2001 From: Nigel Date: Fri, 14 May 2021 13:24:13 -0600 Subject: [PATCH 07/12] feat(admin): Show the line items on the PO on the Admin Site --- InvenTree/order/admin.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/InvenTree/order/admin.py b/InvenTree/order/admin.py index 4519f8a2a9..1e7b20e5a1 100644 --- a/InvenTree/order/admin.py +++ b/InvenTree/order/admin.py @@ -13,6 +13,10 @@ from .models import SalesOrder, SalesOrderLineItem from .models import SalesOrderAllocation +class PurchaseOrderLineItemInlineAdmin(admin.StackedInline): + model = PurchaseOrderLineItem + + class PurchaseOrderAdmin(ImportExportModelAdmin): list_display = ( @@ -29,6 +33,10 @@ class PurchaseOrderAdmin(ImportExportModelAdmin): 'description', ] + inlines = [ + PurchaseOrderLineItemInlineAdmin + ] + class SalesOrderAdmin(ImportExportModelAdmin): From 16b7d6c34df29499653706b4ccea1f730fba0432 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 16 May 2021 18:18:58 +0200 Subject: [PATCH 08/12] database and debug info in version copy --- InvenTree/templates/version.html | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/InvenTree/templates/version.html b/InvenTree/templates/version.html index c8ec6862b6..3349bb5fb2 100644 --- a/InvenTree/templates/version.html +++ b/InvenTree/templates/version.html @@ -2,4 +2,6 @@ InvenTree-Version: {% inventree_version %} Django Version: {% django_version %} {% inventree_commit_hash as hash %}{% if hash %}Commit Hash: {{ hash }}{% endif %} -{% inventree_commit_date as commit_date %}{% if commit_date %}Commit Date: {{ commit_date }}{% endif %} \ No newline at end of file +{% inventree_commit_date as commit_date %}{% if commit_date %}Commit Date: {{ commit_date }}{% endif %} +Database: {% inventree_db_engine %} +Debug-Mode: {% inventree_in_debug_mode %} From b2a912c77020786048f5b0ed11acb0eca8f4cc03 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 16 May 2021 18:19:35 +0200 Subject: [PATCH 09/12] docker-mode switch in settings and tags --- InvenTree/InvenTree/settings.py | 5 +++++ InvenTree/part/templatetags/inventree_extras.py | 7 +++++++ docker/Dockerfile | 1 + 3 files changed, 13 insertions(+) diff --git a/InvenTree/InvenTree/settings.py b/InvenTree/InvenTree/settings.py index 7ff90fc7c3..67a500a07a 100644 --- a/InvenTree/InvenTree/settings.py +++ b/InvenTree/InvenTree/settings.py @@ -87,6 +87,11 @@ DEBUG = _is_true(get_setting( CONFIG.get('debug', True) )) +DOCKER = _is_true(get_setting( + 'INVENTREE_DOCKER', + False +)) + # Configure logging settings log_level = get_setting( 'INVENTREE_LOG_LEVEL', diff --git a/InvenTree/part/templatetags/inventree_extras.py b/InvenTree/part/templatetags/inventree_extras.py index e8743028a0..734b365447 100644 --- a/InvenTree/part/templatetags/inventree_extras.py +++ b/InvenTree/part/templatetags/inventree_extras.py @@ -81,6 +81,13 @@ def inventree_in_debug_mode(*args, **kwargs): return djangosettings.DEBUG +@register.simple_tag() +def inventree_docker_mode(*args, **kwargs): + """ Return True if the server is running as a Docker image """ + + return djangosettings.DOCKER + + @register.simple_tag() def inventree_db_engine(*args, **kwargs): """ Return the InvenTree database backend e.g. 'postgresql' """ diff --git a/docker/Dockerfile b/docker/Dockerfile index 3e0a7e1230..ea70d9f994 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -14,6 +14,7 @@ ENV INVENTREE_REPO="${repository}" ENV INVENTREE_BRANCH="${branch}" ENV INVENTREE_LOG_LEVEL="INFO" +ENV INVENTREE_DOCKER="true" # InvenTree paths ENV INVENTREE_SRC_DIR="${INVENTREE_HOME}/src" From ff9970f1cc42a823be665a6e9d1baa7437fcc22a Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 16 May 2021 18:20:06 +0200 Subject: [PATCH 10/12] docker in version copy --- InvenTree/templates/version.html | 1 + 1 file changed, 1 insertion(+) diff --git a/InvenTree/templates/version.html b/InvenTree/templates/version.html index 3349bb5fb2..b702fd85f5 100644 --- a/InvenTree/templates/version.html +++ b/InvenTree/templates/version.html @@ -5,3 +5,4 @@ Django Version: {% django_version %} {% inventree_commit_date as commit_date %}{% if commit_date %}Commit Date: {{ commit_date }}{% endif %} Database: {% inventree_db_engine %} Debug-Mode: {% inventree_in_debug_mode %} +Deployed using Docker: {% inventree_docker_mode %} \ No newline at end of file From cfa6994302ec85494cdbf8b90313ccd9ecbb5b0c Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 16 May 2021 18:20:32 +0200 Subject: [PATCH 11/12] docker-mode in stats --- InvenTree/templates/stats.html | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/InvenTree/templates/stats.html b/InvenTree/templates/stats.html index 1598d45d26..403030644a 100644 --- a/InvenTree/templates/stats.html +++ b/InvenTree/templates/stats.html @@ -26,6 +26,14 @@ {% trans "Server is running in debug mode" %} {% endif %} + {% inventree_docker_mode as docker_mode %} + {% if docker_mode %} + + + {% trans "Docker Mode" %} + {% trans "Server is deployed using docker" %} + + {% endif %} {% if user.is_staff %} From 64c1503fe4a75761c1cc41fce94d409c411f451a Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Mon, 17 May 2021 20:15:53 +1000 Subject: [PATCH 12/12] Disable "purchase price" field for non-purchaseable parts --- InvenTree/templates/js/modals.js | 9 +++++++++ InvenTree/templates/js/stock.js | 14 ++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/InvenTree/templates/js/modals.js b/InvenTree/templates/js/modals.js index b621caab80..f447fdce72 100644 --- a/InvenTree/templates/js/modals.js +++ b/InvenTree/templates/js/modals.js @@ -89,6 +89,15 @@ function setFieldOptions(fieldName, optionList, options={}) { } +function clearFieldOptions(fieldName) { + /** + * Clear (emtpy) the options list for a particular field + */ + + setFieldOptions(fieldName, []); +} + + function reloadFieldOptions(fieldName, options) { /* Reload the options for a given field, * using an AJAX request. diff --git a/InvenTree/templates/js/stock.js b/InvenTree/templates/js/stock.js index a0601aeb13..8f06d403ee 100644 --- a/InvenTree/templates/js/stock.js +++ b/InvenTree/templates/js/stock.js @@ -1218,6 +1218,17 @@ function createNewStockItem(options) { field: 'part', action: function(value) { + if (!value) { + // No part chosen + + clearFieldOptions('supplier_part'); + enableField('serial_numbers', false); + enableField('purchase_price_0', false); + enableField('purchase_price_1', false); + + return; + } + // Reload options for supplier part reloadFieldOptions( 'supplier_part', @@ -1243,6 +1254,9 @@ function createNewStockItem(options) { enableField('serial_numbers', response.trackable); clearField('serial_numbers'); + enableField('purchase_price_0', response.purchaseable); + enableField('purchase_price_1', response.purchaseable); + // Populate the expiry date if (response.default_expiry <= 0) { // No expiry date