2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-06-16 03:55:41 +00:00

User Setting To Search Notes (#9393)

* add search notes and tie user search settings to checkboxes in search drawer

* add user setting to optionally search the notes of objects

* add search filter test

* add PR link

* add limit parameter

* typo, meant to check part result

* resolve api_version.py conflict

* don't use search_whole and search_regex together

---------

Co-authored-by: Matthias Mair <code@mjmair.com>
This commit is contained in:
Jacob Felknor
2025-04-03 16:22:39 -06:00
committed by GitHub
parent 2712f30382
commit 6021035e3f
8 changed files with 133 additions and 11 deletions

View File

@ -582,6 +582,7 @@ class APISearchViewSerializer(serializers.Serializer):
search = serializers.CharField()
search_regex = serializers.BooleanField(default=False, required=False)
search_whole = serializers.BooleanField(default=False, required=False)
search_notes = serializers.BooleanField(default=False, required=False)
limit = serializers.IntegerField(default=1, required=False)
offset = serializers.IntegerField(default=0, required=False)
@ -643,6 +644,7 @@ class APISearchView(GenericAPIView):
'search': '',
'search_regex': False,
'search_whole': False,
'search_notes': False,
'limit': 1,
'offset': 0,
}

View File

@ -1,12 +1,15 @@
"""InvenTree API version information."""
# InvenTree API version
INVENTREE_API_VERSION = 331
INVENTREE_API_VERSION = 332
"""Increment this API version number whenever there is a significant change to the API that any clients need to know about."""
INVENTREE_API_TEXT = """
v332 - 2025-04-02 : https://github.com/inventree/InvenTree/pull/9393
- Adds 'search_notes' parameter to all searchable API endpoints
v331 - 2025-04-01 : https://github.com/inventree/InvenTree/pull/9437
- Set correct types on various formerly-string PK fields as well permissions
- Include metadata request and response types

View File

@ -32,14 +32,23 @@ class InvenTreeSearchFilter(filters.SearchFilter):
"""Return a set of search fields for the request, adjusted based on request params.
The following query params are available to 'augment' the search (in decreasing order of priority)
- search_notes: If True, 'notes' is added to the search_fields if it isn't already present
- search_regex: If True, search is performed on 'regex' comparison
"""
regex = InvenTree.helpers.str2bool(
request.query_params.get('search_regex', False)
search_notes = InvenTree.helpers.str2bool(
request.query_params.get('search_notes', False)
)
search_fields = super().get_search_fields(view, request)
if search_notes and 'notes' not in search_fields:
# don't modify existing list, create a new object so further queries aren't affected
search_fields = [*search_fields, 'notes']
regex = InvenTree.helpers.str2bool(
request.query_params.get('search_regex', False)
)
fields = []
if search_fields:

View File

@ -297,6 +297,7 @@ class SearchTests(InvenTreeAPITestCase):
'stock',
'order',
'sales_order',
'build',
]
roles = ['build.view', 'part.view']
@ -353,6 +354,82 @@ class SearchTests(InvenTreeAPITestCase):
self.assertNotIn('stockitem', response.data)
self.assertNotIn('build', response.data)
def test_search_filters(self):
"""Test that the regex, whole word, and notes filters are handled correctly."""
SEARCH_TERM = 'some note'
RE_SEARCH_TERM = 'some (.*) note'
response = self.post(
reverse('api-search'),
{'search': SEARCH_TERM, 'limit': 10, 'part': {}, 'build': {}},
expected_code=200,
)
# No build or part results
self.assertEqual(response.data['build']['count'], 0)
self.assertEqual(response.data['part']['count'], 0)
# add the search_notes param
response = self.post(
reverse('api-search'),
{
'search': SEARCH_TERM,
'limit': 10,
'search_notes': True,
'part': {},
'build': {},
},
expected_code=200,
)
# now should have some build results
self.assertEqual(response.data['build']['count'], 4)
# use the regex term
response = self.post(
reverse('api-search'),
{
'search': RE_SEARCH_TERM,
'limit': 10,
'search_notes': True,
'part': {},
'build': {},
},
expected_code=200,
)
# No results again
self.assertEqual(response.data['build']['count'], 0)
# add the regex_search param
response = self.post(
reverse('api-search'),
{
'search': RE_SEARCH_TERM,
'limit': 10,
'search_notes': True,
'search_regex': True,
'part': {},
'build': {},
},
expected_code=200,
)
# we get our results back!
self.assertEqual(response.data['build']['count'], 4)
# add the search_whole param
response = self.post(
reverse('api-search'),
{
'search': RE_SEARCH_TERM,
'limit': 10,
'search_notes': True,
'search_whole': True,
'part': {},
'build': {},
},
expected_code=200,
)
# No results again
self.assertEqual(response.data['build']['count'], 0)
def test_permissions(self):
"""Test that users with insufficient permissions are handled correctly."""
# First, remove all roles

View File

@ -165,6 +165,14 @@ USER_SETTINGS: dict[str, InvenTreeSettingsKeyType] = {
'default': False,
'validator': bool,
},
'SEARCH_NOTES': {
'name': _('Search Notes'),
'description': _(
"Search queries return results for matches from the item's notes"
),
'default': False,
'validator': bool,
},
'PART_SHOW_QUANTITY_IN_FORMS': {
'name': _('Show Quantity in Forms'),
'description': _('Display available part quantity in some forms'),