diff --git a/InvenTree/part/templatetags/inventree_extras.py b/InvenTree/part/templatetags/inventree_extras.py index 89f6ff7179..c0dc15c2b0 100644 --- a/InvenTree/part/templatetags/inventree_extras.py +++ b/InvenTree/part/templatetags/inventree_extras.py @@ -154,7 +154,7 @@ def authorized_owners(group): owners = [] try: - for owner in group.get_users(include_group=True): + for owner in group.get_related_owners(include_group=True): owners.append(owner.owner) except AttributeError: # group is None diff --git a/InvenTree/stock/test_views.py b/InvenTree/stock/test_views.py index 6b8c6de255..366f15239f 100644 --- a/InvenTree/stock/test_views.py +++ b/InvenTree/stock/test_views.py @@ -323,11 +323,9 @@ class StockOwnershipTest(StockViewTestCase): self.assertEqual(location.owner, user_group_owner) # Test item edit - # response = self.client.post(reverse('stock-item-edit', args=(test_item_id,)), - # {'part': 1, 'status': StockStatus.OK, 'owner': new_user_as_owner.pk}, - # HTTP_X_REQUESTED_WITH='XMLHttpRequest') - # print(response.content) - # self.assertContains(response, '"form_valid": false', status_code=200) + response = self.client.post(reverse('stock-item-edit', args=(test_item_id,)), + {'part': 1, 'status': StockStatus.OK, 'owner': new_user_as_owner.pk}, + HTTP_X_REQUESTED_WITH='XMLHttpRequest') # Make sure the item's owner is unchanged item = StockItem.objects.get(pk=test_item_id) @@ -384,18 +382,19 @@ class StockOwnershipTest(StockViewTestCase): } # Try to create new item with no owner - # response = self.client.post(reverse('stock-item-create'), - # new_item, HTTP_X_REQUESTED_WITH='XMLHttpRequest') - # self.assertContains(response, '"form_valid": false', status_code=200) + response = self.client.post(reverse('stock-item-create'), + new_item, HTTP_X_REQUESTED_WITH='XMLHttpRequest') + # print(response.content) + self.assertContains(response, '"form_valid": false', status_code=200) # Try to create new item with invalid owner - # new_item['owner'] = user_as_owner - # response = self.client.post(reverse('stock-item-create'), - # new_item, HTTP_X_REQUESTED_WITH='XMLHttpRequest') - # self.assertContains(response, '"form_valid": false', status_code=200) + new_item['owner'] = user_as_owner.pk + response = self.client.post(reverse('stock-item-create'), + new_item, HTTP_X_REQUESTED_WITH='XMLHttpRequest') + self.assertContains(response, '"form_valid": false', status_code=200) # Try to create new item with valid owner - new_item['owner'] = new_user_as_owner + new_item['owner'] = new_user_as_owner.pk response = self.client.post(reverse('stock-item-create'), new_item, HTTP_X_REQUESTED_WITH='XMLHttpRequest') self.assertContains(response, '"form_valid": true', status_code=200) diff --git a/InvenTree/stock/views.py b/InvenTree/stock/views.py index 2f294aa085..14d8abe723 100644 --- a/InvenTree/stock/views.py +++ b/InvenTree/stock/views.py @@ -37,6 +37,7 @@ from .models import StockItem, StockLocation, StockItemTracking, StockItemAttach import common.settings from common.models import InvenTreeSetting +from users.models import Owner from .admin import StockItemResource @@ -166,7 +167,7 @@ class StockLocationEdit(AjaxUpdateView): stock_ownership_control = InvenTreeSetting.get_setting('STOCK_OWNERSHIP_CONTROL') if stock_ownership_control: - authorized_owners = self.object.owner.get_users() + authorized_owners = self.object.owner.get_related_owners() # Update children locations children_locations = self.object.get_children() @@ -1427,9 +1428,10 @@ class StockItemEdit(AjaxUpdateView): # Check location owner type and filter if type(location_owner.owner) is Group: - queryset = location_owner.get_users(include_group=True) - if self.request.user in queryset: - form.fields['owner'].initial = self.request.user + user_as_owner = Owner.get_owner(self.request.user) + queryset = location_owner.get_related_owners(include_group=True) + if user_as_owner in queryset: + form.fields['owner'].initial = user_as_owner form.fields['owner'].queryset = queryset elif type(location_owner.owner) is User: form.fields['owner'].disabled = True @@ -1446,9 +1448,10 @@ class StockItemEdit(AjaxUpdateView): # 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 + user_as_owner = Owner.get_owner(self.request.user) + queryset = item_owner.get_related_owners(include_group=True) + if user_as_owner in queryset: + form.fields['owner'].initial = user_as_owner form.fields['owner'].queryset = queryset elif type(item_owner.owner) is User: form.fields['owner'].disabled = True @@ -1727,6 +1730,8 @@ class StockItemCreate(AjaxCreateView): ForeignKey choices based on other selections """ + print('------------ FORM ------------------') + form = super().get_form() # Hide the "expiry date" field if the feature is not enabled @@ -1797,17 +1802,25 @@ class StockItemCreate(AjaxCreateView): if not stock_ownership_control: form.fields['owner'].widget = HiddenInput() else: + print('> Stock ownership is enabled') try: location_owner = location.owner except AttributeError: location_owner = None + print(f'{location_owner=}') + if location_owner: # Check location owner type and filter if type(location_owner.owner) is Group: - queryset = location_owner.get_users() - if self.request.user in queryset: - form.fields['owner'].initial = self.request.user + print(f'{self.request.user=}') + user_as_owner = Owner.get_owner(self.request.user) + print(f'{user_as_owner=}') + queryset = location_owner.get_related_owners() + print(f'{queryset=}') + + if user_as_owner in queryset: + form.fields['owner'].initial = user_as_owner form.fields['owner'].queryset = queryset elif type(location_owner.owner) is User: form.fields['owner'].disabled = True diff --git a/InvenTree/users/models.py b/InvenTree/users/models.py index 6243400687..8817d3409c 100644 --- a/InvenTree/users/models.py +++ b/InvenTree/users/models.py @@ -422,27 +422,62 @@ class Owner(models.Model): except IntegrityError: return None + return existing_owner + @classmethod def get_owner(cls, user_or_group): - # Get corresponding owner - try: - group = Owner.objects.get(owner_id=user_or_group.id, - owner_type=ContentType.objects.get_for_model(Group).id) - return group - except Owner.DoesNotExist: - pass + owner = None + content_type_id = 0 + content_type_id_list = [ContentType.objects.get_for_model(Group).id, + ContentType.objects.get_for_model(User).id] - try: - user = Owner.objects.get(owner_id=user_or_group.id, - owner_type=ContentType.objects.get_for_model(User).id) - return user - except Owner.DoesNotExist: - pass + # If instance type is obvious: set content type + if type(user_or_group) is Group: + content_type_id = content_type_id_list[0] + elif type(user_or_group) is User: + content_type_id = content_type_id_list[1] - return None + if content_type_id: + try: + owner = Owner.objects.get(owner_id=user_or_group.id, + owner_type=content_type_id) + except Owner.DoesNotExist: + pass + else: + # Check whether user_or_group is a Group instance + try: + group = Group.objects.get(pk=user_or_group.id) + except Group.DoesNotExist: + group = None - def get_users(self, include_group=False): + if group: + try: + owner = Owner.objects.get(owner_id=user_or_group.id, + owner_type=content_type_id_list[0]) + except Owner.DoesNotExist: + pass + + return owner + + # Check whether user_or_group is a User instance + try: + user = User.objects.get(pk=user_or_group.id) + except User.DoesNotExist: + user = None + + if user: + try: + owner = Owner.objects.get(owner_id=user_or_group.id, + owner_type=content_type_id_list[1]) + except Owner.DoesNotExist: + pass + + return owner + + return owner + + def get_related_owners(self, include_group=False): owner_users = None