Skip to content

Commit

Permalink
Improve searching for stock types by name in the web interface
Browse files Browse the repository at this point in the history
  • Loading branch information
sde1000 committed Aug 1, 2024
1 parent ba4b16b commit 4cb5241
Showing 1 changed file with 18 additions and 13 deletions.
31 changes: 18 additions & 13 deletions quicktill/tillweb/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
from sqlalchemy.orm import defaultload
from sqlalchemy.orm import undefer, undefer_group
from sqlalchemy.sql import select, desc
from sqlalchemy.sql.expression import tuple_, func, null
from sqlalchemy.sql.expression import tuple_, func, null, and_, or_
from sqlalchemy import distinct
from quicktill.models import (
StockType,
Expand Down Expand Up @@ -1148,7 +1148,7 @@ def __init__(self, info, *args, **kwargs):
label_function=stocktype_widget_label,
query_filter=lambda x: x.order_by(StockType.manufacturer,
StockType.name),
widget=Select2Ajax(min_input_length=2))
widget=Select2Ajax(min_input_length=3))
itemsize = SQLAModelChoiceField(StockUnit, required=False,
empty_label='Choose an item size')
quantity = forms.IntegerField(min_value=1, required=False, initial=1)
Expand Down Expand Up @@ -1416,18 +1416,23 @@ def _stocktype_to_dict(x, include_stockunits):
def stocktype_search_json(request, info, include_stockunits=False):
if 'q' not in request.GET:
return JsonResponse({'results': []})
words = request.GET['q'].split()
query = request.GET['q'].strip()
words = query.split()
if not words:
return JsonResponse({'results': []})
q = td.s.query(StockType)\
.order_by(StockType.dept_id, StockType.manufacturer,
StockType.name)
if len(words) == 1:
q = q.filter((StockType.manufacturer.ilike(f"%{words[0]}%"))
| (StockType.name.ilike(f"%{words[0]}%")))
else:
q = q.filter(StockType.manufacturer.ilike(f"%{words[0]}%"))\
.filter(StockType.name.ilike(f"%{words[1]}%"))
# We always search for the query entered in the full name of the
# product formed from joining the manufacturer and name. If the
# query consists of exactly two words, we also search for the
# first word in the manufacturer and the second word in the name.
qf = or_(StockType.fullname.ilike(f"%{query}%"),
StockType.fullname.ilike(f"%{' '.join(words)}%"))
if len(words) == 2:
qf = qf | and_(StockType.manufacturer.ilike(f"%{words[0]}%"),
StockType.name.ilike(f"%{words[1]}%"))
q = q.filter(qf)
if include_stockunits:
q = q.options(joinedload('unit').joinedload('stockunits'))
results = q.all()
Expand Down Expand Up @@ -1688,7 +1693,7 @@ def __init__(self, info, *args, **kwargs):
label_function=stocktype_widget_label,
query_filter=lambda x: x.order_by(StockType.manufacturer,
StockType.name),
widget=Select2Ajax(min_input_length=2))
widget=Select2Ajax(min_input_length=3))
description = forms.CharField()
size = forms.DecimalField(
min_value=min_quantity, max_digits=qty_max_digits,
Expand Down Expand Up @@ -2093,7 +2098,7 @@ def __init__(self, info, *args, **kwargs):
label_function=stocktype_widget_label,
query_filter=lambda x: x.order_by(StockType.manufacturer,
StockType.name),
widget=Select2Ajax(min_input_length=2))
widget=Select2Ajax(min_input_length=3))
department = SQLAModelChoiceField(
Department,
label="Restrict new stock to this department",
Expand Down Expand Up @@ -2190,7 +2195,7 @@ def __init__(self, info, *args, **kwargs):
label_function=stocktype_widget_label,
query_filter=lambda x: x.order_by(StockType.manufacturer,
StockType.name),
widget=Select2Ajax(min_input_length=2))
widget=Select2Ajax(min_input_length=3))
capacity = forms.IntegerField(
label="Maximum number of items on display", min_value=1)

Expand Down Expand Up @@ -2280,7 +2285,7 @@ def __init__(self, info, *args, **kwargs):
label_function=stocktype_widget_label,
query_filter=lambda x: x.order_by(StockType.manufacturer,
StockType.name),
widget=Select2Ajax(min_input_length=2))
widget=Select2Ajax(min_input_length=3))


def stockline_continuous(request, info, s):
Expand Down

0 comments on commit 4cb5241

Please sign in to comment.