diff --git a/InvenTree/build/api.py b/InvenTree/build/api.py index 2ca9dd31dc..4d47cf9076 100644 --- a/InvenTree/build/api.py +++ b/InvenTree/build/api.py @@ -20,6 +20,7 @@ from InvenTree.status_codes import BuildStatus from .models import Build, BuildItem, BuildOrderAttachment from .serializers import BuildAttachmentSerializer, BuildCompleteSerializer, BuildSerializer, BuildItemSerializer from .serializers import BuildAllocationSerializer, BuildUnallocationSerializer +from users.models import Owner class BuildFilter(rest_filters.FilterSet): @@ -51,6 +52,25 @@ class BuildFilter(rest_filters.FilterSet): return queryset + assigned_to_me = rest_filters.BooleanFilter(label='assigned_to_me', method='filter_assigned_to_me') + + def filter_assigned_to_me(self, queryset, name, value): + """ + Filter by orders which are assigned to the current user + """ + + value = str2bool(value) + + # Work out who "me" is! + owners = Owner.get_owners_matching_user(self.request.user) + + if value: + queryset = queryset.filter(responsible__in=owners) + else: + queryset = queryset.exclude(responsible__in=owners) + + return queryset + class BuildList(generics.ListCreateAPIView): """ API endpoint for accessing a list of Build objects. diff --git a/InvenTree/order/api.py b/InvenTree/order/api.py index 1ae6ae0184..98b9bbe934 100644 --- a/InvenTree/order/api.py +++ b/InvenTree/order/api.py @@ -22,8 +22,39 @@ from InvenTree.status_codes import PurchaseOrderStatus, SalesOrderStatus import order.models as models import order.serializers as serializers - from part.models import Part +from users.models import Owner + + +class POFilter(rest_filters.FilterSet): + """ + Custom API filters for the POList endpoint + """ + + assigned_to_me = rest_filters.BooleanFilter(label='assigned_to_me', method='filter_assigned_to_me') + + def filter_assigned_to_me(self, queryset, name, value): + """ + Filter by orders which are assigned to the current user + """ + + value = str2bool(value) + + # Work out who "me" is! + owners = Owner.get_owners_matching_user(self.request.user) + + if value: + queryset = queryset.filter(responsible__in=owners) + else: + queryset = queryset.exclude(responsible__in=owners) + + return queryset + + class Meta: + model = models.PurchaseOrder + fields = [ + 'supplier', + ] class POList(generics.ListCreateAPIView): @@ -35,6 +66,7 @@ class POList(generics.ListCreateAPIView): queryset = models.PurchaseOrder.objects.all() serializer_class = serializers.POSerializer + filterset_class = POFilter def create(self, request, *args, **kwargs): """ @@ -150,10 +182,6 @@ class POList(generics.ListCreateAPIView): 'reference': ['reference_int', 'reference'], } - filter_fields = [ - 'supplier', - ] - search_fields = [ 'reference', 'supplier__name', diff --git a/InvenTree/part/api.py b/InvenTree/part/api.py index dbc1140214..c1b86b6528 100644 --- a/InvenTree/part/api.py +++ b/InvenTree/part/api.py @@ -583,6 +583,8 @@ class PartFilter(rest_filters.FilterSet): active = rest_filters.BooleanFilter() + virtual = rest_filters.BooleanFilter() + class PartList(generics.ListCreateAPIView): """ diff --git a/InvenTree/templates/js/translated/build.js b/InvenTree/templates/js/translated/build.js index 02b2ff5321..0deec4f859 100644 --- a/InvenTree/templates/js/translated/build.js +++ b/InvenTree/templates/js/translated/build.js @@ -34,7 +34,12 @@ function buildFormFields() { reference: { prefix: global_settings.BUILDORDER_REFERENCE_PREFIX, }, - part: {}, + part: { + filters: { + assembly: true, + virtual: false, + } + }, title: {}, quantity: {}, parent: { diff --git a/InvenTree/templates/js/translated/table_filters.js b/InvenTree/templates/js/translated/table_filters.js index 6920626284..b7ba79e498 100644 --- a/InvenTree/templates/js/translated/table_filters.js +++ b/InvenTree/templates/js/translated/table_filters.js @@ -298,6 +298,10 @@ function getAvailableTableFilters(tableKey) { type: 'bool', title: '{% trans "Overdue" %}', }, + assigned_to_me: { + type: 'bool', + title: '{% trans "Assigned to me" %}', + }, }; } @@ -327,6 +331,10 @@ function getAvailableTableFilters(tableKey) { type: 'bool', title: '{% trans "Overdue" %}', }, + assigned_to_me: { + type: 'bool', + title: '{% trans "Assigned to me" %}', + }, }; } diff --git a/InvenTree/users/models.py b/InvenTree/users/models.py index 2b16a9bb05..e9d0a62d8e 100644 --- a/InvenTree/users/models.py +++ b/InvenTree/users/models.py @@ -477,6 +477,34 @@ class Owner(models.Model): owner: Returns the Group or User instance combining the owner_type and owner_id fields """ + @classmethod + def get_owners_matching_user(cls, user): + """ + Return all "owner" objects matching the provided user: + + A) An exact match for the user + B) Any groups that the user is a part of + """ + + user_type = ContentType.objects.get(app_label='auth', model='user') + group_type = ContentType.objects.get(app_label='auth', model='group') + + owners = [] + + try: + owners.append(cls.objects.get(owner_id=user.pk, owner_type=user_type)) + except: + pass + + for group in user.groups.all(): + try: + owner = cls.objects.get(owner_id=group.pk, owner_type=group_type) + owners.append(owner) + except: + pass + + return owners + @staticmethod def get_api_url(): return reverse('api-owner-list')