aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFilipp Lepalaan <filipp@mac.com>2015-11-11 15:43:55 +0200
committerFilipp Lepalaan <filipp@mac.com>2015-11-11 15:43:55 +0200
commit19444b3b1c3d80b860d9d749942b7d2558950bcb (patch)
tree0942f5e005b7f607ee64d73978a6cf7912945adc
parentf51bc293756243e6880a1419a82fb51ea1733a30 (diff)
downloadServo-19444b3b1c3d80b860d9d749942b7d2558950bcb.tar.gz
Servo-19444b3b1c3d80b860d9d749942b7d2558950bcb.tar.bz2
Servo-19444b3b1c3d80b860d9d749942b7d2558950bcb.zip
Refactored searches into separate module
-rwxr-xr-xservo/templates/customers/search.html6
-rwxr-xr-xservo/templates/default.html3
-rwxr-xr-xservo/templates/devices/search_gsx.html51
-rwxr-xr-xservo/templates/devices/search_gsx_parts.html46
-rwxr-xr-xservo/templates/devices/search_gsx_results.html8
-rwxr-xr-xservo/templates/devices/view.html2
-rwxr-xr-xservo/templates/search/results/gsx_results.html2
-rwxr-xr-xservo/templates/search/spotlight.html41
-rw-r--r--servo/templatetags/servo_tags.py7
-rw-r--r--servo/urls/customer.py22
-rw-r--r--servo/urls/default.py1
-rw-r--r--servo/urls/device.py11
-rw-r--r--servo/urls/note.py1
-rw-r--r--servo/urls/order.py1
-rw-r--r--servo/urls/products.py21
-rw-r--r--servo/urls/sales.py1
-rw-r--r--servo/urls/search.py28
-rw-r--r--servo/views/customer.py72
-rw-r--r--servo/views/device.py178
-rw-r--r--servo/views/invoices.py16
-rw-r--r--servo/views/note.py22
-rw-r--r--servo/views/order.py49
-rw-r--r--servo/views/product.py37
-rw-r--r--servo/views/search.py366
24 files changed, 357 insertions, 635 deletions
diff --git a/servo/templates/customers/search.html b/servo/templates/customers/search.html
index 53b416b..3fecaa4 100755
--- a/servo/templates/customers/search.html
+++ b/servo/templates/customers/search.html
@@ -12,9 +12,9 @@
{% block first_column %}
<ul class="nav nav-list">
<li class="nav-header">{% trans "Show" %}</li>
- <li{% if not kind %} class="active"{% endif %}><a href="{% url 'customers-search' %}?q={{ query }}">{% trans "All" %}</a></li>
- <li{% if kind == 'company' %} class="active"{% endif %}><a href="{% url 'customers-search' %}?q={{ query }}&amp;kind=company">{% trans "Companies" %}</a></li>
- <li{% if kind == 'contact' %} class="active"{% endif %}><a href="{% url 'customers-search' %}?q={{ query }}&amp;kind=contact">{% trans "People" %}</a></li>
+ <li{% if not kind %} class="active"{% endif %}><a href="{% url 'search-customers' %}?q={{ query }}">{% trans "All" %}</a></li>
+ <li{% if kind == 'company' %} class="active"{% endif %}><a href="{% url 'search-customers' %}?q={{ query }}&amp;kind=company">{% trans "Companies" %}</a></li>
+ <li{% if kind == 'contact' %} class="active"{% endif %}><a href="{% url 'search-customers' %}?q={{ query }}&amp;kind=contact">{% trans "People" %}</a></li>
</ul>
{% endblock first_column %}
diff --git a/servo/templates/default.html b/servo/templates/default.html
index adcc592..8a62a4a 100755
--- a/servo/templates/default.html
+++ b/servo/templates/default.html
@@ -40,8 +40,9 @@
<li class="{% active request '^stats' %}"><a href="{% url 'stats-index' %}"><i class="halflings stats white"></i> {% trans "Statistics" %}</a></li>
</ul>
<div class="nav-collapse collapse">
- <form class="navbar-search pull-right" method="get" action="{{ request|search_url }}">
+ <form class="navbar-search pull-right" method="get" action="{% url 'search-spotlight' %}">
<input type="text" class="search-query" name="q" placeholder="{% trans "Search" %}" autocomplete="off" value="{{ request.session.search_query }}" id="toolbar-search" autofocus/>
+ <input type="hidden" name="hint" value="{{ search_hint|default:'orders' }}"/>
</form>
</div>
</div>
diff --git a/servo/templates/devices/search_gsx.html b/servo/templates/devices/search_gsx.html
index 4f06b81..007befe 100755
--- a/servo/templates/devices/search_gsx.html
+++ b/servo/templates/devices/search_gsx.html
@@ -3,39 +3,38 @@
{% block second_column %}
{% block tabs %}
- <ul class="nav nav-tabs" id="gsx-tabs">
- {% if param == 'serialNumber' or param == 'alternateDeviceId' %}
- <li><a href="{% url 'devices-search_gsx' 'warranty' param query %}">{% trans "Device" %}</a></li>
- {% else %}
- <li class="disabled"><a href="#">{% trans "Device" %}</a></li>
- {% endif %}
- {% if param == 'serialNumber' or param == 'alternateDeviceId' %}
- <li><a href="{% url 'devices-search_gsx' 'orders' param query %}">{% trans "Orders" %}</a></li>
- {% else %}
- <li class="disabled"><a href="#">{% trans "Orders" %}</a></li>
- {% endif %}
- {% if param == 'serialNumber' or param == 'partNumber' %}
- <li><a href="{% url 'devices-search_gsx' 'parts' param query %}">{% trans "Parts" %}</a></li>
- {% else %}
- <li class="disabled"><a href="#">{% trans "Parts" %}</a></li>
- {% endif %}
- {% if param == 'serialNumber' or param == 'dispatchId' %}
- <li><a href="{% url 'devices-search_gsx' 'repairs' param query %}">{% trans "Repairs" %}</a></li>
- {% else %}
- <li class="disabled"><a href="#">{% trans "Repairs" %}</a></li>
- {% endif %}
- </ul>
+<ul class="nav nav-tabs" id="gsx-tabs">
+{% if param == 'serialNumber' or param == 'alternateDeviceId' %}
+ <li><a href="{% url 'search-search_gsx' 'warranty' param query %}">{% trans "Device" %}</a></li>
+{% else %}
+ <li class="disabled"><a href="#">{% trans "Device" %}</a></li>
+{% endif %}
+{% if param == 'serialNumber' or param == 'alternateDeviceId' %}
+ <li><a href="{% url 'search-search_gsx' 'orders' param query %}">{% trans "Orders" %}</a></li>
+ {% else %}
+ <li class="disabled"><a href="#">{% trans "Orders" %}</a></li>
+ {% endif %}
+ {% if param == 'serialNumber' or param == 'partNumber' %}
+ <li><a href="{% url 'search-search_gsx' 'parts' param query %}">{% trans "Parts" %}</a></li>
+ {% else %}
+ <li class="disabled"><a href="#">{% trans "Parts" %}</a></li>
+ {% endif %}
+ {% if param == 'serialNumber' or param == 'dispatchId' %}
+ <li><a href="{% url 'search-search_gsx' 'repairs' param query %}">{% trans "Repairs" %}</a></li>
+ {% else %}
+ <li class="disabled"><a href="#">{% trans "Repairs" %}</a></li>
+ {% endif %}
+</ul>
{% endblock tabs %}
{% block results %}
- {% include "devices/search_gsx_results.html" %}
+ {% include "devices/search_gsx_results.html" %}
{% endblock results %}
-
{% endblock second_column %}
{% block media %}
<script type="text/javascript">
- var loc = location.pathname + location.search;
- $('#gsx-tabs>li>a[href="'+loc+'"]').parent().addClass('active');
+ var loc = location.pathname + location.search;
+ $('#gsx-tabs>li>a[href="'+loc+'"]').parent().addClass('active');
</script>
{% endblock media %}
diff --git a/servo/templates/devices/search_gsx_parts.html b/servo/templates/devices/search_gsx_parts.html
index 63bfdb9..48ba7a7 100755
--- a/servo/templates/devices/search_gsx_parts.html
+++ b/servo/templates/devices/search_gsx_parts.html
@@ -3,28 +3,28 @@
{% autoescape on %}
{% for p in results %}
- <tr>
- <td><a href="{% url 'products-view_product' code=p.code %}">{{ p.code }}</a></td>
- <td>{{ p.title }}<br/><span class="muted small" title="{{ p.eee_code }}">{{ p.eee_code|truncatechars:40 }}</td>
- <td>{{ p.price_sales_exchange|currency }}</td>
- <td>{{ p.price_sales_stock|currency }}</td>
- <td>0</td>
- <td>
- <div class="btn-group pull-right">
- <a class="btn dropdown-toggle" data-toggle="dropdown" href="#">
- <i class="icon-cog"></i> <span class="caret"></span>
- </a>
- <ul class="dropdown-menu">
- <li{% if not perms.servo.add_product %} class="disabled"{% endif %}>
- {% if device %}
- <a href="{% url 'products-create' group=device.get_product_category code=p.code %}">{% trans "Create Product" %}</a>
- {% else %}
- <a href="{% url 'products-create' code=p.code %}">{% trans "Create Product" %}</a>
- {% endif %}
- </li>
- </ul>
- </div>
- </td>
- </tr>
+<tr>
+ <td><a href="{% url 'products-view_product' code=p.code %}">{{ p.code }}</a></td>
+ <td>{{ p.title }}<br/><span class="muted small" title="{{ p.eee_code }}">{{ p.eee_code|truncatechars:40 }}</td>
+ <td>{{ p.price_sales_exchange|currency }}</td>
+ <td>{{ p.price_sales_stock|currency }}</td>
+ <td>0</td>
+ <td>
+ <div class="btn-group pull-right">
+ <a class="btn dropdown-toggle" data-toggle="dropdown" href="#">
+ <i class="icon-cog"></i> <span class="caret"></span>
+ </a>
+ <ul class="dropdown-menu">
+ <li{% if not perms.servo.add_product %} class="disabled"{% endif %}>
+ {% if device %}
+ <a href="{% url 'products-create' group=device.get_product_category code=p.code %}">{% trans "Create Product" %}</a>
+ {% else %}
+ <a href="{% url 'products-create' code=p.code %}">{% trans "Create Product" %}</a>
+ {% endif %}
+ </li>
+ </ul>
+ </div>
+ </td>
+</tr>
{% endfor %}
{% endautoescape %}
diff --git a/servo/templates/devices/search_gsx_results.html b/servo/templates/devices/search_gsx_results.html
index b7a0926..df92660 100755
--- a/servo/templates/devices/search_gsx_results.html
+++ b/servo/templates/devices/search_gsx_results.html
@@ -1,5 +1,5 @@
-<div id="gsx-container" data-source="{% url 'devices-get_gsx_search_results' what param query %}">
- <div class="progress active">
- <div class="bar" style="width:1%;" data-progress="0"></div>
- </div>
+<div id="gsx-container" data-source="{% url 'search-get_gsx_search_results' what param query %}">
+ <div class="progress active">
+ <div class="bar" style="width:1%;" data-progress="0"></div>
+ </div>
</div>
diff --git a/servo/templates/devices/view.html b/servo/templates/devices/view.html
index fd6d3a9..51a30c1 100755
--- a/servo/templates/devices/view.html
+++ b/servo/templates/devices/view.html
@@ -66,7 +66,7 @@
</div>
{% if device.is_apple_device %}
<div class="tab-pane" id="tab3">
- <div id="gsx-container" data-source="{% url 'devices-search_gsx' what='repairs' param='serialNumber' query=device.sn %}">
+ <div id="gsx-container" data-source="{% url 'search-search_gsx' what='repairs' param='serialNumber' query=device.sn %}">
<div class="progress active">
<div class="bar" style="width:100%;" data-progress="0"></div>
</div>
diff --git a/servo/templates/search/results/gsx_results.html b/servo/templates/search/results/gsx_results.html
index dc7fff5..0e4c890 100755
--- a/servo/templates/search/results/gsx_results.html
+++ b/servo/templates/search/results/gsx_results.html
@@ -1,4 +1,4 @@
-<div id="gsx-container" data-source="{% url 'search-search_gsx' what=what arg=arg value=value %}">
+<div id="gsx-container" data-source="{% url 'search-get_gsx_search_results' what=what arg=arg value=value %}">
<div class="progress active">
<div class="bar" style="width:1%;" data-progress="0"></div>
</div>
diff --git a/servo/templates/search/spotlight.html b/servo/templates/search/spotlight.html
index 3b3715c..f18eb43 100755
--- a/servo/templates/search/spotlight.html
+++ b/servo/templates/search/spotlight.html
@@ -3,35 +3,32 @@
{% load i18n %}
{% block toolbar %}
- <a href="{% url 'customers-create_customer' group='all' %}?name={{ query }}" class="btn btn-inverse"><i class="icon-plus icon-white"></i> {% trans "New Customer" %}</a>
{% endblock toolbar %}
{% block first_column %}
-<ul class="nav nav-list">
- <li class="nav-header">{% trans "Results" %}</li>
- <li class="{% active request 'search/customers' %}">
- <a href="/search/customers/?q={{ query }}">{% trans "Customers" %}</a>
- </li>
- <li class="{% active request 'search/devices' %}">
- <a href="/search/devices/?q={{ query }}">{% trans "Devices" %}</a>
- </li>
- <li class="{% active request 'search/gsx' %}">
- <a href="/search/gsx/{{ what }}?q={{ query }}">{% trans "GSX" %}</a>
- </li>
- <li class="{% active request 'search/orders' %}">
- <a href="/search/orders/?q={{ query }}">{% trans "Orders" %}</a>
- </li>
- <li class="{% active request 'search/products' %}">
- <a href="/search/products/?q={{ query }}">{% trans "Products and Parts" %}</a>
- </li>
- <li class="{% active request 'search/notes' %}"><a href="/search/notes/?q={{ query }}">{% trans "Notes" %}</a></li>
- <li class="{% active request 'search/articles' %}"><a href="/search/articles/?q={{ query }}">{% trans "Articles" %}</a></li>
-</ul>
{% endblock first_column %}
{% block second_column %}
+<ul class="nav nav-tabs">
+ <li class="active">
+ <a href="{% url 'search-customers' %}?q={{ query }}">{% trans "Customers" %}</a>
+ </li>
+ <li class="{% active request 'search/devices' %}">
+ <a href="{% url 'search-devices' %}?q={{ query }}">{% trans "Devices" %}</a>
+ </li>
+ <li class="{% active request 'search/gsx' %}">
+ <a href="/search/gsx/{{ what }}?q={{ query }}">{% trans "GSX" %}</a>
+ </li>
+ <li class="{% active request 'search/orders' %}">
+ <a href="{% url 'search-orders' %}?q={{ query }}">{% trans "Orders" %}</a>
+ </li>
+ <li class="{% active request 'search/products' %}">
+ <a href="{% url 'search-products' %}?q={{ query }}">{% trans "Products and Parts" %}</a>
+ </li>
+ <li class="{% active request 'search/notes' %}"><a href="/search/notes/?q={{ query }}">{% trans "Notes" %}</a></li>
+</ul>
{% endblock second_column %}
{% block footer %}
- <li><i class="icon-home"></i> <a href="{% url 'accounts-list_orders' %}">{% trans "Home" %}</a> <span class="divider">/</span></li><li class="active">{{ title }}</li>
+ <li><i class="icon-home"></i> <a href="{% url 'accounts-list_orders' %}">{% trans "Home" %}</a> <span class="divider">/</span></li><li class="active">{{ title }}</li>
{% endblock footer %}
diff --git a/servo/templatetags/servo_tags.py b/servo/templatetags/servo_tags.py
index 2b25e04..72cb7b0 100644
--- a/servo/templatetags/servo_tags.py
+++ b/servo/templatetags/servo_tags.py
@@ -44,13 +44,6 @@ def count_or_empty(queryset):
@register.filter
-def search_url(request):
- "Returns the proper search URL"
- prefix = request.path.split("/")[1]
- return "/%s/search/" % prefix
-
-
-@register.filter
def str_find(string, substr):
return (string.find(substr) > -1)
diff --git a/servo/urls/customer.py b/servo/urls/customer.py
index f029325..9665aaf 100644
--- a/servo/urls/customer.py
+++ b/servo/urls/customer.py
@@ -6,24 +6,30 @@ urlpatterns = patterns(
"servo.views.customer",
url(r'^$', 'index', {'group': 'all'}, name="customers-list_all"),
url(r'^find/$', 'find', name="customers-find"),
- url(r'^search/$', 'search', name="customers-search"),
url(r'^filter/$', 'filter', name="customers-filter"),
url(r'^download/$', 'download', name="customers-download"),
url(r'^download/(?P<group>[\w\-]+)/$', 'download', name="customers-download"),
url(r'^find/download$', 'download', name="customers-download_search"),
url(r'^groups/add/$', 'edit_group', name="customers-create_group"),
- url(r'^groups/(?P<group>[\w\-]+)/edit/$', 'edit_group', name="customers-edit_group"),
- url(r'^groups/(?P<group>[\w\-]+)/delete/$', 'delete_group', name="customers-delete_group"),
+ url(r'^groups/(?P<group>[\w\-]+)/edit/$', 'edit_group',
+ name="customers-edit_group"),
+ url(r'^groups/(?P<group>[\w\-]+)/delete/$', 'delete_group',
+ name="customers-delete_group"),
url(r'^(?P<group>[\w\-]+)/$', 'index', name="customers-list"),
url(r'^(?P<group>[\w\-]+)/upload/$', 'upload', name="customers-upload"),
url(r'^(?P<group>[\w\-]+)/add/$', 'edit', name="customers-create_customer"),
- url(r'^(?P<group>[\w\-]+)/(?P<pk>\d+)/$', 'view', name="customers-view_customer"),
- url(r'^(?P<group>[\w\-]+)/(?P<pk>\d+)/edit/$', 'edit', name="customers-edit_customer"),
- url(r'^(?P<group>[\w\-]+)/(?P<pk>\d+)/delete/$', 'delete', name="customers-delete_customer"),
+ url(r'^(?P<group>[\w\-]+)/(?P<pk>\d+)/$', 'view',
+ name="customers-view_customer"),
+ url(r'^(?P<group>[\w\-]+)/(?P<pk>\d+)/edit/$', 'edit',
+ name="customers-edit_customer"),
+ url(r'^(?P<group>[\w\-]+)/(?P<pk>\d+)/delete/$', 'delete',
+ name="customers-delete_customer"),
url(r'^(?P<pk>\d+)/move/$', 'move', name="customers-move_customer"),
- url(r'^(?P<pk>\d+)/move/(?P<new_parent>\d+)/$', 'move', name="customers-move_customer"),
+ url(r'^(?P<pk>\d+)/move/(?P<new_parent>\d+)/$', 'move',
+ name="customers-move_customer"),
url(r'^(?P<pk>\d+)/merge/$', 'merge', name="customers-merge_customer"),
- url(r'^(?P<pk>\d+)/merge/(?P<target>\d+)/$', 'merge', name="customers-merge_customer"),
+ url(r'^(?P<pk>\d+)/merge/(?P<target>\d+)/$', 'merge',
+ name="customers-merge_customer"),
url(r'^(?P<parent_id>\d+)/new/$', 'edit', name="customers-create_contact"),
url(r'^(\d+)/orders/(\d+)/$', 'add_order', name="customers-add_to_order"),
url(r'^(?P<pk>\d+)/notes/$', 'notes', name="customers-list_notes"),
diff --git a/servo/urls/default.py b/servo/urls/default.py
index 35c1f05..d70d295 100644
--- a/servo/urls/default.py
+++ b/servo/urls/default.py
@@ -49,5 +49,6 @@ urlpatterns = patterns(
(r'^kaboom/$', 'servo.views.error.report'),
url(r'^home/', include('servo.urls.account')),
+ url(r'^search/', include('servo.urls.search')),
)
diff --git a/servo/urls/device.py b/servo/urls/device.py
index defef62..04839dc 100644
--- a/servo/urls/device.py
+++ b/servo/urls/device.py
@@ -4,7 +4,6 @@ from django.conf.urls import patterns, url
from django.views.decorators.cache import cache_page
from servo.views.order import create
-from servo.views.device import get_gsx_search_results
from servo.views.diagnostics import diagnostics, select_test, run_test
@@ -12,7 +11,6 @@ urlpatterns = patterns(
"servo.views.device",
url(r'^$', 'index', name="devices-list"),
- url(r'^search/$', 'search'),
url(r'^find/$', "find", name="devices-find"),
url(r'^add/$', "edit_device", name="devices-add"),
@@ -27,14 +25,6 @@ urlpatterns = patterns(
url(r'^(?P<pk>\d+)/orders/(?P<order_id>\d+)/queue/(?P<queue_id>\d+)/parts/$',
"parts", name="devices-parts"),
- url(r'^search/gsx/(?P<what>\w+)/(?P<param>\w+)/(?P<query>[~\w\s,\-\(\)/\.]+)/$',
- "search_gsx",
- name="devices-search_gsx"),
-
- url(r'^search/gsx/(?P<what>\w+)/(?P<param>\w+)/(?P<query>[~\w\s,\-\(\)/\.]+)/$',
- cache_page(60*15)(get_gsx_search_results),
- name="devices-get_gsx_search_results"),
-
url(r'^choose/order/(\d+)/$', 'choose', name="devices-choose"),
url(r'^upload/$', 'upload_devices', name="devices-upload_devices"),
url(r'^(?P<device_id>\d+)/orders/create/$', create,
@@ -58,5 +48,4 @@ urlpatterns = patterns(
"delete_device",
name="devices-delete_device"),
- url(r'^search$', 'search', name="devices-search"),
)
diff --git a/servo/urls/note.py b/servo/urls/note.py
index 4057f40..0e1b65c 100644
--- a/servo/urls/note.py
+++ b/servo/urls/note.py
@@ -5,7 +5,6 @@ from django.conf.urls import patterns, url
urlpatterns = patterns(
"servo.views.note",
url(r'^$', 'list_notes', name="notes-list_notes"),
- url(r'^search/$', 'search', name="notes-search"),
url(r'^find/$', 'find', name="notes-find"),
url(r'^templates/$', 'templates'),
diff --git a/servo/urls/order.py b/servo/urls/order.py
index 39badfa..c2a49a6 100644
--- a/servo/urls/order.py
+++ b/servo/urls/order.py
@@ -12,7 +12,6 @@ urlpatterns = patterns(
url(r'^$', 'list_orders', name='orders-index'),
url(r'^\?queue=(?P<queue>\d+)$', 'list_orders', name='orders-list_queue'),
- url(r'^search/$', 'search', name="orders-search"),
url(r'^batch/$', 'batch_process', name="orders-batch_process"),
url(r'^download/$', 'download_results', name="orders-download_results"),
diff --git a/servo/urls/products.py b/servo/urls/products.py
index 9de2575..9c60baa 100644
--- a/servo/urls/products.py
+++ b/servo/urls/products.py
@@ -12,20 +12,18 @@ urlpatterns = patterns(
url(r'^upload/parts/$', "upload_gsx_parts", name="products-upload_gsx_parts"),
url(r'^update_price/(\d+)/$', "update_price", name="products-update_price"),
- url(r'^all/(?P<pk>\d+)/$', "view_product", {'group': 'all'}, name="products-view_product"),
+ url(r'^all/(?P<pk>\d+)/$', "view_product", {'group': 'all'},
+ name="products-view_product"),
url(r'^(?P<group>[\w\-/]*)/(?P<pk>\d+)/view/$', "view_product",
name="products-view_product"),
# Editing product categories
url(r'^categories/create/$', "edit_category", name="products-create_category"),
- url(r'^categories/(?P<slug>[\w\-]+)/edit/$',
- "edit_category",
+ url(r'^categories/(?P<slug>[\w\-]+)/edit/$', "edit_category",
name="products-edit_category"),
- url(r'^categories/(?P<slug>[\w\-]+)/delete/$',
- "delete_category",
+ url(r'^categories/(?P<slug>[\w\-]+)/delete/$', "delete_category",
name="products-delete_category"),
- url(r'^categories/(?P<parent_slug>[\w\-]+)/create/$',
- "edit_category",
+ url(r'^categories/(?P<parent_slug>[\w\-]+)/create/$', "edit_category",
name="products-create_category"),
# Editing products
@@ -37,15 +35,14 @@ urlpatterns = patterns(
name="products-delete_product"),
# Choosing a product for an order
- url(r'^choose/order/(?P<order_id>\d+)/$', "choose_product", name="products-choose"),
+ url(r'^choose/order/(?P<order_id>\d+)/$', "choose_product",
+ name="products-choose"),
url(r'^(?P<group>[\w\-]+)/(?P<code>[\w\-/]+)/create/$', "edit_product",
name="products-create"),
- url(r'^all/(?P<code>[\w\-/]+)/view/$',
- "view_product", {'group': 'all'},
+ url(r'^all/(?P<code>[\w\-/]+)/view/$', "view_product", {'group': 'all'},
name="products-view_product"),
- url(r'^(?P<code>[\w\-/]+)/new/$',
- "edit_product", {'group': None},
+ url(r'^(?P<code>[\w\-/]+)/new/$', "edit_product", {'group': None},
name="products-create"),
url(r'^code/(?P<code>[\w\-/]+)/location/(?P<location>\d+)/get_info/$',
diff --git a/servo/urls/sales.py b/servo/urls/sales.py
index 152a394..dd1d637 100644
--- a/servo/urls/sales.py
+++ b/servo/urls/sales.py
@@ -8,5 +8,4 @@ urlpatterns = patterns(
url(r'^purchases/', include('servo.urls.purchases')),
url(r'^shipments/', include('servo.urls.shipments')),
url(r'^invoices/', include('servo.urls.invoices')),
- url(r'^search/$', 'servo.views.product.search'),
)
diff --git a/servo/urls/search.py b/servo/urls/search.py
index 486bdcf..06278d6 100644
--- a/servo/urls/search.py
+++ b/servo/urls/search.py
@@ -3,27 +3,17 @@
from django.conf.urls import patterns, url
from django.views.decorators.cache import cache_page
-from servo.views.search import search_gsx
+from servo.views.search import search_gsx, get_gsx_search_results
urlpatterns = patterns(
"servo.views.search",
- url(r'^$', "spotlight",
- name="search-spotlight"),
- url(r'^gsx/(?P<what>\w+)/$', "list_gsx",
- name="search-gsx"),
- url(r'^gsx/(?P<what>\w+)/for/(?P<q>\w+)/$', "list_gsx",
- name="search-gsx"),
- # /search/gsx/parts/?productName=iPod+Shuffle...
- url(r'^gsx/(?P<what>\w+)/(?P<arg>\w+)/(?P<value>[~\w\s,\-\(\)/\.]+)/$',
- cache_page(60*15)(search_gsx),
+ url(r'^$', "spotlight", name="search-spotlight"),
+ url(r'^customers/$', "customers", name="search-customers"),
+ url(r'^devices/(?P<what>\w+)/(?P<param>\w+)/(?P<query>[~\w\s,\-\(\)/\.]+)/$',
+ "search_gsx",
name="search-search_gsx"),
- url(r'^gsx/(?P<what>\w+)/results/$', "view_gsx_results",
- name="search-gsx_results"),
- url(r'^notes/$', "list_notes"),
- url(r'^products/$', "list_products"),
- url(r'^orders/$', "list_orders"),
- url(r'^customers/$', "list_customers"),
- url(r'^devices/$', "list_devices"),
- url(r'^gsx/$', "list_gsx"),
- url(r'^articles/$', "list_articles"),
+ url(r'^gsx/(?P<what>\w+)/(?P<param>\w+)/(?P<query>[~\w\s,\-\(\)/\.]+)/$',
+ #cache_page(60*15)(get_gsx_search_results),
+ get_gsx_search_results,
+ name="search-get_gsx_search_results"),
)
diff --git a/servo/views/customer.py b/servo/views/customer.py
index 9adb3e5..1372419 100644
--- a/servo/views/customer.py
+++ b/servo/views/customer.py
@@ -10,7 +10,8 @@ from django.forms.models import modelform_factory
from django.utils.translation import ugettext as _
from django.contrib.auth.decorators import permission_required
from django.shortcuts import render, redirect, get_object_or_404
-from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
+
+from servo.lib.utils import paginate
from servo.models.note import Note
from servo.models.order import Order
@@ -29,6 +30,7 @@ def prepare_view(request, group='all'):
title = _("Customers")
customer_list = []
+ search_hint = "customers"
all_customers = Customer.objects.all().order_by('name')
customer_count = all_customers.count()
@@ -53,15 +55,7 @@ def prepare_view(request, group='all'):
title = g.name
page = request.GET.get('page')
- paginator = Paginator(customer_list, 40)
-
- try:
- customers = paginator.page(page)
- except PageNotAnInteger:
- customers = paginator.page(1)
- except EmptyPage:
- customers = paginator.page(paginator.num_pages)
-
+ customers = paginate(customer_list, page, 40)
groups = CustomerGroup.objects.all()
return locals()
@@ -80,8 +74,8 @@ def index(request, group='all'):
@permission_required("servo.change_order")
def add_order(request, customer_id, order_id):
- order = Order.objects.get(pk=order_id)
- customer = Customer.objects.get(pk=customer_id)
+ order = get_object_or_404(Order, pk=order_id)
+ customer = get_object_or_404(Customer, pk=customer_id)
order.customer = customer
order.save()
@@ -95,19 +89,14 @@ def add_order(request, customer_id, order_id):
def notes(request, pk, note_id=None):
from servo.forms.note import NoteForm
- customer = Customer.objects.get(pk=pk)
+ customer = get_object_or_404(Customer, pk=pk)
form = NoteForm(initial={'recipient': customer.name})
return render(request, "notes/form.html", {'form': form})
def view(request, pk, group='all'):
- try:
- c = Customer.objects.get(pk=pk)
- except Customer.DoesNotExist:
- messages.error(request, _('Customer not found'))
- return redirect(index)
-
+ c = get_object_or_404(Customer, pk=pk)
data = prepare_view(request, group)
data['title'] = c.name
@@ -150,7 +139,7 @@ def edit_group(request, group='all'):
@permission_required("servo.change_customer")
def delete_group(request, group):
- group = CustomerGroup.objects.get(slug=group)
+ group = get_object_or_404(CustomerGroup, slug=group)
if request.method == "POST":
group.delete()
@@ -178,7 +167,7 @@ def edit(request, pk=None, parent_id=None, group='all'):
form = CustomerForm(initial={'name': name})
if pk is not None:
- customer = Customer.objects.get(pk=pk)
+ customer = get_object_or_404(Customer, pk=pk)
form = CustomerForm(instance=customer)
if parent_id is not None:
@@ -233,7 +222,7 @@ def edit(request, pk=None, parent_id=None, group='all'):
@permission_required("servo.delete_customer")
def delete(request, pk=None, group='all'):
- customer = Customer.objects.get(pk=pk)
+ customer = get_object_or_404(Customer, pk=pk)
if request.method == "POST":
customer.delete()
@@ -254,7 +243,7 @@ def merge(request, pk, target=None):
- invoices
Deletes the source customer
"""
- customer = Customer.objects.get(pk=pk)
+ customer = get_object_or_404(Customer, pk=pk)
title = _('Merge %s with') % customer.name
if request.method == 'POST':
@@ -281,7 +270,7 @@ def move(request, pk, new_parent=None):
"""
Moves a customer under another customer
"""
- customer = Customer.objects.get(pk=pk)
+ customer = get_object_or_404(Customer, pk=pk)
if new_parent is not None:
if int(new_parent) == 0:
@@ -304,28 +293,6 @@ def move(request, pk, new_parent=None):
return render(request, "customers/move.html", locals())
-def search(request):
- """
- Searches for customers from "spotlight"
- """
- query = request.GET.get("q")
- kind = request.GET.get('kind')
- request.session['search_query'] = query
-
- customers = Customer.objects.filter(
- Q(fullname__icontains=query) | Q(email__icontains=query) | Q(phone__contains=query)
- )
-
- if kind == 'company':
- customers = customers.filter(is_company=True)
-
- if kind == 'contact':
- customers = customers.filter(is_company=False)
-
- title = _('%d results for "%s"') % (customers.count(), query)
- return render(request, "customers/search.html", locals())
-
-
def filter(request):
"""
Search for customers by name
@@ -380,14 +347,7 @@ def find(request):
title = _('Search for customers')
page = request.GET.get('page')
- paginator = Paginator(results, 50)
-
- try:
- customers = paginator.page(page)
- except PageNotAnInteger:
- customers = paginator.page(1)
- except EmptyPage:
- customers = paginator.page(paginator.num_pages)
+ customers = paginate(results, page, 50)
return render(request, "customers/find.html", locals())
@@ -430,7 +390,9 @@ def create_message(request, pk):
def upload(request, group='all'):
-
+ """
+ Uploads customer data in CSV format
+ """
action = request.path
form = CustomerUploadForm()
diff --git a/servo/views/device.py b/servo/views/device.py
index d828e47..f52af8f 100644
--- a/servo/views/device.py
+++ b/servo/views/device.py
@@ -11,8 +11,8 @@ from django.shortcuts import render, redirect, get_object_or_404
from django.utils.translation import ugettext as _
from django.template.defaultfilters import slugify
from django.views.decorators.cache import cache_page
-from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
+from servo.lib.utils import paginate
from servo.models import Device, Order, Product, GsxAccount, ServiceOrderItem
from servo.forms.devices import DeviceForm, DeviceUploadForm, DeviceSearchForm
@@ -46,6 +46,7 @@ def model_from_slug(product_line, model=None):
def prep_list_view(request, product_line=None, model=None):
title = _('Devices')
+ search_hint = "devices"
all_devices = Device.objects.all()
product_lines = gsxws.products.models()
@@ -66,15 +67,7 @@ def prep_list_view(request, product_line=None, model=None):
all_devices = all_devices.filter(slug=model)
page = request.GET.get('page')
- paginator = Paginator(all_devices, 50)
-
- try:
- devices = paginator.page(page)
- except PageNotAnInteger:
- devices = paginator.page(1)
- except EmptyPage:
- devices = paginator.page(paginator.num_pages)
-
+ devices = paginate(all_devices, page, 50)
return locals()
@@ -168,160 +161,6 @@ def view_device(request, pk, product_line=None, model=None):
return render(request, "devices/view.html", data)
-def get_gsx_search_results(request, what, param, query):
- """
- The second phase of a GSX search.
- There should be an active GSX session open at this stage.
- """
- data = {}
- results = []
- query = query.upper()
- device = Device(sn=query)
- error_template = "search/results/gsx_error.html"
-
- # @TODO: this isn't a GSX search. Move it somewhere else.
- if what == "orders":
- try:
- if param == 'serialNumber':
- device = Device.objects.get(sn__exact=query)
- if param == 'alternateDeviceId':
- device = Device.objects.get(imei__exact=query)
- except (Device.DoesNotExist, ValueError,):
- return render(request, "search/results/gsx_notfound.html")
-
- orders = device.order_set.all()
- return render(request, "orders/list.html", locals())
-
- if what == "warranty":
- # Update wty info if been here before
- try:
- device = Device.objects.get(sn__exact=query)
- device.update_gsx_details()
- except Exception:
- try:
- device = Device.from_gsx(query)
- except Exception as e:
- return render(request, error_template, {'message': e})
-
- results.append(device)
-
- # maybe it's a device we've already replaced...
- try:
- soi = ServiceOrderItem.objects.get(sn__iexact=query)
- results[0].repeat_service = soi.order
- except ServiceOrderItem.DoesNotExist:
- pass
-
- if what == "parts":
- # looking for parts
- if param == "partNumber":
- # ... with a part number
- part = gsxws.Part(partNumber=query)
-
- try:
- partinfo = part.lookup()
- except gsxws.GsxError, e:
- return render(request, error_template, {'message': e})
-
- product = Product.from_gsx(partinfo)
- cache.set(query, product)
- results.append(product)
-
- if param == "serialNumber":
- # ... with a serial number
- try:
- results = device.get_parts()
- data['device'] = device
- except Exception as e:
- return render(request, error_template, {'message': e})
-
- if param == "productName":
- product = gsxws.Product(productName=query)
- parts = product.parts()
- for p in parts:
- results.append(Product.from_gsx(p))
-
- if what == "repairs":
- # Looking for GSX repairs
- if param == "serialNumber":
- # ... with a serial number
- try:
- device = gsxws.Product(query)
- #results = device.repairs()
- # @TODO: move the encoding hack to py-gsxws
- for i, p in enumerate(device.repairs()):
- d = {'purchaseOrderNumber': p.purchaseOrderNumber}
- d['repairConfirmationNumber'] = p.repairConfirmationNumber
- d['createdOn'] = p.createdOn
- d['customerName'] = p.customerName.encode('utf-8')
- d['repairStatus'] = p.repairStatus
- results.append(d)
- except gsxws.GsxError, e:
- return render(request, "search/results/gsx_notfound.html")
-
- elif param == "dispatchId":
- # ... with a repair confirmation number
- repair = gsxws.Repair(number=query)
- try:
- results = repair.lookup()
- except gsxws.GsxError as message:
- return render(request, error_template, locals())
-
- return render(request, "devices/search_gsx_%s.html" % what, locals())
-
-
-def search_gsx(request, what, param, query):
- """
- The first phase of a GSX search
- """
- title = _(u'Search results for "%s"') % query
-
- try:
- act = request.session.get("gsx_account")
- act = None
- if act is None:
- GsxAccount.default(user=request.user)
- else:
- act.connect(request.user)
- except gsxws.GsxError as message:
- return render(request, "devices/search_gsx_error.html", locals())
-
- if request.is_ajax():
- if what == "parts":
- try:
- dev = Device.from_gsx(query)
- products = dev.get_parts()
- return render(request, "devices/parts.html", locals())
- except gsxws.GsxError as message:
- return render(request, "search/results/gsx_error.html", locals())
-
- return get_gsx_search_results(request, what, param, query)
-
- return render(request, "devices/search_gsx.html", locals())
-
-
-def search(request):
- """
- Searching for devices from the main navbar
- """
- query = request.GET.get("q", '').strip()
- request.session['search_query'] = query
-
- query = query.upper()
- valid_arg = gsxws.validate(query)
-
- if valid_arg in ('serialNumber', 'alternateDeviceId',):
- return redirect(search_gsx, "warranty", valid_arg, query)
-
- devices = Device.objects.filter(
- Q(sn__icontains=query) | Q(description__icontains=query)
- )
-
- title = _(u'Devices matching "%s"') % query
-
- return render(request, "devices/search.html", locals())
-
-
def find(request):
"""
Searching for device from devices/find
@@ -348,16 +187,9 @@ def find(request):
results = results.filter(created_at__range=[fdata['date_start'],
fdata['date_end']])
- paginator = Paginator(results, 100)
page = request.GET.get("page")
-
- try:
- devices = paginator.page(page)
- except PageNotAnInteger:
- devices = paginator.page(1)
- except EmptyPage:
- devices = paginator.page(paginator.num_pages)
-
+ devices = paginate(results, page, 100)
+
return render(request, "devices/find.html", locals())
diff --git a/servo/views/invoices.py b/servo/views/invoices.py
index 6b77c8b..639515c 100644
--- a/servo/views/invoices.py
+++ b/servo/views/invoices.py
@@ -7,8 +7,8 @@ from django.utils.translation import ugettext as _
from django.forms.models import inlineformset_factory
from django.contrib.auth.decorators import permission_required
from django.shortcuts import render, redirect, get_object_or_404
-from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
+from servo.lib.utils import paginate
from servo.forms.invoices import *
from servo.models import Order, Invoice, Payment, PurchaseOrder
@@ -57,24 +57,16 @@ def invoices(request):
if fdata.get('service_order'):
invoices = invoices.filter(order__code__exact=fdata['service_order'])
- page = request.GET.get('page')
data['total'] = invoices.aggregate(Sum('total_net'))
data['total_paid'] = invoices.exclude(paid_at=None).aggregate(Sum('total_net'))
pos = PurchaseOrder.objects.filter(created_at__range=[start_date, end_date])
data['total_purchases'] = pos.aggregate(Sum('total'))
- paginator = Paginator(invoices, 50)
-
- try:
- invoices = paginator.page(page)
- except PageNotAnInteger:
- invoices = paginator.page(1)
- except EmptyPage:
- invoices = paginator.page(paginator.num_pages)
-
+ page = request.GET.get('page')
data['form'] = form
data['invoices'] = invoices
-
+ data['invoices'] = paginate(invoices, page, 50)
+
return render(request, "invoices/index.html", data)
diff --git a/servo/views/note.py b/servo/views/note.py
index 4793e17..2ea6a14 100644
--- a/servo/views/note.py
+++ b/servo/views/note.py
@@ -81,6 +81,7 @@ def prep_list_view(request, kind):
data['kind'] = kind
data['notes'] = notes
+ data['search_hint'] = "notes"
data['inbox_count'] = Note.objects.filter(order=None).count()
return data
@@ -331,27 +332,6 @@ def view_note(request, kind, pk):
return render(request, "notes/view_note.html", data)
-def search(request):
- query = request.GET.get("q")
- request.session['search_query'] = query
-
- results = Note.objects.filter(body__icontains=query).order_by('-created_at')
- title = _(u'%d search results for "%s"') % (results.count(), query,)
-
- paginator = Paginator(results, 10)
-
- page = request.GET.get("page")
-
- try:
- notes = paginator.page(page)
- except PageNotAnInteger:
- notes = paginator.page(1)
- except EmptyPage:
- notes = paginator.page(paginator.num_pages)
-
- return render(request, "notes/search.html", locals())
-
-
def find(request):
form = NoteSearchForm(request.GET)
results = Note.objects.none()
diff --git a/servo/views/order.py b/servo/views/order.py
index 3c284fb..a12fec2 100644
--- a/servo/views/order.py
+++ b/servo/views/order.py
@@ -22,7 +22,8 @@ from django.shortcuts import render, redirect, get_object_or_404
from django.views.decorators.csrf import csrf_exempt
from django.contrib.auth.decorators import permission_required
-from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
+
+from servo.lib.utils import paginate
from servo.models.order import *
from servo.forms.orders import *
@@ -137,18 +138,10 @@ def prepare_list_view(request, args):
orders = orders.filter(status_limit_yellow__lte=now)
page = request.GET.get("page")
- paginator = Paginator(orders.distinct(), 100)
-
- try:
- order_pages = paginator.page(page)
- except PageNotAnInteger:
- order_pages = paginator.page(1)
- except EmptyPage:
- order_pages = paginator.page(paginator.num_pages)
data['form'] = form
data['queryset'] = orders
- data['orders'] = order_pages
+ data['orders'] = paginate(orders.distinct(), page, 100)
data['subtitle'] = _("%d search results") % orders.count()
return data
@@ -888,43 +881,9 @@ def remove_customer(request, pk, customer_id):
return render(request, "orders/remove_customer.html", data)
-def search(request):
- query = request.GET.get("q")
-
- if not query or len(query) < 3:
- messages.error(request, _('Search query is too short'))
- return redirect(list_orders)
-
- request.session['search_query'] = query
-
- # Redirect Order ID:s to the order
- try:
- order = Order.objects.get(code__iexact=query)
- return redirect(order)
- except Order.DoesNotExist:
- pass
-
- orders = Order.objects.filter(
- Q(code=query) | Q(devices__sn__contains=query) |
- Q(customer__fullname__icontains=query) |
- Q(customer__phone__contains=query) |
- Q(repair__confirmation=query) |
- Q(repair__reference=query)
- )
-
- data = {
- 'title': _('Orders'),
- 'subtitle': _(u'%d results for "%s"') % (orders.count(), query)
- }
-
- data['orders'] = orders.distinct()
-
- return render(request, "orders/index.html", data)
-
-
@permission_required("servo.add_order")
def copy_order(request, pk):
- order = Order.objects.get(pk=pk)
+ order = get_object_or_404(Order, pk=pk)
new_order = order.duplicate(request.user)
return redirect(new_order)
diff --git a/servo/views/product.py b/servo/views/product.py
index 01f551b..53213e2 100644
--- a/servo/views/product.py
+++ b/servo/views/product.py
@@ -14,7 +14,7 @@ from django.forms.models import inlineformset_factory
from django.contrib.contenttypes.models import ContentType
from django.contrib.auth.decorators import permission_required
-from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
+from servo.lib.utils import paginate
from servo.models import (Attachment, TaggedItem,
Product, ProductCategory,
@@ -28,6 +28,7 @@ def prep_list_view(request, group='all'):
Prepares the product list view
"""
title = _("Products")
+ search_hint = "products"
all_products = Product.objects.all()
categories = ProductCategory.objects.all()
@@ -71,14 +72,7 @@ def prep_list_view(request, group='all'):
title += u" / %s" % group.title
page = request.GET.get("page")
- paginator = Paginator(all_products.distinct(), 25)
-
- try:
- products = paginator.page(page)
- except PageNotAnInteger:
- products = paginator.page(1)
- except EmptyPage:
- products = paginator.page(paginator.num_pages)
+ products = paginate(all_products.distinct(), page, 25)
return locals()
@@ -320,31 +314,6 @@ def delete_product(request, pk, group):
return render(request, 'products/remove.html', locals())
-def search(request):
-
- query = request.GET.get("q")
- request.session['search_query'] = query
-
- results = Product.objects.filter(
- Q(code__icontains=query) | Q(title__icontains=query) | Q(eee_code__icontains=query)
- )
-
- paginator = Paginator(results, 100)
- page = request.GET.get("page")
-
- try:
- products = paginator.page(page)
- except PageNotAnInteger:
- products = paginator.page(1)
- except EmptyPage:
- products = paginator.page(paginator.num_pages)
-
- title = _(u'Search results for "%s"') % query
- group = ProductCategory(title=_('All'), slug='all')
-
- return render(request, 'products/search.html', locals())
-
-
def view_product(request, pk=None, code=None, group=None):
product = Product()
diff --git a/servo/views/search.py b/servo/views/search.py
index 02eac99..30e1496 100644
--- a/servo/views/search.py
+++ b/servo/views/search.py
@@ -6,225 +6,283 @@ import gsxws
from django.db.models import Q
from django.core.cache import cache
from django.shortcuts import render, redirect
-from django.utils.translation import ugettext as _
from django.core.urlresolvers import reverse
+from django.utils.translation import ugettext as _
from django.http import QueryDict, HttpResponseRedirect
-from servo.models.note import Note
-from servo.models.wiki import Article
-from servo.models.device import Device
-from servo.models.product import Product
-from servo.models.common import GsxAccount
-from servo.models.purchases import PurchaseOrder
-from servo.models.order import Order, ServiceOrderItem
-
-
-def results_redirect(view, data):
- q = QueryDict('', mutable=True)
- q['q'] = data['query']
- query_str = q.urlencode()
- url = reverse(view, args=[data['what']])
- return HttpResponseRedirect("%s?%s" % (url, query_str))
-
-
-def prepare_result_view(request):
-
- query = request.GET.get('q')
-
- data = {'title': _('Search results for "%s"' % query)}
-
- data['gsx_type'] = gsxws.validate(query.upper())
- data['query'] = query
- data['tag_id'] = None
- data['cat_id'] = None # Product category
- data['group'] = 'all' # customer group
-
- return data, query
-
+from servo.lib.utils import paginate
+from servo.models import (Note, Device, Product,
+ GsxAccount, PurchaseOrder, Order,
+ ServiceOrderItem, Customer, ProductCategory,)
-def list_gsx(request, what="warranty"):
- data, query = prepare_result_view(request)
- data['what'] = what
- return render(request, "search/results/gsx.html", data)
+def search_gsx(request, what, param, query):
+ """
+ The first phase of a GSX search. Sets up the GSX connection.
+ """
+ title = _(u'Search results for "%s"') % query
-def search_gsx(request, what, arg, value):
- if request.is_ajax():
-
- if what == "parts" and value != "None":
- results = []
+ try:
+ act = request.session.get("gsx_account")
+ act = None
+ if act is None:
GsxAccount.default(user=request.user)
+ else:
+ act.connect(request.user)
+ except gsxws.GsxError as message:
+ return render(request, "devices/search_gsx_error.html", locals())
- try:
- product = gsxws.Product(productName=value)
- parts = product.parts()
- for p in parts:
- results.append(Product.from_gsx(p))
- except gsxws.GsxError, e:
- data = {'message': e}
- return render(request, "search/results/gsx_error.html", data)
-
- data = {'results': results}
-
- return render(request, "search/results/gsx_%s.html" % what, data)
+ if request.is_ajax():
+ return get_gsx_search_results(request, what, param, query)
- data = {arg: value}
- return render(request, "search/gsx_results.html", data)
+ return render(request, "devices/search_gsx.html", locals())
-def view_gsx_results(request, what="warranty"):
+def get_gsx_search_results(request, what, param, query):
"""
- Searches for something from GSX. Defaults to warranty lookup.
- GSX search strings are always UPPERCASE.
+ The second phase of a GSX search.
+ There should be an active GSX session open at this stage.
"""
- results = list()
- data, query = prepare_result_view(request)
- query = query.upper()
-
+ data = {}
+ results = []
+ query = query.upper()
+ device = Device(sn=query)
error_template = "search/results/gsx_error.html"
- if data['gsx_type'] == "dispatchId":
- what = "repairs"
-
- if data['gsx_type'] == "partNumber":
- what = "parts"
-
- data['what'] = what
- gsx_type = data['gsx_type']
-
- try:
- if request.session.get("current_queue"):
- queue = request.session['current_queue']
- GsxAccount.default(request.user, queue)
- else:
- GsxAccount.default(request.user)
- except gsxws.GsxError, e:
- error = {'message': e}
- return render(request, error_template, error)
-
- if gsx_type == "serialNumber" or "alternateDeviceId":
+ # @TODO: this isn't a GSX search. Move it somewhere else.
+ if what == "orders":
try:
- device = Device.objects.get(sn=query)
- except Device.DoesNotExist:
- device = Device(sn=query)
+ if param == 'serialNumber':
+ device = Device.objects.get(sn__exact=query)
+ if param == 'alternateDeviceId':
+ device = Device.objects.get(imei__exact=query)
+ except (Device.DoesNotExist, ValueError,):
+ return render(request, "search/results/gsx_notfound.html")
+
+ orders = device.order_set.all()
+ return render(request, "orders/list.html", locals())
if what == "warranty":
- if cache.get(query):
- result = cache.get(query)
- else:
+ # Update wty info if been here before
+ try:
+ device = Device.objects.get(sn__exact=query)
+ device.update_gsx_details()
+ except Exception:
try:
- result = Device.from_gsx(query)
- except gsxws.GsxError, e:
- error = {'message': e}
- return render(request, error_template, error)
+ device = Device.from_gsx(query)
+ except Exception as e:
+ return render(request, error_template, {'message': e})
- if re.match(r'iPhone', result.description):
- result.activation = device.get_activation()
+ results.append(device)
- results.append(result)
+ # maybe it's a device we've already replaced...
+ try:
+ soi = ServiceOrderItem.objects.get(sn__iexact=query)
+ results[0].repeat_service = soi.order
+ except ServiceOrderItem.DoesNotExist:
+ pass
if what == "parts":
# looking for parts
- if gsx_type == "partNumber":
+ if param == "partNumber":
# ... with a part number
part = gsxws.Part(partNumber=query)
try:
partinfo = part.lookup()
- except gsxws.GsxError, e:
- error = {'message': e}
- return render(request, error_template, error)
+ except gsxws.GsxError as e:
+ return render(request, error_template, {'message': e})
product = Product.from_gsx(partinfo)
cache.set(query, product)
results.append(product)
- else:
- # ... with a serial number
+
+ if param == "serialNumber":
try:
- results = device.get_parts()
- data['device'] = device
- except Exception, e:
- error = {'message': e}
- return render(request, error_template, error)
+ dev = Device.from_gsx(query)
+ products = dev.get_parts()
+ return render(request, "devices/parts.html", locals())
+ except gsxws.GsxError as message:
+ return render(request, "search/results/gsx_error.html", locals())
+
+ if param == "productName":
+ product = gsxws.Product(productName=query)
+ parts = product.parts()
+ for p in parts:
+ results.append(Product.from_gsx(p))
if what == "repairs":
# Looking for GSX repairs
- if gsx_type == "serialNumber":
+ if param == "serialNumber":
# ... with a serial number
try:
device = gsxws.Product(query)
- results = device.repairs()
- except gsxws.GsxError, e:
+ #results = device.repairs()
+ # @TODO: move the encoding hack to py-gsxws
+ for i, p in enumerate(device.repairs()):
+ d = {'purchaseOrderNumber': p.purchaseOrderNumber}
+ d['repairConfirmationNumber'] = p.repairConfirmationNumber
+ d['createdOn'] = p.createdOn
+ d['customerName'] = p.customerName.encode('utf-8')
+ d['repairStatus'] = p.repairStatus
+ results.append(d)
+ except gsxws.GsxError as e:
return render(request, "search/results/gsx_notfound.html")
- elif gsx_type == "dispatchId":
+ elif param == "dispatchId":
# ... with a repair confirmation number
repair = gsxws.Repair(number=query)
try:
results = repair.lookup()
- except gsxws.GsxError, e:
- error = {'message': e}
- return render(request, error_template, error)
+ except gsxws.GsxError as message:
+ return render(request, error_template, locals())
- if what == "repair_details":
- repair = gsxws.Repair(number=query)
- results = repair.details()
- return render(request, "search/results/gsx_repair_details.html", results)
+ return render(request, "devices/search_gsx_%s.html" % what, locals())
- # Cache the results for quicker access later
- cache.set('%s-%s' % (what, query), results)
- data['results'] = results
- return render(request, "search/results/gsx_%s.html" % what, data)
+def products(request):
+ """
+ Searches our local inventory
+ """
+ query = request.GET.get("q")
+ request.session['search_query'] = query
-def list_products(request):
- data, query = prepare_result_view(request)
- data['products'] = Product.objects.filter(
- Q(code__icontains=query) | Q(title__icontains=query)
+ results = Product.objects.filter(
+ Q(code__icontains=query) | Q(title__icontains=query) | Q(eee_code__icontains=query)
)
- return render(request, "search/results/products.html", data)
+ page = request.GET.get("page")
+ products = paginate(results, page, 50)
+ title = _(u'Search results for "%s"') % query
+ group = ProductCategory(title=_('All'), slug='all')
-def list_notes(request):
- data, query = prepare_result_view(request)
- data['notes'] = Note.objects.filter(body__icontains=query)
- return render(request, "search/results/notes.html", data)
+ return render(request, 'products/search.html', locals())
-def spotlight(request):
+def orders(request):
"""
- Searches for anything and redirects to the "closest" result view.
- GSX searches are done separately.
+ Searches local service orders
"""
- data, query = prepare_result_view(request)
- data['what'] = "warranty"
+ query = request.GET.get("q")
- if Order.objects.filter(customer__name__icontains=query).exists():
- return list_orders(request)
+ if not query or len(query) < 3:
+ messages.error(request, _('Search query is too short'))
+ return redirect(list_orders)
- if data['gsx_type'] == "serialNumber":
- try:
- device = Device.objects.get(sn=query)
- return redirect(device)
- except Device.DoesNotExist:
- return results_redirect("search-gsx", data)
+ request.session['search_query'] = query
- data['parts'] = ServiceOrderItem.objects.filter(sn__icontains=query)
+ # Redirect Order ID:s to the order
+ try:
+ order = Order.objects.get(code__iexact=query)
+ return redirect(order)
+ except Order.DoesNotExist:
+ pass
+
+ orders = Order.objects.filter(
+ Q(code=query) | Q(devices__sn__contains=query) |
+ Q(customer__fullname__icontains=query) |
+ Q(customer__phone__contains=query) |
+ Q(repair__confirmation=query) |
+ Q(repair__reference=query)
+ )
- if gsxws.validate(query, "dispatchId"):
- try:
- po = PurchaseOrder.objects.get(confirmation=query)
- data['orders'] = [po.sales_order]
- except PurchaseOrder.DoesNotExist:
- pass
+ data = {
+ 'title': _('Orders'),
+ 'subtitle': _(u'%d results for "%s"') % (orders.count(), query)
+ }
+
+ page = request.GET.get('page')
+ data['orders'] = paginate(orders.distinct(), page, 100)
+
+ return render(request, "orders/index.html", data)
+
+
+def customers(request):
+ """
+ Searches for customers from "spotlight"
+ """
+ query = request.GET.get("q")
+ kind = request.GET.get('kind')
+ request.session['search_query'] = query
+
+ customers = Customer.objects.filter(
+ Q(fullname__icontains=query) | Q(email__icontains=query) | Q(phone__contains=query)
+ )
+
+ if kind == 'company':
+ customers = customers.filter(is_company=True)
+
+ if kind == 'contact':
+ customers = customers.filter(is_company=False)
+
+ title = _('%d results for "%s"') % (customers.count(), query)
+
+ return render(request, "customers/search.html", locals())
+
+
+def devices(request):
+ """
+ Searching for devices from the main navbar
+ """
+ query = request.GET.get("q", '').strip()
+ request.session['search_query'] = query
+
+ query = query.upper()
+ valid_arg = gsxws.validate(query)
+
+ if valid_arg in ('serialNumber', 'alternateDeviceId',):
+ return redirect(search_gsx, "warranty", valid_arg, query)
- data['products'] = Product.objects.filter(
- Q(code__icontains=query) | Q(title__icontains=query)
+ devices = Device.objects.filter(
+ Q(sn__icontains=query) | Q(description__icontains=query)
)
- data['articles'] = Article.objects.filter(content__contains=query)
+ title = _(u'Devices matching "%s"') % query
+
+ return render(request, "devices/search.html", locals())
+
+
+def notes(request):
+ """
+ Searches for local notes
+ """
+ query = request.GET.get("q")
+ request.session['search_query'] = query
+
+ results = Note.objects.filter(body__icontains=query).order_by('-created_at')
+ title = _(u'%d search results for "%s"') % (results.count(), query,)
+ notes = paginate(results, request.GET.get('page'), 10)
+
+ return render(request, "notes/search.html", locals())
+
+
+def spotlight(request):
+ """
+ Searches for anything and redirects to the "closest" result view.
+ GSX searches are done separately.
+
+ To give good results, we must first "classify" the search query.
+ Some strings are easy to classify:
+ - serial numbers, repair confirmations, part numbers
+ Others, not so much:
+ - customer names, notes
+ """
+ hint = request.GET.get('hint')
+
+ if hint == 'orders':
+ return orders(request)
+
+ if hint == 'customers':
+ return customers(request)
+
+ if hint == 'devices':
+ return devices(request)
+
+ if hint == 'notes':
+ return notes(request)
- return render(request, "search/spotlight.html", data)
+ if hint == 'products':
+ return products(request)