From b6135fda744df0efe375cc4859349adc3710d011 Mon Sep 17 00:00:00 2001 From: eeintech Date: Tue, 12 Jan 2021 13:16:04 -0500 Subject: [PATCH] Updated templates and a lot of manual testing --- .../part/templatetags/inventree_extras.py | 19 +++ InvenTree/stock/templates/stock/item.html | 5 +- .../stock/templates/stock/item_base.html | 20 ++-- InvenTree/stock/templates/stock/location.html | 15 ++- InvenTree/stock/views.py | 110 ++++++++++++++++-- InvenTree/templates/stock_table.html | 5 +- InvenTree/users/models.py | 18 ++- 7 files changed, 162 insertions(+), 30 deletions(-) diff --git a/InvenTree/part/templatetags/inventree_extras.py b/InvenTree/part/templatetags/inventree_extras.py index 9692e208e2..89f6ff7179 100644 --- a/InvenTree/part/templatetags/inventree_extras.py +++ b/InvenTree/part/templatetags/inventree_extras.py @@ -145,3 +145,22 @@ def get_color_theme_css(username): inventree_css_static_url = os.path.join(settings.STATIC_URL, inventree_css_sheet) return inventree_css_static_url + + +@register.simple_tag() +def authorized_owners(group): + """ Return authorized owners """ + + owners = [] + + try: + for owner in group.get_users(include_group=True): + owners.append(owner.owner) + except AttributeError: + # group is None + pass + except TypeError: + # group.get_users returns None + pass + + return owners diff --git a/InvenTree/stock/templates/stock/item.html b/InvenTree/stock/templates/stock/item.html index 1082eef397..74fe8acdcd 100644 --- a/InvenTree/stock/templates/stock/item.html +++ b/InvenTree/stock/templates/stock/item.html @@ -9,12 +9,15 @@ {% include "stock/tabs.html" with tab="tracking" %} {% setting_object 'STOCK_OWNERSHIP_CONTROL' as owner_control %} +{% if owner_control.value == "True" %} + {% authorized_owners item.owner as owners %} +{% endif %}

{% trans "Stock Tracking Information" %}


-{% if owner_control.value == "False" or owner_control.value == "True" and item.owner == user %} +{% if owner_control.value == "False" or owner_control.value == "True" and user in owners %} {% if roles.stock.change and not item.is_building %}
diff --git a/InvenTree/stock/templates/stock/item_base.html b/InvenTree/stock/templates/stock/item_base.html index 48c65d65bf..6279c48ab7 100644 --- a/InvenTree/stock/templates/stock/item_base.html +++ b/InvenTree/stock/templates/stock/item_base.html @@ -16,6 +16,15 @@ InvenTree | {% trans "Stock Item" %} - {{ item }} {% include 'stock/loc_link.html' with location=item.location %} {% setting_object 'STOCK_OWNERSHIP_CONTROL' as owner_control %} +{% if owner_control.value == "True" %} + {% authorized_owners item.owner as owners %} + + {% if not user in owners and not user.is_superuser %} +
+ {% trans "You are not the owner of this item. This stock item cannot be edited." %}
+
+ {% endif %} +{% endif %} {% if item.is_building %}
@@ -31,12 +40,6 @@ InvenTree | {% trans "Stock Item" %} - {{ item }}
{% endif %} -{% if owner_control.value == "True" and not item.owner == user and not user.is_superuser %} -
- {% trans "You are not the owner of this item. This stock item cannot be edited." %}
-
-{% endif %} - {% if item.hasRequiredTests and not item.passedAllRequiredTests %}
{% trans "This stock item has not passed all required tests" %} @@ -78,6 +81,9 @@ InvenTree | {% trans "Stock Item" %} - {{ item }} {% block page_data %} {% setting_object 'STOCK_OWNERSHIP_CONTROL' as owner_control %} +{% if owner_control.value == "True" %} + {% authorized_owners item.owner as owners %} +{% endif %}

{% trans "Stock Item" %} @@ -144,7 +150,7 @@ InvenTree | {% trans "Stock Item" %} - {{ item }} {% endif %} - {% if owner_control.value == "False" or owner_control.value == "True" and item.owner == user or user.is_superuser %} + {% if owner_control.value == "False" or owner_control.value == "True" and user in owners or user.is_superuser %} {% if roles.stock.change and not item.is_building %}
diff --git a/InvenTree/stock/templates/stock/location.html b/InvenTree/stock/templates/stock/location.html index 6c47a697ca..5c03b365ab 100644 --- a/InvenTree/stock/templates/stock/location.html +++ b/InvenTree/stock/templates/stock/location.html @@ -5,11 +5,14 @@ {% block content %} {% setting_object 'STOCK_OWNERSHIP_CONTROL' as owner_control %} +{% if owner_control.value == "True" %} + {% authorized_owners location.owner as owners %} -{% if location and owner_control.value == "True" and not location.owner in user.groups.all and not user.is_superuser %} -
- {% trans "You are not in the list of owners of this location. This stock location cannot be edited." %}
-
+ {% if location and not user in owners and not user.is_superuser %} +
+ {% trans "You are not in the list of owners of this location. This stock location cannot be edited." %}
+
+ {% endif %} {% endif %}
@@ -27,7 +30,7 @@

{% trans "All stock items" %}

{% endif %}
- {% if owner_control.value == "False" or owner_control.value == "True" and location.owner in user.groups.all or user.is_superuser or not location %} + {% if owner_control.value == "False" or owner_control.value == "True" and user in owners or user.is_superuser or not location %} {% if roles.stock.add %}
- {% if owner_control.value == "False" or owner_control.value == "True" and location.owner in user.groups.all or user.is_superuser %} + {% if owner_control.value == "False" or owner_control.value == "True" and user in owners or user.is_superuser %} {% if roles.stock.change %}
diff --git a/InvenTree/stock/views.py b/InvenTree/stock/views.py index 7b3cedb5b4..0eab69661f 100644 --- a/InvenTree/stock/views.py +++ b/InvenTree/stock/views.py @@ -166,13 +166,59 @@ class StockLocationEdit(AjaxUpdateView): stock_ownership_control = InvenTreeSetting.get_setting('STOCK_OWNERSHIP_CONTROL') if stock_ownership_control: - if self.object.get_children(): - for child in self.object.get_children(): - child.owner = self.object.owner - child.save() + authorized_owners = self.object.owner.get_users() + print(f'{authorized_owners=}') + + # Update children locations + children_locations = self.object.get_children() + for child in children_locations: + # Check if current owner is subset of new owner + if child.owner and authorized_owners: + if child.owner in authorized_owners: + continue + + child.owner = self.object.owner + child.save() + + # Update stock items + stock_items = self.object.get_stock_items() + print(f'{stock_items=}') + for stock_item in stock_items: + # Check if current owner is subset of new owner + if stock_item.owner and authorized_owners: + if stock_item.owner in authorized_owners: + print(f'{stock_item.owner} is authorized') + continue + + print(f'Updating stock item {stock_item} owner') + stock_item.owner = self.object.owner + stock_item.save() return self.object + def validate(self, item, form): + """ Check that owner is set if stock ownership control is enabled """ + + parent = form.cleaned_data.get('parent', None) + + owner = form.cleaned_data.get('owner', None) + + # Is ownership control enabled? + stock_ownership_control = InvenTreeSetting.get_setting('STOCK_OWNERSHIP_CONTROL') + + if stock_ownership_control: + if not owner and not self.request.user.is_superuser: + form.add_error('owner', _('Owner is required (ownership control is enabled)')) + else: + try: + if parent.owner: + if parent.owner != owner: + error = f'Owner requires to be equivalent to parent\'s owner ({parent.owner})' + form.add_error('owner', error) + except AttributeError: + # No parent + pass + class StockLocationQRCode(QRCodeView): """ View for displaying a QR code for a StockLocation object """ @@ -1288,6 +1334,18 @@ class StockAdjust(AjaxView, FormMixin): count += 1 + # Is ownership control enabled? + stock_ownership_control = InvenTreeSetting.get_setting('STOCK_OWNERSHIP_CONTROL') + + if stock_ownership_control: + # Fetch destination owner + destination_owner = destination.owner + + if destination_owner: + # Update owner + item.owner = destination_owner + item.save() + if count == 0: return _('No items were moved') @@ -1361,12 +1419,18 @@ class StockItemEdit(AjaxUpdateView): if not stock_ownership_control: form.fields['owner'].widget = HiddenInput() else: - location_owner = location.owner + try: + location_owner = location.owner + except AttributeError: + location_owner = None + # Check if location has owner if location_owner: + form.fields['owner'].initial = location_owner + # Check location owner type and filter if type(location_owner.owner) is Group: - queryset = location_owner.get_users() + queryset = location_owner.get_users(include_group=True) if self.request.user in queryset: form.fields['owner'].initial = self.request.user form.fields['owner'].queryset = queryset @@ -1374,6 +1438,25 @@ class StockItemEdit(AjaxUpdateView): form.fields['owner'].disabled = True form.fields['owner'].initial = location_owner + try: + item_owner = item.owner + except AttributeError: + item_owner = None + + # Check if item has owner + if item_owner: + form.fields['owner'].initial = item_owner + + # Check location owner type and filter + if type(item_owner.owner) is Group: + queryset = item_owner.get_users(include_group=True) + if self.request.user in queryset: + form.fields['owner'].initial = self.request.user + form.fields['owner'].queryset = queryset + elif type(item_owner.owner) is User: + form.fields['owner'].disabled = True + form.fields['owner'].initial = item_owner + return form def validate(self, item, form): @@ -1384,8 +1467,9 @@ class StockItemEdit(AjaxUpdateView): # Is ownership control enabled? stock_ownership_control = InvenTreeSetting.get_setting('STOCK_OWNERSHIP_CONTROL') - if not owner and stock_ownership_control: - form.add_error('owner', _('Owner is required (ownership control is enabled)')) + if stock_ownership_control: + if not owner and not self.request.user.is_superuser: + form.add_error('owner', _('Owner is required (ownership control is enabled)')) class StockItemConvert(AjaxUpdateView): @@ -1495,7 +1579,7 @@ class StockLocationCreate(AjaxCreateView): stock_ownership_control = InvenTreeSetting.get_setting('STOCK_OWNERSHIP_CONTROL') if stock_ownership_control: - if not owner: + if not owner and not self.request.user.is_superuser: form.add_error('owner', _('Owner is required (ownership control is enabled)')) else: try: @@ -1716,7 +1800,11 @@ class StockItemCreate(AjaxCreateView): if not stock_ownership_control: form.fields['owner'].widget = HiddenInput() else: - location_owner = location.owner + try: + location_owner = location.owner + except AttributeError: + location_owner = None + if location_owner: # Check location owner type and filter if type(location_owner.owner) is Group: @@ -1848,7 +1936,7 @@ class StockItemCreate(AjaxCreateView): if stock_ownership_control: # Check if owner is set - if not owner: + if not owner and not self.request.user.is_superuser: form.add_error('owner', _('Owner is required (ownership control is enabled)')) return diff --git a/InvenTree/templates/stock_table.html b/InvenTree/templates/stock_table.html index 9746ff0aaa..2e13721af1 100644 --- a/InvenTree/templates/stock_table.html +++ b/InvenTree/templates/stock_table.html @@ -2,6 +2,9 @@ {% load inventree_extras %} {% setting_object 'STOCK_OWNERSHIP_CONTROL' as owner_control %} +{% if owner_control.value == "True" %} + {% authorized_owners location.owner as owners %} +{% endif %}
@@ -12,7 +15,7 @@ {% if read_only %} {% else %} - {% if owner_control.value == "False" or owner_control.value == "True" and location.owner in user.groups.all or user.is_superuser %} + {% if owner_control.value == "False" or owner_control.value == "True" and user in owners or user.is_superuser %} {% if roles.stock.add %}