diff --git a/InvenTree/stock/models.py b/InvenTree/stock/models.py index 42cc5b9f7a..83e7a0db8d 100644 --- a/InvenTree/stock/models.py +++ b/InvenTree/stock/models.py @@ -63,6 +63,43 @@ class StockLocation(InvenTreeTree): help_text=_('Select Owner'), related_name='stock_locations') + def get_location_owner(self): + """ + Get the closest "owner" for this location. + + Start at this location, and traverse "up" the location tree until we find an owner + """ + + for loc in self.get_ancestors(include_self=True, ascending=True): + if loc.owner is not None: + return loc.owner + + return None + + def check_ownership(self, user): + """ + Check if the user "owns" (is one of the owners of) the location. + """ + + # Superuser accounts automatically "own" everything + if user.is_superuser: + return True + + ownership_enabled = common.models.InvenTreeSetting.get_setting('STOCK_OWNERSHIP_CONTROL') + + if not ownership_enabled: + # Location ownership function is not enabled, so return True + return True + + owner = self.get_location_owner() + + if owner is None: + # No owner set, for this location or any location above + # So, no ownership checks to perform! + return True + + return user in owner.get_related_owners(include_group=True) + def get_absolute_url(self): return reverse('stock-location-detail', kwargs={'pk': self.id}) diff --git a/InvenTree/stock/templates/stock/location.html b/InvenTree/stock/templates/stock/location.html index c07e4f8162..68a4cd7aed 100644 --- a/InvenTree/stock/templates/stock/location.html +++ b/InvenTree/stock/templates/stock/location.html @@ -20,7 +20,6 @@ {% endblock %} {% block actions %} -{% setting_object 'STOCK_OWNERSHIP_CONTROL' as owner_control %} {% if location and user.is_staff and roles.stock_location.change %} @@ -40,7 +39,7 @@ -{% if owner_control.value == "False" or owner_control.value == "True" and user in owners or user.is_superuser %} +{% if user_owns_location %} {% if roles.stock.change %}
{% endif %} -{% endif %} {% endblock %} {% block details_left %} @@ -108,23 +105,23 @@ {% trans "Top level stock location" %} {% endif %} + {% if ownership_enabled and location_owner %} + + + {% trans "Location Owner" %} + + {{ location_owner }} + {% if not user_owns_location %} + + {% trans "Read Only" %} + + {% endif %} + + + {% endif %} {% endblock details_left %} -{% block details_below %} -{% setting_object 'STOCK_OWNERSHIP_CONTROL' as owner_control %} -{% if owner_control.value == "True" %} - {% authorized_owners location.owner as owners %} - - {% 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 %} - -{% endblock details_below %} - {% block details_right %} {% if location %} diff --git a/InvenTree/stock/views.py b/InvenTree/stock/views.py index 9aa70255b1..f9b7dfb6d0 100644 --- a/InvenTree/stock/views.py +++ b/InvenTree/stock/views.py @@ -63,6 +63,11 @@ class StockIndex(InvenTreeRoleMixin, ListView): context['loc_count'] = StockLocation.objects.count() context['stock_count'] = StockItem.objects.count() + # No 'ownership' checks are necessary for the top-level StockLocation view + context['user_owns_location'] = True + context['location_owner'] = None + context['ownership_enabled'] = common.models.InvenTreeSetting.get_setting('STOCK_OWNERSHIP_CONTROL') + return context @@ -76,6 +81,16 @@ class StockLocationDetail(InvenTreeRoleMixin, DetailView): queryset = StockLocation.objects.all() model = StockLocation + def get_context_data(self, **kwargs): + + context = super().get_context_data(**kwargs) + + context['ownership_enabled'] = common.models.InvenTreeSetting.get_setting('STOCK_OWNERSHIP_CONTROL') + context['location_owner'] = context['location'].get_location_owner() + context['user_owns_location'] = context['location'].check_ownership(self.request.user) + + return context + class StockItemDetail(InvenTreeRoleMixin, DetailView): """