From 19444b3b1c3d80b860d9d749942b7d2558950bcb Mon Sep 17 00:00:00 2001 From: Filipp Lepalaan Date: Wed, 11 Nov 2015 15:43:55 +0200 Subject: Refactored searches into separate module --- servo/views/customer.py | 72 +++------- servo/views/device.py | 178 +---------------------- servo/views/invoices.py | 16 +-- servo/views/note.py | 22 +-- servo/views/order.py | 49 +------ servo/views/product.py | 37 +---- servo/views/search.py | 366 ++++++++++++++++++++++++++++-------------------- 7 files changed, 246 insertions(+), 494 deletions(-) (limited to 'servo/views') 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) -- cgit v1.2.3