aboutsummaryrefslogtreecommitdiffstats
path: root/servo
diff options
context:
space:
mode:
authorFilipp Lepalaan <filipp@mac.com>2021-05-30 10:34:01 +0300
committerFilipp Lepalaan <filipp@mac.com>2021-05-30 10:34:01 +0300
commit9dcc51f2211385239b0272bdbf2466637c874f35 (patch)
tree8ac9104abcfa817dc1092e5f338b8c90b4b8aaff /servo
parent467f9fef717cbdc217aae63fef6481150e8e34a7 (diff)
downloadServo-9dcc51f2211385239b0272bdbf2466637c874f35.tar.gz
Servo-9dcc51f2211385239b0272bdbf2466637c874f35.tar.bz2
Servo-9dcc51f2211385239b0272bdbf2466637c874f35.zip
Check-in fixes and improvements
Diffstat (limited to 'servo')
-rw-r--r--servo/forms/checkin.py54
-rw-r--r--servo/models/customer.py4
-rw-r--r--servo/models/device.py4
-rwxr-xr-xservo/static/css/login.css11
-rwxr-xr-xservo/static/css/servo.css1
-rwxr-xr-xservo/templates/accounts/login.html2
-rw-r--r--servo/templates/checkin/newindex.html8
-rwxr-xr-xservo/templates/default.html10
-rwxr-xr-xservo/templates/orders/close.html1
-rwxr-xr-xservo/templates/orders/toolbar.html5
-rw-r--r--servo/validators.py5
-rw-r--r--servo/views/checkin.py13
12 files changed, 72 insertions, 46 deletions
diff --git a/servo/forms/checkin.py b/servo/forms/checkin.py
index 6a6cf9d..7141bc8 100644
--- a/servo/forms/checkin.py
+++ b/servo/forms/checkin.py
@@ -7,6 +7,7 @@ from datetime import date
from django.conf import settings
from django_countries import countries
from django.core.validators import RegexValidator
+from django.utils.safestring import mark_safe
from django.utils.translation import ugettext_lazy as _
from django.forms import SelectDateWidget
@@ -40,15 +41,11 @@ class ConfirmationForm(forms.Form):
class DeviceForm(forms.ModelForm):
- """The form for editing devices in the /checkin view"""
-
+ """
+ Form for entering devices in the /checkin view
+ """
required_css_class = 'required'
- purchase_country = forms.ChoiceField(
- label=_('Country'),
- choices=countries,
- initial=settings.INSTALL_COUNTRY
- )
accessories = forms.CharField(
required=False,
label=_('Accessories'),
@@ -64,10 +61,10 @@ class DeviceForm(forms.ModelForm):
)
condition = forms.CharField(
- label=_('Condition of device'),
required=False,
+ label=_('Condition of device'),
widget=forms.Textarea(attrs={'class': 'span12', 'rows': 3}),
- help_text=_("Please describe the condition of the device")
+ help_text=_('Please describe the condition of the device. Will be shown on the print-out.')
)
queue = forms.ModelChoiceField(
@@ -123,9 +120,10 @@ class DeviceForm(forms.ModelForm):
class CustomerForm(forms.Form):
-
- from django.utils.safestring import mark_safe
-
+ """
+ Form for entering customer info in /checkin
+ Not using a ModelForm for a reason.
+ """
required_css_class = 'required'
fname = forms.CharField(label=_('First name'))
@@ -139,15 +137,12 @@ class CustomerForm(forms.Form):
label=_('Email address'),
widget=forms.TextInput(attrs={'class': 'span12'})
)
- phone = forms.CharField(
- label=_('Phone number'),
- validators=[phone_validator]
- )
+ phone = forms.CharField(label=_('Phone number'))
address = forms.CharField(label=_('Address'))
country = forms.ChoiceField(
label=_('Country'),
choices=Customer.COUNTRY_CHOICES,
- initial=settings.INSTALL_COUNTRY
+ initial=settings.INSTALL_COUNTRY.upper()
)
city = forms.CharField(label=_('City'))
postal_code = forms.CharField(label=_('Postal Code'))
@@ -179,6 +174,24 @@ class CustomerForm(forms.Form):
label=_('Notify by Email')
)
+ def clean(self):
+ cd = super(CustomerForm, self).clean()
+
+ phone = cd.get('phone')
+ country = cd.get('country')
+
+ if len(phone) < 1:
+ return cd
+
+ try:
+ phonenumbers.parse(phone, country)
+ except phonenumbers.NumberParseException as e:
+ print(e)
+ msg = _('Enter a valid phone number')
+ self._errors["phone"] = self.error_class([msg])
+
+ return cd
+
def clean_fname(self):
v = self.cleaned_data.get('fname')
return v.capitalize()
@@ -242,20 +255,21 @@ class IssueForm(forms.Form):
issue_description = forms.CharField(
min_length=10,
label=_(u'Problem description'),
+ help_text=_('Will appear on the print-out'),
widget=forms.Textarea(attrs={'class': 'span12'})
)
attachment = forms.FileField(
required=False,
- label=_(u'Attachment'),
+ label=_('Attachment'),
validators=[file_upload_validator],
- help_text=_(u'Please use this to attach relevant documents')
+ help_text=_('Please use this to attach relevant documents')
)
notes = forms.CharField(
required=False,
label=_(u'Notes'),
widget=forms.Textarea(attrs={'class': 'span12'}),
- help_text=_(u'Will not appear on the print-out')
+ help_text=_('Will not appear on the print-out')
)
diff --git a/servo/models/customer.py b/servo/models/customer.py
index 9d81371..bb34892 100644
--- a/servo/models/customer.py
+++ b/servo/models/customer.py
@@ -93,9 +93,9 @@ class Customer(MPTTModel):
country = models.CharField(
blank=True,
max_length=2,
+ choices=COUNTRY_CHOICES,
verbose_name=_('Country'),
- default=defaults.country,
- choices=COUNTRY_CHOICES
+ default=settings.INSTALL_COUNTRY.upper(),
)
photo = models.ImageField(
null=True,
diff --git a/servo/models/device.py b/servo/models/device.py
index d994d20..671dc3e 100644
--- a/servo/models/device.py
+++ b/servo/models/device.py
@@ -141,8 +141,8 @@ class Device(models.Model):
blank=True,
max_length=128,
choices=countries,
- default=defaults.country,
- verbose_name=_("Purchase Country")
+ verbose_name=_("Country Of Purchase"),
+ default=settings.INSTALL_COUNTRY.upper(),
)
sla_description = models.TextField(null=True, editable=False)
diff --git a/servo/static/css/login.css b/servo/static/css/login.css
index 11363b3..62cc0c7 100755
--- a/servo/static/css/login.css
+++ b/servo/static/css/login.css
@@ -4,6 +4,7 @@
body {
background-color: #f5f5f5;
}
+
form {
margin-left: 10px;
margin-top: 30px;
@@ -13,8 +14,8 @@ form {
margin: auto;
position: absolute;
top: 0; left: 0; bottom: 0; right: 0;
- width: 250px; height: 250px;
- padding: 70px;
+ width: 250px;
+ padding: 250px 70px;
background-color: #fff;
border: 1px solid #e5e5e5;
-webkit-border-radius: 5px;
@@ -29,3 +30,9 @@ form {
width: 251px;
display: block;
}
+
+div.alert {
+ width: 100%;
+ position: fixed;
+ z-index: 99999;
+}
diff --git a/servo/static/css/servo.css b/servo/static/css/servo.css
index ba1a3c8..2f19ef2 100755
--- a/servo/static/css/servo.css
+++ b/servo/static/css/servo.css
@@ -191,6 +191,7 @@ textarea {
.typeahead {
margin-top: 0;
}
+
.alert .errorlist {
margin: 5px;
}
diff --git a/servo/templates/accounts/login.html b/servo/templates/accounts/login.html
index e77c753..80daf06 100755
--- a/servo/templates/accounts/login.html
+++ b/servo/templates/accounts/login.html
@@ -13,7 +13,7 @@
<span class="add-on"><i class="icon-lock"></i></span>
{{ form.password }}
</div>
- <br/>
+ <br/><hr/>
<div class="pull-right">
{% if show_checkin %}
<a class="btn btn" href="{% url 'checkin-index' %}">{% trans "Check-in" %}</a>
diff --git a/servo/templates/checkin/newindex.html b/servo/templates/checkin/newindex.html
index f1fc035..55a52fa 100644
--- a/servo/templates/checkin/newindex.html
+++ b/servo/templates/checkin/newindex.html
@@ -6,7 +6,7 @@
{% block main %}
<div class="page-header">
- <h2>{% trans "Device" %}</h2>
+ <h2>{% trans "Device Info" %}</h2>
</div>
{% comment %}
@@ -66,15 +66,15 @@
{% include "checkin/device_form.html" %}
</div>
<div class="page-header">
- <h2>{% trans "Customer" %}</h2>
+ <h2>{% trans "Customer Info" %}</h2>
</div>
<div id="customer">
{% include "checkin/customer_form.html" %}
</div>
<div class="page-header">
- <h2>{% trans "Problem description" %}</h2>
+ <h2>{% trans "Problem Description" %}</h2>
</div>
- {% if request.user.is_authenticated %}
+ {% if request.user.is_authenticated and tags %}
<div class="row">
<div class="col-md-12">
<div class="form-group">
diff --git a/servo/templates/default.html b/servo/templates/default.html
index 15de430..d770655 100755
--- a/servo/templates/default.html
+++ b/servo/templates/default.html
@@ -64,19 +64,13 @@
</a>
{% with request.user as user %}
<ul class="dropdown-menu">
- <li><a href="#"><i class="icon-user"></i> {{ request.user.get_name }}</a></li>
+ <li><a href="{% url 'accounts-list_orders' %}"><i class="icon-user"></i> {{ user.get_name }}</a></li>
<li class="divider"></li>
- <li><a href="{% url 'accounts-list_orders' %}"><i class="icon-home"></i> {% trans "Homepage" %}</a></li>
- <li><a href="{% url 'accounts-settings' %}"><i class="icon-wrench"></i> {% trans "Profile" %}</a></li>
- {% if request.user.is_staff %}
+ {% if user.is_staff %}
<li><a href="{% url 'admin-settings' %}"><i class="icon-cog"></i> {% trans "System Settings" %}</a></li>
{% endif %}
<li class="divider"></li>
- {% if show_checkin %}
<li><a href="{% url 'checkin-index' %}"><i class="icon-check"></i> {% trans "Go to check-in" %}</a></li>
- {% else %}
- <li class="disabled"><a href="#"><i class="icon-check"></i> {% trans "Go to check-in" %}</a></li>
- {% endif %}
<li><a href="{% url 'accounts-logout' %}" data-modal="#modal"><i class="icon-off"></i> {% trans "Log out" %}...</a></li>
</ul>
{% endwith %}
diff --git a/servo/templates/orders/close.html b/servo/templates/orders/close.html
index b80f862..a53db5e 100755
--- a/servo/templates/orders/close.html
+++ b/servo/templates/orders/close.html
@@ -12,6 +12,7 @@
{% block footer %}
<form action="{{ action }}" method="post" accept-charset="utf-8">
{% csrf_token %}
+ <button class="btn btn-default" data-dismiss="modal">{% trans "Cancel" %}</button>
<button class="btn btn-primary" type="submit">{% trans "Close" %}</button>
</form>
{% endblock footer %}
diff --git a/servo/templates/orders/toolbar.html b/servo/templates/orders/toolbar.html
index 286d93e..56fe851 100755
--- a/servo/templates/orders/toolbar.html
+++ b/servo/templates/orders/toolbar.html
@@ -26,6 +26,9 @@
{% if order.invoice_set.count %}
<li><a href="{% url 'orders-print_order' order.pk 'receipt' %}" class="window">{% trans "Receipt" %}</a></li>
<li><a href="{% url 'orders-print_order' order.pk 'dispatch' %}" class="window">{% trans "Dispatch" context "noun" %}</a></li>
+ {% else %}
+ <li class="disabled"><a href="#" title="{% trans 'Cannot print a receipt without an invoice' %}">{% trans "Receipt" %}</a></li>
+ <li class="disabled"><a href="#" title="{% trans 'Cannot print a dispatch without an invoice' %}">{% trans "Dispatch" context "noun" %}</a></li>
{% endif %}
</ul>
</div>
@@ -61,7 +64,7 @@
{% if order.can_dispatch %}
<a class="btn" href="{% url 'orders-dispatch' order.pk %}">{% trans "Dispatch" %}</a>
{% else %}
- <a class="btn disabled" href="#">{% trans "Dispatch" %}</a>
+ <a class="btn disabled" href="#" title="{%trans 'No parts or services for dispatch' %}">{% trans "Dispatch" %}</a>
{% endif %}
{% if perms.servo.change_order and order.can_close %}
<a class="btn" href="{% url 'orders-close' order.pk %}" data-modal="#modal"><i class="icon-lock"></i> {% trans "Close" %}</a>
diff --git a/servo/validators.py b/servo/validators.py
index 6fc3a91..97fe974 100644
--- a/servo/validators.py
+++ b/servo/validators.py
@@ -11,18 +11,21 @@ from django.utils.translation import ugettext as _
def phone_validator(val):
try:
- phonenumbers.parse(val, settings.INSTALL_COUNTRY)
+ phonenumbers.parse(val.upper(), settings.INSTALL_COUNTRY)
except phonenumbers.NumberParseException:
raise ValidationError(_('%s is not a valid phone number') % val)
+
def apple_sn_validator(val):
if validate(val.upper()) not in ('serialNumber', 'alternateDeviceId',):
raise ValidationError(_(u'%s is not a valid serial or IMEI number') % val)
+
def sn_validator(val):
if not re.match(r'^\w*$', val):
raise ValidationError(_('Serial numbers may only contain letters and numbers'))
+
def file_upload_validator(val):
allowed = ['.pdf', '.zip', '.doc', '.jpg', '.jpeg', '.png', '.txt', '.mov', '.m4v']
ext = os.path.splitext(val.name)[1].lower()
diff --git a/servo/views/checkin.py b/servo/views/checkin.py
index 513625b..fc1719a 100644
--- a/servo/views/checkin.py
+++ b/servo/views/checkin.py
@@ -161,9 +161,12 @@ def init_session(request):
user = get_object_or_404(User, pk=user_id)
request.session['checkin_locations'] = Location.get_checkin_list()
- checkin_users = User.get_checkin_group()
- queryset = checkin_users.filter(location=location)
- request.session['checkin_users'] = User.serialize(queryset)
+ try:
+ checkin_users = User.get_checkin_group()
+ queryset = checkin_users.filter(location=location)
+ request.session['checkin_users'] = User.serialize(queryset)
+ except Exception as e:
+ messages.error(request, _("Failed to launch check-in interface. Please check your system settings."))
request.session['checkin_user'] = user.pk
request.session['checkin_location'] = location.pk
@@ -351,7 +354,7 @@ def index(request):
order.add_device(device, user)
- note = Note(created_by=user, body=idata['issue_description'])
+ note = Note(created_by=user, body=idata['issue_description'], type=Note.T_PROBLEM)
note.is_reported = True
note.order = order
note.save()
@@ -385,7 +388,7 @@ def index(request):
# mark down internal notes (only if logged in)
if len(idata.get('notes')):
- note = Note(created_by=user, body=idata['notes'])
+ note = Note(created_by=user, body=idata['notes'], type=Note.T_NOTE)
note.is_reported = False
note.order = order
note.save()