summaryrefslogtreecommitdiff
path: root/archaeological_warehouse
diff options
context:
space:
mode:
authorÉtienne Loks <etienne.loks@iggdrasil.net>2021-02-12 11:36:21 +0100
committerÉtienne Loks <etienne.loks@iggdrasil.net>2021-02-28 12:15:24 +0100
commit5683f1ef9128367e8bcbe87eb58a122a9e7e1aea (patch)
tree5f4779b7e1b91b0f86376591dbe087bf38306021 /archaeological_warehouse
parent6b51ad99e8787d33fba8d22f32517ec8be8414db (diff)
downloadIshtar-5683f1ef9128367e8bcbe87eb58a122a9e7e1aea.tar.bz2
Ishtar-5683f1ef9128367e8bcbe87eb58a122a9e7e1aea.zip
Container autocomplete: improve search
Diffstat (limited to 'archaeological_warehouse')
-rw-r--r--archaeological_warehouse/tests.py43
-rw-r--r--archaeological_warehouse/views.py30
2 files changed, 69 insertions, 4 deletions
diff --git a/archaeological_warehouse/tests.py b/archaeological_warehouse/tests.py
index 93acafa9f..873941d8e 100644
--- a/archaeological_warehouse/tests.py
+++ b/archaeological_warehouse/tests.py
@@ -513,6 +513,49 @@ class ContainerTest(FindInit, TestCase):
warehouse_type=models.WarehouseType.objects.all()[0]
)
+ def test_container_search(self):
+ ct = models.ContainerType.objects.all()[0]
+ ct2 = models.ContainerType.objects.all()[0]
+ container_1 = models.Container.objects.create(
+ reference="Test", responsible=self.main_warehouse,
+ location=self.main_warehouse,
+ container_type=ct
+ )
+ container_2 = models.Container.objects.create(
+ reference="35000", responsible=self.main_warehouse,
+ parent=container_1,
+ location=self.main_warehouse,
+ container_type=ct2
+ )
+ container_2.index = 42000
+ container_2.save()
+ username, password, user = create_user()
+ user.user_permissions.add(Permission.objects.get(
+ codename='view_warehouse'))
+ client = Client()
+ client.login(username=username, password=password)
+ url = "/autocomplete-container/{}/".format(self.main_warehouse.pk)
+ response = client.get(url, {"term": "Test"})
+ self.assertEqual(response.status_code, 200)
+ c = json.loads(response.content.decode())
+ self.assertEqual(len(c), 2)
+ response = client.get(url, {"term": "Test 35000"})
+ self.assertEqual(response.status_code, 200)
+ c = json.loads(response.content.decode())
+ self.assertEqual(len(c), 1)
+ response = client.get(url, {"term": "42000"})
+ self.assertEqual(response.status_code, 200)
+ c = json.loads(response.content.decode())
+ self.assertEqual(len(c), 1)
+ response = client.get(
+ url,
+ {"term": "{} Test {} Test 35000".format(ct.label, ct2.label)})
+ self.assertEqual(response.status_code, 200)
+ c = json.loads(response.content.decode())
+ self.assertEqual(len(c), 1)
+
+
+
def test_form_creation(self):
data = {
'reference': 'hop-ref',
diff --git a/archaeological_warehouse/views.py b/archaeological_warehouse/views.py
index bc8bac127..efa5bdf19 100644
--- a/archaeological_warehouse/views.py
+++ b/archaeological_warehouse/views.py
@@ -95,20 +95,42 @@ def autocomplete_container(request, warehouse_id=None):
return HttpResponse(content_type='text/plain')
if not request.GET.get('term'):
return HttpResponse(content_type='text/plain')
- term = request.GET.get('term')
+ term = request.GET.get('term').strip()
limit = 15
base_query = Q()
if warehouse_id:
base_query = Q(location_id=warehouse_id)
query = base_query
+ # exact index
+ try:
+ query = query & Q(index=int(term))
+ containers = list(models.Container.objects.filter(
+ query).values('id', 'cached_label')[:limit])
+ except ValueError:
+ containers = []
# exact ref
query = query & Q(reference__unaccent__iexact=term)
- containers = list(models.Container.objects.filter(
+ containers += list(models.Container.objects.filter(
query).values('id', 'cached_label')[:limit])
limit = 15 - len(containers)
- splitted = term.split(' ')
+ splitted = [s for s in term.split(' ') if s]
if limit > 0:
- if len(splitted) > 1:
+ if len(splitted) > 1 and not len(splitted) % 2:
+ # group by container type, ref tuple
+ groups = [(splitted[idx * 2], splitted[idx * 2 + 1])
+ for idx in range(int(len(splitted) / 2))]
+ query = base_query
+ for idx, g in enumerate(reversed(groups)):
+ base_key = "parent__" * idx
+ key1 = base_key + "container_type__label__unaccent__iexact"
+ key2 = base_key + "reference__unaccent__iexact"
+ query &= Q(**{key1: g[0], key2: g[1]})
+ ids = set([c["id"] for c in containers])
+ containers += list(models.Container.objects.filter(
+ query).exclude(pk__in=ids).values('id', 'cached_label')[
+ :limit])
+
+ if len(splitted) > 1 and (15 - len(containers)) > 0:
# group to do a "type" "reference" search
for idx in range(1, len(splitted)):
group_1 = splitted[:idx]