aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFilipp Lepalaan <filipp@mac.com>2017-04-24 22:26:17 +0300
committerFilipp Lepalaan <filipp@mac.com>2017-04-24 22:26:17 +0300
commit85e92ff2ee4ca30e0144790a1d95b8023595bf2f (patch)
treeff38ef1fe1957e00732ab43f891b7915a7a97274
parent5934831e5921b78651418a589da3c67ed320a309 (diff)
downloadServo-85e92ff2ee4ca30e0144790a1d95b8023595bf2f.tar.gz
Servo-85e92ff2ee4ca30e0144790a1d95b8023595bf2f.tar.bz2
Servo-85e92ff2ee4ca30e0144790a1d95b8023595bf2f.zip
Cleanup
-rw-r--r--TODO.md3
-rw-r--r--servo/forms/admin.py2
-rw-r--r--servo/management/commands/backup.py50
-rw-r--r--servo/models/note.py5
-rwxr-xr-xservo/templates/accounts/login.html2
-rwxr-xr-xservo/templates/accounts/logout.html2
-rw-r--r--servo/templates/checkin/error.html7
-rw-r--r--servo/templates/checkin/index.html3
-rwxr-xr-xservo/templates/default.html20
-rwxr-xr-xservo/templates/default_print.html8
-rwxr-xr-xservo/templates/orders/edit.html2
-rwxr-xr-xservo/templates/orders/notes.html2
-rw-r--r--servo/tests/test_functional.py5
-rw-r--r--servo/views/account.py16
-rw-r--r--servo/views/checkin.py54
15 files changed, 96 insertions, 85 deletions
diff --git a/TODO.md b/TODO.md
index cd6ed02..1422131 100644
--- a/TODO.md
+++ b/TODO.md
@@ -1,5 +1,8 @@
- Move CSV generation to streamingoutput?
+- add order.unit_received_at
+- add order.customer_contacted_at
+- add
New checkin
===========
diff --git a/servo/forms/admin.py b/servo/forms/admin.py
index ec4ee56..d0c284a 100644
--- a/servo/forms/admin.py
+++ b/servo/forms/admin.py
@@ -295,7 +295,7 @@ class SettingsForm(BaseForm):
initial=True,
required=False,
label=_("Enable check-in interface"),
- help_text=_("Uncheck to disable the check-in interface")
+ help_text=_("Uncheck to disable the check-in interface completely")
)
checkin_user = forms.ModelChoiceField(
diff --git a/servo/management/commands/backup.py b/servo/management/commands/backup.py
index 9d63b27..28129e6 100644
--- a/servo/management/commands/backup.py
+++ b/servo/management/commands/backup.py
@@ -24,7 +24,7 @@ def write(path, header, cursor):
class Command(BaseCommand):
help = 'Export this servo database in a portable format'
-
+
def handle(self, *args, **options):
# creates a folder, then dumps different portable tables as separate
# files to it, then compresses the folder and deletes it
@@ -33,50 +33,50 @@ class Command(BaseCommand):
dirname = datetime.now().strftime('%Y%m%d-%H%M')
backupdir = os.path.join(settings.BACKUP_DIR, dirname)
-
+
if not os.path.exists(backupdir):
os.mkdir(backupdir)
path = os.path.join(backupdir, 'notes.csv')
cursor = connection.cursor()
- cursor.execute("""SELECT id, order_id, created_by_id, created_at, body
- FROM servo_note""")
+ cursor.execute("""SELECT id, order_id, created_by_id, created_at, body
+ FROM servo_note""")
header = ['ID', 'ORDER_ID', 'USER_ID', 'CREATED_AT', 'NOTE']
write(path, header, cursor)
path = os.path.join(backupdir, 'users.csv')
header = ['ID', 'USERNAME', 'FIRST_NAME', 'LAST_NAME', 'EMAIL']
- cursor.execute("""SELECT id, username, first_name, last_name, email
+ cursor.execute("""SELECT id, username, first_name, last_name, email
FROM servo_user WHERE is_visible = TRUE""")
write(path, header, cursor)
path = os.path.join(backupdir, 'orders.csv')
- header = ['ID', 'CODE', 'CREATED_AT',
- 'CLOSED_AT', 'CUSTOMER_ID', 'USER_ID', 'QUEUE_ID']
- cursor.execute("""SELECT id, code, created_at, closed_at,
+ header = ['ID', 'CODE', 'CREATED_AT',
+ 'CLOSED_AT', 'CUSTOMER_ID', 'USER_ID', 'QUEUE_ID']
+ cursor.execute("""SELECT id, code, created_at, closed_at,
customer_id, user_id, queue_id
FROM servo_order""")
write(path, header, cursor)
path = os.path.join(backupdir, 'queues.csv')
header = ['ID', 'NAME', 'DESCRIPTION',
- 'CLOSED_AT', 'CUSTOMER_ID', 'USER_ID', 'QUEUE_ID']
+ 'CLOSED_AT', 'CUSTOMER_ID', 'USER_ID', 'QUEUE_ID']
cursor.execute("""SELECT id, title, description FROM servo_queue""")
write(path, header, cursor)
path = os.path.join(backupdir, 'devices.csv')
header = ['ID', 'SERIAL_NUMBER', 'IMEI',
- 'CONFIGURATION', 'WARRANTY_STATUS', 'PURCHASE_DATE', 'NOTES']
+ 'CONFIGURATION', 'WARRANTY_STATUS', 'PURCHASE_DATE', 'NOTES']
cursor.execute("""SELECT id, sn, imei, configuration, warranty_status,
purchased_on, notes FROM servo_device""")
write(path, header, cursor)
path = os.path.join(backupdir, 'repairs.csv')
header = ['ID', 'ORDER_ID', 'DEVICE_ID', 'USER_ID',
- 'SUBMITTED_AT', 'COMPLETED_AT', 'REQUEST_REVIEW',
- 'TECH_ID', 'UNIT_RECEIVED', 'CONFIRMATION',
- 'REFERENCE', 'SYMPTOM', 'DIAGNOSIS', 'NOTES']
+ 'SUBMITTED_AT', 'COMPLETED_AT', 'REQUEST_REVIEW',
+ 'TECH_ID', 'UNIT_RECEIVED', 'CONFIRMATION',
+ 'REFERENCE', 'SYMPTOM', 'DIAGNOSIS', 'NOTES']
cursor.execute("""SELECT id, order_id, device_id,
created_by_id, submitted_at, completed_at,
request_review, tech_id, unit_received_at, confirmation, reference,
@@ -85,10 +85,10 @@ class Command(BaseCommand):
WHERE submitted_at IS NOT NULL""")
write(path, header, cursor)
- header = ['ID', 'CODE', 'TITLE', 'DESCRIPTION',
- 'PRICE_PURCHASE_EXCHANGE', 'PRICE_PURCHASE_STOCK',
- 'PRICE_SALES_EXCHANGE', 'PRICE_SALES_STOCK', 'COMPONENT_CODE',
- 'PART_TYPE', 'EEE_CODE']
+ header = ['ID', 'CODE', 'TITLE', 'DESCRIPTION',
+ 'PRICE_PURCHASE_EXCHANGE', 'PRICE_PURCHASE_STOCK',
+ 'PRICE_SALES_EXCHANGE', 'PRICE_SALES_STOCK', 'COMPONENT_CODE',
+ 'PART_TYPE', 'EEE_CODE']
cursor.execute("""SELECT id, code, title, description,
price_purchase_exchange, price_purchase_stock,
price_sales_exchange, price_sales_stock,
@@ -98,8 +98,8 @@ class Command(BaseCommand):
write(path, header, cursor)
header = ['ID', 'PARENT_ID', 'NAME', 'PHONE', 'EMAIL',
- 'STREET_ADDRESS', 'POSTAL_CODE', 'CITY'
- 'COUNTRY', 'NOTES']
+ 'STREET_ADDRESS', 'POSTAL_CODE', 'CITY'
+ 'COUNTRY', 'NOTES']
cursor.execute("""SELECT id, parent_id, name, phone,
email, street_address, zip_code, city, country, notes
FROM servo_customer""")
@@ -108,9 +108,9 @@ class Command(BaseCommand):
path = os.path.join(backupdir, 'order_products.csv')
header = ['ID', 'PRODUCT_ID', 'ORDER_ID', 'CODE', 'TITLE',
- 'DESCRIPTION', 'AMOUNT', 'SERIAL_NUMBER', 'KBB_SN',
- 'IMEI', 'REPORTED', 'PRICE_CATEGORY', 'PRICE'
- 'COMPTIA_CODE', 'COMPTIA_MODIFIER']
+ 'DESCRIPTION', 'AMOUNT', 'SERIAL_NUMBER', 'KBB_SN',
+ 'IMEI', 'REPORTED', 'PRICE_CATEGORY', 'PRICE'
+ 'COMPTIA_CODE', 'COMPTIA_MODIFIER']
cursor.execute("""SELECT id, product_id, order_id, code,
title, description, amount, sn, price, kbb_sn,
imei, should_report, price_category, price,
@@ -120,9 +120,9 @@ class Command(BaseCommand):
path = os.path.join(backupdir, 'parts.csv')
header = ['ID', 'REPAIR_ID', 'ORDER_ITEM_ID',
- 'NUMBER', 'TITLE', 'COMPTIA_CODE', 'COMPTIA_MODIFIER',
- 'RETURN_ORDER', 'RETURN_STATUS', 'RETURN_CODE',
- 'ORDER_STATUS', 'COVERAGE', 'SHIP_TO', 'RETURNED_AT']
+ 'NUMBER', 'TITLE', 'COMPTIA_CODE', 'COMPTIA_MODIFIER',
+ 'RETURN_ORDER', 'RETURN_STATUS', 'RETURN_CODE',
+ 'ORDER_STATUS', 'COVERAGE', 'SHIP_TO', 'RETURNED_AT']
cursor.execute("""SELECT id, repair_id, order_item_id,
part_number, part_title, comptia_code, comptia_modifier,
return_order, return_status, return_code,
diff --git a/servo/models/note.py b/servo/models/note.py
index 8b2943f..3f48282 100644
--- a/servo/models/note.py
+++ b/servo/models/note.py
@@ -112,7 +112,8 @@ class Note(MPTTModel):
is_reported = models.BooleanField(
default=False,
- verbose_name=_("Report")
+ verbose_name=_("Report"),
+ help_text=_('Show this note on the confirmation printout')
)
is_read = models.BooleanField(
default=True,
@@ -178,7 +179,7 @@ class Note(MPTTModel):
def zip_attachments(self):
pass
-
+
def get_default_sender(self):
return Configuration.get_default_sender(self.created_by)
diff --git a/servo/templates/accounts/login.html b/servo/templates/accounts/login.html
index 80ba716..ea71bcc 100755
--- a/servo/templates/accounts/login.html
+++ b/servo/templates/accounts/login.html
@@ -2,7 +2,7 @@
{% load i18n %}
{% block content %}
-<img src="{{ STATIC_URL }}images/logo_servoapp.png" class="servo-logo" alt=""/>
+<img src="{{ STATIC_URL }}images/logo_servoapp.png" class="servo-logo" alt="Servo Logo"/>
<form action="{% url "accounts-login" %}" method="post" accept-charset="utf-8">
{% csrf_token %}
<div class="input-prepend">
diff --git a/servo/templates/accounts/logout.html b/servo/templates/accounts/logout.html
index 1b64d45..3bb9f34 100755
--- a/servo/templates/accounts/logout.html
+++ b/servo/templates/accounts/logout.html
@@ -2,7 +2,7 @@
{% load i18n %}
{% block header %}
-{% trans "Logging out?" %}
+{% trans "Confirmation" %}
{% endblock header %}
{% block body %}
diff --git a/servo/templates/checkin/error.html b/servo/templates/checkin/error.html
index d21e91f..ee0ecc9 100644
--- a/servo/templates/checkin/error.html
+++ b/servo/templates/checkin/error.html
@@ -6,10 +6,11 @@
{% block main %}
<div class="container-narrow">
<div class="jumbotron">
- <img src="{{ STATIC_URL }}/images/sadmac.png"/>
- <p class="lead">{% trans "It appears that an error has occurred." %}</p>
+ <img src="{{ STATIC_URL }}/images/sadmac.png" alt="{% trans "An error occurred" %}" title="{% trans "An error occurred" %}"/>
+ <p class="lead">{% trans "An error occurred." %}</p>
<p>{{ message }}</p>
- <a class="btn btn-large btn-success" href="{% url 'checkin-index' %}"><i class="icon-refresh icon-white"></i> {% trans "Try again" %}</a>
+ <a class="btn btn-large btn-success" href="{{ url }}"><i class="glyphicon glyphicon-repeat"></i> {% trans "Try again" %}</a>
+ <a class="btn btn-large btn-default" href="{% url 'accounts-login' %}"><i class="icon-refresh icon-white"></i> {% trans "Return to login page" %}</a>
</div>
</div>
{% endblock main %}
diff --git a/servo/templates/checkin/index.html b/servo/templates/checkin/index.html
index c197d31..545825d 100644
--- a/servo/templates/checkin/index.html
+++ b/servo/templates/checkin/index.html
@@ -50,8 +50,7 @@
</li>
{% endif %}
</ul>
- </div><!--/.nav-collapse -->
- </div>
+ </div><!--/.nav-collapse -->
</div>
</div>
<div class="main container">
diff --git a/servo/templates/default.html b/servo/templates/default.html
index 139d083..363f3c8 100755
--- a/servo/templates/default.html
+++ b/servo/templates/default.html
@@ -1,21 +1,21 @@
{% load servo_tags %}
{% load humanize %}
-{% load cache %}
+{% load static %}
{% load i18n %}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
- <link rel="icon" type="image/png" href="{{ STATIC_URL }}images/favicon.png">
- <link rel="apple-touch-icon" type="image/png" href="{{ STATIC_URL }}images/apple-touch-icon.png">
- <link href="{{ STATIC_URL }}js/bootstrap/css/bootstrap.min.css" rel="stylesheet">
- <link href="{{ STATIC_URL }}js/bootstrap/css/bootstrap-responsive.min.css" rel="stylesheet">
- <link href="{{ STATIC_URL }}css/bootstrap-datetimepicker.min.css" rel="stylesheet">
- <link href="{{ STATIC_URL }}css/bootstrap-sortable.css" rel="stylesheet">
- <link href="{{ STATIC_URL }}css/glyphicons.css" rel="stylesheet">
- <link href="{{ STATIC_URL }}css/halflings.css" rel="stylesheet">
- <link href="{{ STATIC_URL }}css/servo.css" rel="stylesheet">
+ <link rel="icon" type="image/png" href="{% static "images/favicon.png" %}">
+ <link rel="apple-touch-icon" type="image/png" href="{% static "images/apple-touch-icon.png" %}">
+ <link href="{% static "js/bootstrap/css/bootstrap.min.css" %}" rel="stylesheet">
+ <link href="{% static "js/bootstrap/css/bootstrap-responsive.min.css" %}" rel="stylesheet">
+ <link href="{% static "css/bootstrap-datetimepicker.min.css" %}" rel="stylesheet">
+ <link href="{% static "css/bootstrap-sortable.css" %}" rel="stylesheet">
+ <link href="{% static "css/glyphicons.css" %}" rel="stylesheet">
+ <link href="{% static "css/halflings.css" %}" rel="stylesheet">
+ <link href="{% static "css/servo.css" %}" rel="stylesheet">
<title>{{ title }} | Servo</title>
</head>
<body>
diff --git a/servo/templates/default_print.html b/servo/templates/default_print.html
index ed3f4de..6abee01 100755
--- a/servo/templates/default_print.html
+++ b/servo/templates/default_print.html
@@ -1,17 +1,19 @@
+{% load static %}
<!DOCTYPE html>
<html>
<head>
<title>{{ title }}</title>
<meta charset="utf-8">
- <link rel="icon" type="image/png" href="{{ STATIC_URL }}images/favicon.png">
- <link href="{{ STATIC_URL }}js/bootstrap/css/bootstrap.min.css" rel="stylesheet">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link rel="icon" type="image/png" href="{% static "images/favicon.png" %}">
+ <link rel="stylesheet" href="{% static "js/bootstrap/css/bootstrap.min.css" %}">
</head>
<body>
<div class="container">
{% block content %}
{% endblock content %}
</div>
- <script src="{{ STATIC_URL }}js/jquery.min.js"></script>
+ <script type="text/javascript" src="{% static "js/jquery.min.js" %}"></script>
{% if request.user.autoprint %}
<script type="text/javascript">
$(function() {
diff --git a/servo/templates/orders/edit.html b/servo/templates/orders/edit.html
index c340585..92fc3f2 100755
--- a/servo/templates/orders/edit.html
+++ b/servo/templates/orders/edit.html
@@ -1,6 +1,6 @@
{% extends "default.html" %}
-{% load staticfiles %}
{% load servo_tags %}
+{% load static %}
{% load i18n %}
{% block toolbar %}
diff --git a/servo/templates/orders/notes.html b/servo/templates/orders/notes.html
index 0e59e81..e7975e6 100755
--- a/servo/templates/orders/notes.html
+++ b/servo/templates/orders/notes.html
@@ -51,7 +51,7 @@
</ul>
</div>
<div class="media-body">
- <h5 class="media-heading">{{ node.get_sender_name }} {{ node.created_at|relative_date }}
+ <h5 class="media-heading">{{ node.get_sender_name }} <span class="muted">{{ node.created_at|relative_date }}</span>
{% if node.escalation.is_submitted %}
<small class="muted"><i class="icon-globe"></i> {{ node.escalation.escalation_id }}</small>
{% endif %}
diff --git a/servo/tests/test_functional.py b/servo/tests/test_functional.py
index d9fabfb..f62a26e 100644
--- a/servo/tests/test_functional.py
+++ b/servo/tests/test_functional.py
@@ -4,6 +4,7 @@ import os
import unittest
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
+from selenium.webdriver.support.ui import Select
class NewVisitorTest(unittest.TestCase):
@@ -105,6 +106,10 @@ class NewVisitorTest(unittest.TestCase):
field = self.browser.find_element_by_id('id_condition')
field.send_keys('Like new')
+ # Employee puts order in non-default queue
+ select = Select(self.browser.find_element_by_id('id_queue'))
+ select.select_by_index(1)
+
# Submit the repair
submit_button = self.browser.find_element_by_id('id_btn_submit')
submit_button.click()
diff --git a/servo/views/account.py b/servo/views/account.py
index 9f0da54..2b50959 100644
--- a/servo/views/account.py
+++ b/servo/views/account.py
@@ -1,7 +1,6 @@
# -*- coding: utf-8 -*-
import csv
-import pytz
from datetime import date
from django.contrib import auth
@@ -23,9 +22,7 @@ from servo.forms.account import ProfileForm, RegistrationForm, LoginForm
def settings(request):
- """
- User editing their profile preferences
- """
+ """User editing their profile."""
title = _("Profile Settings")
form = ProfileForm(instance=request.user)
@@ -37,7 +34,7 @@ def settings(request):
user = form.save()
messages.success(request, _("Settings saved"))
User.refresh_nomail()
-
+
if form.cleaned_data['password1']:
request.user.set_password(form.cleaned_data['password1'])
request.user.save()
@@ -89,13 +86,14 @@ def login(request):
if 'username' in request.POST:
+ form = LoginForm(request.POST)
+
if request.session.test_cookie_worked():
request.session.delete_test_cookie()
else:
- error = {'message': _('Please enable cookies to use this system')}
- return render(request, 'checkin/error.html', error)
-
- form = LoginForm(request.POST)
+ message = _('Please enable cookies to use this system')
+ url = request.path
+ return render(request, 'checkin/error.html', locals())
if form.is_valid():
user = auth.authenticate(
diff --git a/servo/views/checkin.py b/servo/views/checkin.py
index f931ef6..1a8256a 100644
--- a/servo/views/checkin.py
+++ b/servo/views/checkin.py
@@ -21,15 +21,13 @@ from servo.exceptions import ConfigurationError
from servo.models import (User, Device, GsxAccount, Order,
Customer, Location, Note, Attachment,
Configuration, ChecklistItem, Tag,)
-from servo.forms import (SerialNumberForm, AppleSerialNumberForm,
- DeviceForm, IssueForm, CustomerForm,
- AttachmentForm, StatusCheckForm,)
+from servo import forms
def find_device(request):
device = Device(sn=request.GET['sn'])
device.description = _('Other Device')
- device_form = DeviceForm(instance=device)
+ device_form = forms.DeviceForm(instance=device)
try:
apple_sn_validator(device.sn)
@@ -38,7 +36,7 @@ def find_device(request):
try:
device = get_device(request, device.sn)
- device_form = DeviceForm(instance=device)
+ device_form = forms.DeviceForm(instance=device)
except GsxError as e:
error = e
@@ -221,7 +219,7 @@ def status(request):
if request.GET.get('code'):
timeline = []
- form = StatusCheckForm(request.GET)
+ form = forms.StatusCheckForm(request.GET)
if form.is_valid():
code = form.cleaned_data['code']
try:
@@ -235,7 +233,7 @@ def status(request):
messages.error(request, _(u'Order %s not found') % code)
return render(request, "checkin/status-show.html", locals())
else:
- form = StatusCheckForm()
+ form = forms.StatusCheckForm()
return render(request, "checkin/status.html", locals())
@@ -269,26 +267,26 @@ def index(request):
title = _('Service Order Check-In')
dcat = request.GET.get('d', 'mac')
dmap = {
- 'mac' : _('Mac'),
- 'iphone' : _('iPhone'),
- 'ipad' : _('iPad'),
- 'ipod' : _('iPod'),
- 'acc' : _('Apple Accessory'),
- 'beats' : _('Beats Products'),
- 'other' : _('Other Devices'),
+ 'mac': _('Mac'),
+ 'iphone': _('iPhone'),
+ 'ipad': _('iPad'),
+ 'ipod': _('iPod'),
+ 'acc': _('Apple Accessory'),
+ 'beats': _('Beats Products'),
+ 'other': _('Other Devices'),
}
- issue_form = IssueForm()
+ issue_form = forms.IssueForm()
device = Device(description=dmap[dcat])
if dcat in ('mac', 'iphone', 'ipad', 'ipod'):
- sn_form = AppleSerialNumberForm()
+ sn_form = forms.AppleSerialNumberForm()
else:
- sn_form = SerialNumberForm()
+ sn_form = forms.SerialNumberForm()
tags = Tag.objects.filter(type="order")
- device_form = DeviceForm(instance=device)
- customer_form = CustomerForm(request)
+ device_form = forms.DeviceForm(instance=device)
+ customer_form = forms.CustomerForm(request)
if request.method == 'POST':
@@ -298,10 +296,10 @@ def index(request):
else:
request.session.delete_test_cookie()
- sn_form = SerialNumberForm(request.POST)
- issue_form = IssueForm(request.POST, request.FILES)
- customer_form = CustomerForm(request, request.POST)
- device_form = DeviceForm(request.POST, request.FILES)
+ sn_form = forms.SerialNumberForm(request.POST)
+ issue_form = forms.IssueForm(request.POST, request.FILES)
+ customer_form = forms.CustomerForm(request, request.POST)
+ device_form = forms.DeviceForm(request.POST, request.FILES)
if device_form.is_valid() and issue_form.is_valid() and customer_form.is_valid():
@@ -322,8 +320,8 @@ def index(request):
if len(cdata['company']):
name += ', ' + cdata['company']
- customer.name = name
- customer.city = cdata['city']
+ customer.name = name
+ customer.city = cdata['city']
customer.phone = cdata['phone']
customer.email = cdata['email']
customer.phone = cdata['phone']
@@ -362,7 +360,7 @@ def index(request):
if ddata.get('pop'):
f = {'content_type': Attachment.get_content_type('note').pk}
f['object_id'] = note.pk
- a = AttachmentForm(f, {'content': ddata['pop']})
+ a = forms.AttachmentForm(f, {'content': ddata['pop']})
a.save()
if request.POST.get('tags'):
@@ -406,6 +404,10 @@ def index(request):
redirect_to = thanks
+ # Move to custom queue, if set
+ if device_form.cleaned_data.get('queue'):
+ order.set_queue(device_form.cleaned_data['queue'], user)
+
"""
if request.user.is_authenticated():
if request.user.autoprint: