From ac26f61ecdcd75e8c9de8448c05d71ba84e54bd2 Mon Sep 17 00:00:00 2001 From: Oliver Date: Mon, 13 Nov 2023 15:06:45 +1100 Subject: [PATCH] Owner list API updates (#5906) * Implement better search matching for owner list API * Update UserSerializer -Add filterset fields to various API endpoints * Allow owner list to be filtered by "is_active" status - Only applies to users (not groups) * Add ability to filter "owner" list by "is_active" status - Only applies to users * Use "is_active" filter for "responsible" form field --- InvenTree/templates/js/translated/build.js | 3 ++ InvenTree/templates/js/translated/part.js | 3 ++ .../templates/js/translated/purchase_order.js | 3 ++ .../templates/js/translated/return_order.js | 3 ++ .../templates/js/translated/sales_order.js | 3 ++ InvenTree/users/api.py | 39 ++++++++++++++++--- 6 files changed, 48 insertions(+), 6 deletions(-) diff --git a/InvenTree/templates/js/translated/build.js b/InvenTree/templates/js/translated/build.js index 6ef72a04f1..b0caeef764 100644 --- a/InvenTree/templates/js/translated/build.js +++ b/InvenTree/templates/js/translated/build.js @@ -113,6 +113,9 @@ function buildFormFields() { }, responsible: { icon: 'fa-users', + filters: { + is_active: true, + } }, }; diff --git a/InvenTree/templates/js/translated/part.js b/InvenTree/templates/js/translated/part.js index 48b8c627a0..3ededcf28c 100644 --- a/InvenTree/templates/js/translated/part.js +++ b/InvenTree/templates/js/translated/part.js @@ -172,6 +172,9 @@ function partFields(options={}) { }, responsible: { icon: 'fa-user', + filters: { + is_active: true, + } }, component: { default: global_settings.PART_COMPONENT, diff --git a/InvenTree/templates/js/translated/purchase_order.js b/InvenTree/templates/js/translated/purchase_order.js index 8807942430..c0e719ab96 100644 --- a/InvenTree/templates/js/translated/purchase_order.js +++ b/InvenTree/templates/js/translated/purchase_order.js @@ -139,6 +139,9 @@ function purchaseOrderFields(options={}) { }, responsible: { icon: 'fa-user', + filters: { + is_active: true, + } }, }; diff --git a/InvenTree/templates/js/translated/return_order.js b/InvenTree/templates/js/translated/return_order.js index dfae5067da..78ef11e4ad 100644 --- a/InvenTree/templates/js/translated/return_order.js +++ b/InvenTree/templates/js/translated/return_order.js @@ -104,6 +104,9 @@ function returnOrderFields(options={}) { }, responsible: { icon: 'fa-user', + filters: { + is_active: true, + } } }; diff --git a/InvenTree/templates/js/translated/sales_order.js b/InvenTree/templates/js/translated/sales_order.js index 61e1990c3b..3f586e72f0 100644 --- a/InvenTree/templates/js/translated/sales_order.js +++ b/InvenTree/templates/js/translated/sales_order.js @@ -130,6 +130,9 @@ function salesOrderFields(options={}) { }, responsible: { icon: 'fa-user', + filters: { + is_active: true, + } } }; diff --git a/InvenTree/users/api.py b/InvenTree/users/api.py index 08cf44a442..3486bf6ebb 100644 --- a/InvenTree/users/api.py +++ b/InvenTree/users/api.py @@ -10,6 +10,7 @@ from rest_framework import exceptions, permissions from rest_framework.response import Response from rest_framework.views import APIView +import InvenTree.helpers from InvenTree.filters import SEARCH_ORDER_FILTER from InvenTree.mixins import (ListAPI, ListCreateAPI, RetrieveAPI, RetrieveUpdateAPI, RetrieveUpdateDestroyAPI) @@ -42,19 +43,39 @@ class OwnerList(ListAPI): but until we determine a better way, this is what we have... """ search_term = str(self.request.query_params.get('search', '')).lower() + is_active = self.request.query_params.get('is_active', None) queryset = super().filter_queryset(queryset) - if not search_term: - return queryset - results = [] - # Extract search term f + # Get a list of all matching users, depending on the *is_active* flag + if is_active is not None: + is_active = InvenTree.helpers.str2bool(is_active) + matching_user_ids = User.objects.filter(is_active=is_active).values_list('pk', flat=True) for result in queryset.all(): - if search_term in result.name().lower(): - results.append(result) + + name = str(result.name()).lower().strip() + search_match = True + + # Extract search term f + if search_term: + for entry in search_term.strip().split(' '): + if entry not in name: + search_match = False + break + + if not search_match: + continue + + if is_active is not None: + # Skip any users which do not match the required *is_active* value + if result.owner_type.name == 'user' and result.owner_id not in matching_user_ids: + continue + + # If we get here, there is no reason *not* to include this result + results.append(result) return results @@ -156,6 +177,12 @@ class UserList(ListCreateAPI): 'is_active', ] + filterset_fields = [ + 'is_staff', + 'is_active', + 'is_superuser', + ] + class GroupDetail(RetrieveUpdateDestroyAPI): """Detail endpoint for a particular auth group"""