diff options
author | Filipp Lepalaan <filipp@mac.com> | 2021-05-30 10:34:01 +0300 |
---|---|---|
committer | Filipp Lepalaan <filipp@mac.com> | 2021-05-30 10:34:01 +0300 |
commit | 9dcc51f2211385239b0272bdbf2466637c874f35 (patch) | |
tree | 8ac9104abcfa817dc1092e5f338b8c90b4b8aaff | |
parent | 467f9fef717cbdc217aae63fef6481150e8e34a7 (diff) | |
download | Servo-9dcc51f2211385239b0272bdbf2466637c874f35.tar.gz Servo-9dcc51f2211385239b0272bdbf2466637c874f35.tar.bz2 Servo-9dcc51f2211385239b0272bdbf2466637c874f35.zip |
Check-in fixes and improvements
-rw-r--r-- | servo/forms/checkin.py | 54 | ||||
-rw-r--r-- | servo/models/customer.py | 4 | ||||
-rw-r--r-- | servo/models/device.py | 4 | ||||
-rwxr-xr-x | servo/static/css/login.css | 11 | ||||
-rwxr-xr-x | servo/static/css/servo.css | 1 | ||||
-rwxr-xr-x | servo/templates/accounts/login.html | 2 | ||||
-rw-r--r-- | servo/templates/checkin/newindex.html | 8 | ||||
-rwxr-xr-x | servo/templates/default.html | 10 | ||||
-rwxr-xr-x | servo/templates/orders/close.html | 1 | ||||
-rwxr-xr-x | servo/templates/orders/toolbar.html | 5 | ||||
-rw-r--r-- | servo/validators.py | 5 | ||||
-rw-r--r-- | servo/views/checkin.py | 13 |
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() |