From 9ff032ef32a9977a1c4b9736bc38c8c8a207a767 Mon Sep 17 00:00:00 2001
From: Martin Mares <mj@ucw.cz>
Date: Sun, 13 Nov 2022 13:33:40 +0100
Subject: [PATCH] =?UTF-8?q?M=C3=ADsta:=20Vyhled=C3=A1v=C3=A1n=C3=AD=20uva?=
 =?UTF-8?q?=C5=BEuje=20ka=C5=BEd=C3=A9=20slovo=20dotazu=20zvl=C3=A1=C5=A1?=
 =?UTF-8?q?=C5=A5?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Podobně jako to děláme u hledání uživatelů podle jména.

Také upozorňujeme, když se hledá jenom v podstromu.

A pokud jsme našli jednoznačný výsledek, flashneme zprávu upozorňující,
že je to výsledek hledání.
---
 mo/web/org_place.py             | 57 ++++++++++++++++++---------------
 mo/web/templates/org_place.html |  2 +-
 2 files changed, 32 insertions(+), 27 deletions(-)

diff --git a/mo/web/org_place.py b/mo/web/org_place.py
index 649082e1..be48bc15 100644
--- a/mo/web/org_place.py
+++ b/mo/web/org_place.py
@@ -19,7 +19,7 @@ import wtforms.validators as validators
 
 
 class PlaceSearchForm(FlaskForm):
-    query = mo_fields.String(render_kw={'autofocus': True, 'placeholder': 'Kód nebo začátek názvu'})
+    query = mo_fields.String(render_kw={'autofocus': True, 'placeholder': 'Kód nebo části názvu'})
     submit = wtforms.SubmitField('Hledat')
 
 
@@ -35,33 +35,38 @@ def org_place(id: int):
     found_places = None
     search_failed = False
     search_limited = False
-    if search_form.validate_on_submit() and search_form.query.data:
+    if search_form.validate_on_submit():
         query = search_form.query.data
-        found = db.get_place_by_code(query)
-        if found is not None:
-            return redirect(url_for('org_place', id=found.place_id))
-        max_places = 100
-        if '%' in query:
-            found_places = []
-        else:
-            found_places_q = (sess.query(db.Place)
-                              .filter(func.lower(db.f_unaccent(db.Place.name)).like(func.lower(db.f_unaccent(query + '%'))))
-                              .filter(db.Place.place_id != place.place_id))
+        query_words = query.split()
+
+        if len(query_words) == 1:
+            found = db.get_place_by_code(query_words[0])
+            if found is not None:
+                flash('Nalezeno toto místo', 'info')
+                return redirect(url_for('org_place', id=found.place_id))
+
+        if len(query_words) > 0 and '%' not in query:
+            max_places = 100
+            place_q = (sess.query(db.Place)
+                       .filter(db.Place.place_id != place.place_id))
+            for qw in query_words:
+                place_q = place_q.filter(func.lower(db.f_unaccent(db.Place.name)).like(func.lower(db.f_unaccent(f'%{qw}%'))))
             if place.level > 0:
-                found_places_q = found_places_q.join(db.RegionDescendant, and_(db.RegionDescendant.region == place.place_id,
-                                                                               db.RegionDescendant.descendant == db.Place.place_id))
-        found_places = (found_places_q
-                        .options(joinedload(db.Place.parent_place))
-                        .order_by(db.Place.level, db.Place.name, db.Place.place_id)
-                        .limit(max_places)
-                        .all())
-
-        if not found_places:
-            search_failed = True
-        if len(found_places) == 1:
-            return redirect(url_for('org_place', id=found_places[0].place_id))
-        else:
-            search_limited = len(found_places) >= max_places
+                place_q = place_q.join(db.RegionDescendant, and_(db.RegionDescendant.region == place.place_id,
+                                                                 db.RegionDescendant.descendant == db.Place.place_id))
+            found_places = (place_q
+                            .options(joinedload(db.Place.parent_place))
+                            .order_by(db.Place.level, db.Place.name, db.Place.place_id)
+                            .limit(max_places)
+                            .all())
+
+            if not found_places:
+                search_failed = True
+            if len(found_places) == 1:
+                flash('Nalezeno toto místo', 'info')
+                return redirect(url_for('org_place', id=found_places[0].place_id))
+            else:
+                search_limited = len(found_places) >= max_places
 
     if place.type == db.PlaceType.school:
         school = sess.query(db.School).get(place.place_id)
diff --git a/mo/web/templates/org_place.html b/mo/web/templates/org_place.html
index fc058c51..5c4a8b80 100644
--- a/mo/web/templates/org_place.html
+++ b/mo/web/templates/org_place.html
@@ -36,7 +36,7 @@
 {% endif %}
 	</div>
 
-<h3>Vyhledávání</h3>
+<h3>Vyhledávání míst{% if place.level > 0 %} v této oblasti{% endif %}</h3>
 
 {% if search_failed %}
 <div class='alert alert-danger' role='alert'>
-- 
GitLab