From 1691f45578501efd4299c127743c33269e1f15f6 Mon Sep 17 00:00:00 2001 From: Oliver Date: Mon, 7 Nov 2022 13:56:50 +1100 Subject: [PATCH] Order editing updates (#3902) * Add extra setting to guard whether purchase order items can be edited "after the fact" * Improvements for "extra" purchase order line table * Similar changes for sales order table * Improvements for image download helper (cherry picked from commit 43b0d3ca55fdcf27ada39ccfca0370029e354da7) --- InvenTree/InvenTree/tests.py | 13 ++++--- InvenTree/common/models.py | 14 +++++++ .../order/purchase_order_detail.html | 17 +++++++- .../templates/order/sales_order_detail.html | 15 ++++++- .../templates/InvenTree/settings/po.html | 1 + .../templates/InvenTree/settings/so.html | 1 + InvenTree/templates/js/translated/order.js | 39 ++++++++++++++----- 7 files changed, 81 insertions(+), 19 deletions(-) diff --git a/InvenTree/InvenTree/tests.py b/InvenTree/InvenTree/tests.py index 5bae7281fc..6b4e7be6c9 100644 --- a/InvenTree/InvenTree/tests.py +++ b/InvenTree/InvenTree/tests.py @@ -275,8 +275,10 @@ class TestHelpers(TestCase): we will simply try multiple times """ + tries = 0 + with self.assertRaises(expected_error): - while retries > 0: + while tries < retries: try: helpers.download_image_from_url(url, timeout=timeout) @@ -285,9 +287,11 @@ class TestHelpers(TestCase): if type(exc) is expected_error: # Re-throw this error raise exc + else: + print("Unexpected error:", type(exc), exc) - time.sleep(30) - retries -= 1 + tries += 1 + time.sleep(10 * tries) # Attempt to download an image which throws a 404 dl_helper("https://httpstat.us/404", requests.exceptions.HTTPError, timeout=10) @@ -295,9 +299,6 @@ class TestHelpers(TestCase): # Attempt to download, but timeout dl_helper("https://httpstat.us/200?sleep=5000", requests.exceptions.ReadTimeout, timeout=1) - # Attempt to download, but not a valid image - dl_helper("https://httpstat.us/200", TypeError, timeout=10) - large_img = "https://github.com/inventree/InvenTree/raw/master/InvenTree/InvenTree/static/img/paper_splash_large.jpg" InvenTreeSetting.set_setting('INVENTREE_DOWNLOAD_IMAGE_MAX_SIZE', 1, change_user=None) diff --git a/InvenTree/common/models.py b/InvenTree/common/models.py index f656dbf82d..388afa9e36 100644 --- a/InvenTree/common/models.py +++ b/InvenTree/common/models.py @@ -1259,6 +1259,13 @@ class InvenTreeSetting(BaseInvenTreeSetting): 'validator': bool, }, + 'SALESORDER_EDIT_COMPLETED_ORDERS': { + 'name': _('Edit Completed Sales Orders'), + 'description': _('Allow editing of sales orders after they have been shipped or completed'), + 'default': False, + 'validator': bool, + }, + 'PURCHASEORDER_REFERENCE_PATTERN': { 'name': _('Purchase Order Reference Pattern'), 'description': _('Required pattern for generating Purchase Order reference field'), @@ -1266,6 +1273,13 @@ class InvenTreeSetting(BaseInvenTreeSetting): 'validator': order.validators.validate_purchase_order_reference_pattern, }, + 'PURCHASEORDER_EDIT_COMPLETED_ORDERS': { + 'name': _('Edit Completed Purchase Orders'), + 'description': _('Allow editing of purchase orders after they have been shipped or completed'), + 'default': False, + 'validator': bool, + }, + # login / SSO 'LOGIN_ENABLE_PWD_FORGOT': { 'name': _('Enable password forgot'), diff --git a/InvenTree/order/templates/order/purchase_order_detail.html b/InvenTree/order/templates/order/purchase_order_detail.html index 35ac42e090..914c97d6ab 100644 --- a/InvenTree/order/templates/order/purchase_order_detail.html +++ b/InvenTree/order/templates/order/purchase_order_detail.html @@ -5,11 +5,13 @@ {% load i18n %} {% load static %} + {% block sidebar %} {% include 'order/po_sidebar.html' %} {% endblock %} {% block page_content %} +{% settings_value "PURCHASEORDER_EDIT_COMPLETED_ORDERS" as allow_extra_editing %}
@@ -18,7 +20,7 @@ {% include "spacer.html" %}
{% if roles.purchase_order.change %} - {% if order.status == PurchaseOrderStatus.PENDING %} + {% if order.is_pending or allow_extra_editing %} {% trans "Upload File" %} @@ -48,11 +50,13 @@

{% trans "Extra Lines" %}

{% include "spacer.html" %}
- {% if roles.purchase_order.change %} + {% if roles.purchase_order.change %} + {% if order.is_pending or allow_extra_editing %} {% endif %} + {% endif %}
@@ -209,6 +213,9 @@ loadPurchaseOrderLineItemTable('#po-line-table', { {% else %} allow_edit: false, {% endif %} + {% if order.status == PurchaseOrderStatus.PENDING %} + pending: true, + {% endif %} {% if order.status == PurchaseOrderStatus.PLACED and roles.purchase_order.change %} allow_receive: true, {% else %} @@ -241,6 +248,12 @@ loadPurchaseOrderExtraLineTable( { order: {{ order.pk }}, status: {{ order.status }}, + {% if order.is_pending %} + pending: true, + {% endif %} + {% if roles.purchase_order.change %} + allow_edit: true, + {% endif %} } ); diff --git a/InvenTree/order/templates/order/sales_order_detail.html b/InvenTree/order/templates/order/sales_order_detail.html index c00ccca34e..a7d1a4506f 100644 --- a/InvenTree/order/templates/order/sales_order_detail.html +++ b/InvenTree/order/templates/order/sales_order_detail.html @@ -10,6 +10,7 @@ {% endblock %} {% block page_content %} +{% settings_value "SALESORDER_EDIT_COMPLETED_ORDERS" as allow_extra_editing %}
@@ -17,11 +18,13 @@

{% trans "Sales Order Items" %}

{% include "spacer.html" %}
- {% if roles.sales_order.change and order.is_pending %} + {% if roles.sales_order.change %} + {% if order.is_pending or allow_extra_editing %} {% endif %} + {% endif %}
@@ -43,10 +46,12 @@ {% include "spacer.html" %}
{% if roles.sales_order.change %} + {% if order.is_pending or allow_extra_editing %} {% endif %} + {% endif %}
@@ -265,6 +270,12 @@ order: {{ order.pk }}, reference: '{{ order.reference }}', status: {{ order.status }}, + {% if roles.sales_order.change %} + allow_edit: true, + {% endif %} + {% if order.is_pending %} + pending: true, + {% endif %} } ); @@ -289,6 +300,8 @@ { order: {{ order.pk }}, status: {{ order.status }}, + {% if roles.sales_order.change %}allow_edit: true,{% endif %} + {% if order.is_pending %}pending: true,{% endif %} } ); diff --git a/InvenTree/templates/InvenTree/settings/po.html b/InvenTree/templates/InvenTree/settings/po.html index d9fd29088e..201d2e1a68 100644 --- a/InvenTree/templates/InvenTree/settings/po.html +++ b/InvenTree/templates/InvenTree/settings/po.html @@ -11,6 +11,7 @@ {% include "InvenTree/settings/setting.html" with key="PURCHASEORDER_REFERENCE_PATTERN" %} + {% include "InvenTree/settings/setting.html" with key="PURCHASEORDER_EDIT_COMPLETED_ORDERS" icon='fa-edit' %}
{% endblock %} diff --git a/InvenTree/templates/InvenTree/settings/so.html b/InvenTree/templates/InvenTree/settings/so.html index b887f24c96..f45cccd630 100644 --- a/InvenTree/templates/InvenTree/settings/so.html +++ b/InvenTree/templates/InvenTree/settings/so.html @@ -13,6 +13,7 @@ {% include "InvenTree/settings/setting.html" with key="SALESORDER_REFERENCE_PATTERN" %} {% include "InvenTree/settings/setting.html" with key="SALESORDER_DEFAULT_SHIPMENT" icon="fa-truck-loading" %} + {% include "InvenTree/settings/setting.html" with key="SALESORDER_EDIT_COMPLETED_ORDERS" icon='fa-edit' %} diff --git a/InvenTree/templates/js/translated/order.js b/InvenTree/templates/js/translated/order.js index ebc4a918e5..1db00c9697 100644 --- a/InvenTree/templates/js/translated/order.js +++ b/InvenTree/templates/js/translated/order.js @@ -2084,6 +2084,11 @@ function loadPurchaseOrderLineItemTable(table, options={}) { options.params['order'] = options.order; options.params['part_detail'] = true; + // Override 'editing' if order is not pending + if (!options.pending && !global_settings.PURCHASEORDER_EDIT_COMPLETED_ORDERS) { + options.allow_edit = false; + } + var filters = loadTableFilters('purchaseorderlineitem'); for (var key in options.params) { @@ -2445,6 +2450,10 @@ function loadPurchaseOrderExtraLineTable(table, options={}) { options.table = table; + if (!options.pending && !global_settings.PURCHASEORDER_EDIT_COMPLETED_ORDERS) { + options.allow_edit = false; + } + options.params = options.params || {}; if (!options.order) { @@ -2561,9 +2570,11 @@ function loadPurchaseOrderExtraLineTable(table, options={}) { var pk = row.pk; - html += makeIconButton('fa-clone', 'button-duplicate', pk, '{% trans "Duplicate line" %}'); - html += makeIconButton('fa-edit icon-blue', 'button-edit', pk, '{% trans "Edit line" %}'); - html += makeIconButton('fa-trash-alt icon-red', 'button-delete', pk, '{% trans "Delete line" %}', ); + if (options.allow_edit) { + html += makeIconButton('fa-clone', 'button-duplicate', pk, '{% trans "Duplicate line" %}'); + html += makeIconButton('fa-edit icon-blue', 'button-edit', pk, '{% trans "Edit line" %}'); + html += makeIconButton('fa-trash-alt icon-red', 'button-delete', pk, '{% trans "Delete line" %}', ); + } html += ``; @@ -3740,6 +3751,10 @@ function loadSalesOrderLineItemTable(table, options={}) { options.table = table; + if (!options.pending && !global_settings.SALESORDER_EDIT_COMPLETED_ORDERS) { + options.allow_edit = false; + } + options.params = options.params || {}; if (!options.order) { @@ -3769,7 +3784,7 @@ function loadSalesOrderLineItemTable(table, options={}) { setupFilterList('salesorderlineitem', $(table), filter_target); // Is the order pending? - var pending = options.status == {{ SalesOrderStatus.PENDING }}; + var pending = options.pending; // Has the order shipped? var shipped = options.status == {{ SalesOrderStatus.SHIPPED }}; @@ -4287,6 +4302,10 @@ function loadSalesOrderExtraLineTable(table, options={}) { options.table = table; + if (!options.pending && !global_settings.SALESORDER_EDIT_COMPLETED_ORDERS) { + options.allow_edit = false; + } + options.params = options.params || {}; if (!options.order) { @@ -4401,14 +4420,14 @@ function loadSalesOrderExtraLineTable(table, options={}) { var html = `
`; - var pk = row.pk; - - html += makeIconButton('fa-clone', 'button-duplicate', pk, '{% trans "Duplicate line" %}'); - html += makeIconButton('fa-edit icon-blue', 'button-edit', pk, '{% trans "Edit line" %}'); - html += makeIconButton('fa-trash-alt icon-red', 'button-delete', pk, '{% trans "Delete line" %}', ); + if (options.allow_edit) { + var pk = row.pk; + html += makeIconButton('fa-clone', 'button-duplicate', pk, '{% trans "Duplicate line" %}'); + html += makeIconButton('fa-edit icon-blue', 'button-edit', pk, '{% trans "Edit line" %}'); + html += makeIconButton('fa-trash-alt icon-red', 'button-delete', pk, '{% trans "Delete line" %}', ); + } html += `
`; - return html; } });