From 07600c09b7811b7f963d679467111e3cda4ac726 Mon Sep 17 00:00:00 2001 From: Filipp Lepalaan Date: Fri, 18 Mar 2016 11:46:47 +0200 Subject: Handle editing a product that's been removed from order --- servo/views/order.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/servo/views/order.py b/servo/views/order.py index e9d5a51..3b3930a 100644 --- a/servo/views/order.py +++ b/servo/views/order.py @@ -664,7 +664,12 @@ def edit_product(request, pk, item_id): Edits a product added to an order """ order = Order.objects.get(pk=pk) - item = ServiceOrderItem.objects.get(pk=item_id) + + try: + item = ServiceOrderItem.objects.get(pk=item_id) + except ServiceOrderItem.DoesNotExist: + messages.error(request, _('Product not found in order')) + return redirect(order) if not item.kbb_sn and item.product.part_type == "REPLACEMENT": try: -- cgit v1.2.3 From f5ae8615a6a53bed91aabbb84276ea891fae9ca7 Mon Sep 17 00:00:00 2001 From: Filipp Lepalaan Date: Fri, 18 Mar 2016 11:52:13 +0200 Subject: Throw 404 rather than custom error --- servo/views/order.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/servo/views/order.py b/servo/views/order.py index 3b3930a..b4838f7 100644 --- a/servo/views/order.py +++ b/servo/views/order.py @@ -664,12 +664,7 @@ def edit_product(request, pk, item_id): Edits a product added to an order """ order = Order.objects.get(pk=pk) - - try: - item = ServiceOrderItem.objects.get(pk=item_id) - except ServiceOrderItem.DoesNotExist: - messages.error(request, _('Product not found in order')) - return redirect(order) + item = get_object_or_404(ServiceOrderItem, pk=item_id) if not item.kbb_sn and item.product.part_type == "REPLACEMENT": try: -- cgit v1.2.3 From d2677674eec9cebaa0748d8035cc1ac8329444e2 Mon Sep 17 00:00:00 2001 From: Filipp Lepalaan Date: Fri, 18 Mar 2016 12:49:48 +0200 Subject: Clear ALL caches, not just default --- servo/management/commands/clearcache.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/servo/management/commands/clearcache.py b/servo/management/commands/clearcache.py index 7c00ef4..ce96459 100644 --- a/servo/management/commands/clearcache.py +++ b/servo/management/commands/clearcache.py @@ -1,12 +1,15 @@ # -*- coding: utf-8 -*- -from django.core.cache import cache +from django.core.cache import caches from django.core.management.base import BaseCommand class Command(BaseCommand): - help = "Clears this install's cache" + help = "Clears this install's caches" def handle(self, *args, **options): - cache.clear() + for c in caches.all(): + c.clear() + + exit(0) -- cgit v1.2.3 From aa34239d1c85517cdb2bcb1a014a6f90a67e592e Mon Sep 17 00:00:00 2001 From: Filipp Lepalaan Date: Fri, 18 Mar 2016 12:57:42 +0200 Subject: Added 24-hour comptia cache --- settings.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/settings.py b/settings.py index 0d513f3..805d764 100644 --- a/settings.py +++ b/settings.py @@ -230,3 +230,10 @@ CELERYBEAT_SCHEDULE = { } from local_settings import * + +CACHES['comptia'] = { + 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', + 'LOCATION': '127.0.0.1:11211', + 'TIMEOUT': 60*60*24, + 'KEY_PREFIX': 'comptia_' +} -- cgit v1.2.3 From 5c1943521f35e22f3fce7033d69659bcd6eb6869 Mon Sep 17 00:00:00 2001 From: Filipp Lepalaan Date: Fri, 18 Mar 2016 13:01:03 +0200 Subject: Added custom comptia cache support --- servo/models/parts.py | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/servo/models/parts.py b/servo/models/parts.py index ab54e79..ecea0ad 100644 --- a/servo/models/parts.py +++ b/servo/models/parts.py @@ -6,6 +6,7 @@ import gsxws from django.db import models from django.utils import timezone from django.core.files import File +from django.core.cache import caches from django.utils.translation import ugettext_lazy as _ from servo.models import GsxAccount @@ -18,21 +19,39 @@ def symptom_modifiers(): return gsxws.MODIFIERS +def get_remote_symptom_codes(group): + """ + Remote lookup for symptom codes + """ + symptoms = {} + cache = caches['comptia'] + # First, try to load from global cache (updated every 24h) + data = cache.get('codes') or {} + + if not data: + # ... then try to fetch from GSX + GsxAccount.fallback() + data = gsxws.comptia.fetch() + cache.set('codes', data) + + for k, v in data.get(group): + symptoms[k] = v + + return symptoms + + def symptom_codes(group): """ - Return CompTIA symptom codes for component group + Returns CompTIA symptom codes for component group """ if group == '': return - symptoms = {} - try: - act = GsxAccount.fallback() - codes = gsxws.comptia.fetch()[group] - for k, v in codes: - symptoms[k] = v - except gsxws.GsxError as e: + symptoms = get_remote_symptom_codes(group) + except Exception as e: + # ... finally fall back to local static data + # @FIXME: How do we keep this up to date? data = yaml.load(open("servo/fixtures/comptia.yaml", "r")) symptoms = data[group]['symptoms'] -- cgit v1.2.3 From 039d439b67d37c7cc98f18fb0636de5d05b86aed Mon Sep 17 00:00:00 2001 From: Filipp Lepalaan Date: Fri, 18 Mar 2016 13:01:31 +0200 Subject: Added periodic CompTIA update command --- servo/management/commands/periodic.py | 38 +++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 servo/management/commands/periodic.py diff --git a/servo/management/commands/periodic.py b/servo/management/commands/periodic.py new file mode 100644 index 0000000..5895e3c --- /dev/null +++ b/servo/management/commands/periodic.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- + +import os +import sys +import gsxws +import subprocess +from time import strftime +from django.conf import settings +from django.core.cache import caches +from django.core.management.base import BaseCommand + +from servo.models import GsxAccount + + +class Command(BaseCommand): + help = 'Peforms periodic commands' + VERBS = ('comptia',) + + def add_arguments(self, parser): + parser.add_argument('verb', type=str, choices=self.VERBS, help='Periodic command to perform') + + def handle(self, *args, **options): + if 'comptia' in options['verb']: + # Update raw CompTIA data (all product groups) + try: + act = GsxAccount.fallback() + except Exception as e: + print >> sys.stderr, 'Failed to connect to GSX (%s)' % e + sys.exit(-1) + + try: + codes = gsxws.comptia.fetch() + caches['comptia'].set('codes', codes) + except Exception as e: + print >> sys.stderr, 'Failed to fetch CompTIA codes (%s)' % e + sys.exit(-1) + + exit(0) -- cgit v1.2.3 From 367aba3c306a49cb8f8e16b34625f51396e3aacf Mon Sep 17 00:00:00 2001 From: Filipp Lepalaan Date: Mon, 21 Mar 2016 12:54:36 +0200 Subject: Added upgrade command Upgrade required libs --- servo/management/commands/upgrade.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 servo/management/commands/upgrade.py diff --git a/servo/management/commands/upgrade.py b/servo/management/commands/upgrade.py new file mode 100644 index 0000000..f232e73 --- /dev/null +++ b/servo/management/commands/upgrade.py @@ -0,0 +1,12 @@ +# -*- coding: utf-8 -*- + +import subprocess +from django.core.management.base import BaseCommand + + +class Command(BaseCommand): + + help = "Upgrade requirements" + + def handle(self, *args, **options): + subprocess.call(['pip', 'install', '-U', '-r', 'requirements.pip']) -- cgit v1.2.3 From f30d6d73513a5535cae4d97ee2cc85f01660750c Mon Sep 17 00:00:00 2001 From: Filipp Lepalaan Date: Mon, 21 Mar 2016 19:14:11 +0200 Subject: Adding device stats --- servo/templates/stats/devices.html | 40 +++++++++++++++++++++++++++++ servo/templates/stats/index.html | 1 + servo/templates/stats/locations.html | 1 + servo/templates/stats/newstats.html | 1 + servo/templates/stats/queues.html | 1 + servo/templates/stats/sales.html | 49 ++++++++++++++++++------------------ servo/templates/stats/statuses.html | 1 + servo/urls/stats.py | 1 + servo/views/stats.py | 27 ++++++++++++++++++++ 9 files changed, 98 insertions(+), 24 deletions(-) create mode 100644 servo/templates/stats/devices.html diff --git a/servo/templates/stats/devices.html b/servo/templates/stats/devices.html new file mode 100644 index 0000000..079530a --- /dev/null +++ b/servo/templates/stats/devices.html @@ -0,0 +1,40 @@ +{% extends "stats/index.html" %} +{% load i18n %} + +{% block tabs %} +
  • {% trans "Technicians" %}
  • +
  • {% trans "Locations" %}
  • +
  • {% trans "Queues" %}
  • +
  • {% trans "Repairs" %}
  • +
  • {% trans "Statuses" %}
  • +
  • {% trans "Sales" %}
  • +
  • {% trans "Devices" %}
  • +{% endblock tabs %} + +{% block stats %} +

    {% trans "Device statistics" %}

    +

    {% trans "Shows the number of orders and GSX repairs created for each device model within the given timeframe." %}

    +
    + + + + + + + + + + {% for r in results %} + + + + + + {% empty %} + + + + {% endfor %} + +
    {% trans "Device" %}{% trans "Service Orders" %}{% trans "GSX Repairs" %}
    {{ r.0 }}{{ r.1 }}{{ r.2 }}
    {% trans "No results found" %}
    +{% endblock stats %} diff --git a/servo/templates/stats/index.html b/servo/templates/stats/index.html index 2edc57d..90c0ed9 100755 --- a/servo/templates/stats/index.html +++ b/servo/templates/stats/index.html @@ -11,6 +11,7 @@
  • {% trans "Repairs" %}
  • {% trans "Statuses" %}
  • {% trans "Sales" %}
  • +
  • {% trans "Devices" %}
  • {% endblock tabs %} diff --git a/servo/templates/stats/locations.html b/servo/templates/stats/locations.html index 576da8b..da4545e 100755 --- a/servo/templates/stats/locations.html +++ b/servo/templates/stats/locations.html @@ -8,6 +8,7 @@
  • {% trans "Repairs" %}
  • {% trans "Statuses" %}
  • {% trans "Sales" %}
  • +
  • {% trans "Devices" %}
  • {% endblock tabs %} {% block stats %} diff --git a/servo/templates/stats/newstats.html b/servo/templates/stats/newstats.html index 1900efc..325ab10 100644 --- a/servo/templates/stats/newstats.html +++ b/servo/templates/stats/newstats.html @@ -11,6 +11,7 @@
  • {% trans "Repairs" %}
  • {% trans "Statuses" %}
  • {% trans "Sales" %}
  • +
  • {% trans "Devices" %}
  • {% endblock tabs %} diff --git a/servo/templates/stats/queues.html b/servo/templates/stats/queues.html index eefec46..f4f493d 100755 --- a/servo/templates/stats/queues.html +++ b/servo/templates/stats/queues.html @@ -8,6 +8,7 @@
  • {% trans "Repairs" %}
  • {% trans "Statuses" %}
  • {% trans "Sales" %}
  • +
  • {% trans "Devices" %}
  • {% endblock tabs %} {% block stats %} diff --git a/servo/templates/stats/sales.html b/servo/templates/stats/sales.html index 186e897..e58b7b4 100755 --- a/servo/templates/stats/sales.html +++ b/servo/templates/stats/sales.html @@ -2,32 +2,33 @@ {% load i18n %} {% block tabs %} -
  • {% trans "Technicians" %}
  • -
  • {% trans "Locations" %}
  • -
  • {% trans "Queues" %}
  • -
  • {% trans "Repairs" %}
  • -
  • {% trans "Statuses" %}
  • -
  • {% trans "Sales" %}
  • +
  • {% trans "Technicians" %}
  • +
  • {% trans "Locations" %}
  • +
  • {% trans "Queues" %}
  • +
  • {% trans "Repairs" %}
  • +
  • {% trans "Statuses" %}
  • +
  • {% trans "Sales" %}
  • +
  • {% trans "Devices" %}
  • {% endblock tabs %} {% block stats %} -

    {% trans "Sales" %}

    -

    {% trans "Shows you invoice totals per queue within the selected time period." %}

    -{% include "stats/plot_snippet.html" with url="/stats/data/sales/invoices/" %} -
    -

    {% trans "Purchases" %}

    -

    {% trans "Shows you Purchase Order totals per queue within the selected time period." %}

    -{% include "stats/plot_snippet.html" with url="/stats/data/sales/purchases/" %} -
    -

    {% trans "Service Parts" %}

    -

    {% trans "Shows you how many parts have been ordered for each labour tier." %}

    -
    -
    -
    -
    -
    +

    {% trans "Sales" %}

    +

    {% trans "Shows you invoice totals per queue within the selected time period." %}

    + {% include "stats/plot_snippet.html" with url="/stats/data/sales/invoices/" %} +
    +

    {% trans "Purchases" %}

    +

    {% trans "Shows you Purchase Order totals per queue within the selected time period." %}

    + {% include "stats/plot_snippet.html" with url="/stats/data/sales/purchases/" %} +
    +

    {% trans "Service Parts" %}

    +

    {% trans "Shows you how many parts have been ordered for each labour tier." %}

    +
    +
    +
    +
    +
    +
    +
    +
    -
    -
    -
    {% endblock stats %} diff --git a/servo/templates/stats/statuses.html b/servo/templates/stats/statuses.html index f4fb427..bfcf73e 100755 --- a/servo/templates/stats/statuses.html +++ b/servo/templates/stats/statuses.html @@ -8,6 +8,7 @@
  • {% trans "Repairs" %}
  • {% trans "Statuses" %}
  • {% trans "Sales" %}
  • +
  • {% trans "Devices" %}
  • {% endblock tabs %} {% block stats %} diff --git a/servo/urls/stats.py b/servo/urls/stats.py index d475e54..58c5ee3 100644 --- a/servo/urls/stats.py +++ b/servo/urls/stats.py @@ -13,4 +13,5 @@ urlpatterns = [ url(r'^statuses/$', statuses, name="stats-statuses"), url(r'^data/(?P[\w/\-]+)/$', data, name="stats-data"), url(r'^repairs/$', repairs, name="stats-repairs"), + url(r'^devices/$', devices, name="stats-devices"), ] diff --git a/servo/views/stats.py b/servo/views/stats.py index 0acf9f7..6a9f9a8 100644 --- a/servo/views/stats.py +++ b/servo/views/stats.py @@ -421,3 +421,30 @@ def repairs(request): totals['turnaround'] = ServoTimeDelta(totals['turnaround']/totals['dispatched']) return render(request, "stats/newstats.html", locals()) + + +def devices(request): + data = prep_view(request) + data['form'] = DeviceStatsForm() + start_date = data['initial']['start_date'] + end_date = data['initial']['end_date'] + + if request.method == 'POST': + form = DeviceStatsForm(request.POST) + if form.is_valid(): + start_date = form.cleaned_data['start_date'] + end_date = form.cleaned_data['end_date'] + + cursor = connection.cursor() + query = '''SELECT d.description device, count(o) AS orders, count(r) AS repairs + FROM servo_device d, servo_order o, servo_repair r, servo_orderdevice od + WHERE d.id = od.device_id + AND o.id = od.order_id + AND r.order_id = o.id + AND (o.created_at, o.created_at) OVERLAPS (%s, %s) + GROUP BY d.description'''; + cursor.execute(query, [start_date, end_date]) + data['results'] = cursor.fetchall() + data['title'] = _('Device statistics') + + return render(request, "stats/devices.html", data) -- cgit v1.2.3 From 1b6e5ee722f76f594e3d95dfa8d77ac2b9f2173a Mon Sep 17 00:00:00 2001 From: Filipp Lepalaan Date: Mon, 21 Mar 2016 19:14:37 +0200 Subject: Adding GSX articles --- servo/lib/utils.py | 17 ++++++ servo/management/commands/periodic.py | 33 +++++++---- servo/migrations/0050_auto_20160229_1634.py | 46 +++++++++++++++ servo/migrations/0051_auto_20160318_1607.py | 26 +++++++++ servo/migrations/0052_auto_20160321_1835.py | 38 ++++++++++++ servo/models/note.py | 91 ++++++++++++++++++++++++++--- servo/models/order.py | 10 +++- servo/stats/forms.py | 11 ++++ servo/templates/notes/list_notes.html | 5 +- servo/templates/notes/view_article.html | 33 +++++++++++ servo/views/note.py | 24 +++++--- 11 files changed, 306 insertions(+), 28 deletions(-) create mode 100644 servo/migrations/0050_auto_20160229_1634.py create mode 100644 servo/migrations/0051_auto_20160318_1607.py create mode 100644 servo/migrations/0052_auto_20160321_1835.py create mode 100644 servo/templates/notes/view_article.html diff --git a/servo/lib/utils.py b/servo/lib/utils.py index 2994fb3..7d9e21c 100644 --- a/servo/lib/utils.py +++ b/servo/lib/utils.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- import json +import html2text import subprocess from django.http import HttpResponse from django.core.cache import cache @@ -107,3 +108,19 @@ class SessionSerializer: def loads(self, data): return json.loads(data, cls=DjangoJSONEncoder) + + +def unescape(s): + import HTMLParser + html_parser = HTMLParser.HTMLParser() + return html_parser.unescape(s) + + +def html_to_text(s, ignore_images=False): + h = html2text.HTML2Text() + h.ignore_images = ignore_images + return h.handle(s) + + +def gsx_to_text(s): + return html_to_text(unescape(s)) diff --git a/servo/management/commands/periodic.py b/servo/management/commands/periodic.py index 5895e3c..e85f9a3 100644 --- a/servo/management/commands/periodic.py +++ b/servo/management/commands/periodic.py @@ -9,25 +9,38 @@ from django.conf import settings from django.core.cache import caches from django.core.management.base import BaseCommand -from servo.models import GsxAccount +from servo.models import GsxAccount, Article class Command(BaseCommand): help = 'Peforms periodic commands' - VERBS = ('comptia',) + VERBS = ('comptia', 'articles',) def add_arguments(self, parser): parser.add_argument('verb', type=str, choices=self.VERBS, help='Periodic command to perform') def handle(self, *args, **options): - if 'comptia' in options['verb']: - # Update raw CompTIA data (all product groups) - try: - act = GsxAccount.fallback() - except Exception as e: - print >> sys.stderr, 'Failed to connect to GSX (%s)' % e - sys.exit(-1) - + try: + act = GsxAccount.fallback() + except Exception as e: + print >> sys.stderr, 'Failed to connect to GSX (%s)' % e + sys.exit(-1) + + if 'articles' in options['verb']: # Update GSX articles + articles = gsxws.comms.fetch() + for a in articles: + try: + article = Article.from_gsx(a) + try: + content = gsxws.comms.content(article.gsx_id) + article.content = content.articleContent + except Exception as e: + pass + article.save() + except ValueError as e: + pass + + if 'comptia' in options['verb']: # Update raw CompTIA data (all product groups) try: codes = gsxws.comptia.fetch() caches['comptia'].set('codes', codes) diff --git a/servo/migrations/0050_auto_20160229_1634.py b/servo/migrations/0050_auto_20160229_1634.py new file mode 100644 index 0000000..fd0d3d4 --- /dev/null +++ b/servo/migrations/0050_auto_20160229_1634.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.2 on 2016-02-29 14:34 +from __future__ import unicode_literals + +from django.conf import settings +import django.contrib.postgres.fields +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('servo', '0049_gsxaccount_timezone'), + ] + + operations = [ + migrations.CreateModel( + name='Article', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('gsx_id', models.CharField(default=b'', editable=False, max_length=20)), + ('date_created', models.DateField(editable=False)), + ('date_published', models.DateField(null=True)), + ('title', models.TextField(default='New Article')), + ('summary', models.TextField(default=b'')), + ('content', models.TextField(default=b'')), + ('priority', models.CharField(choices=[(b'HIGH', 'High'), (b'MEDIUM', 'Medium'), (b'LOW', 'Low')], default=b'HIGH', max_length=128)), + ('url', models.URLField(default=b'')), + ('product_model', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=128), editable=False, null=True, size=None)), + ('read_by', django.contrib.postgres.fields.ArrayField(base_field=models.IntegerField(), null=True, size=None)), + ('flagged_by', django.contrib.postgres.fields.ArrayField(base_field=models.IntegerField(), null=True, size=None)), + ('created_by', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.AlterField( + model_name='serviceorderitem', + name='comptia_code', + field=models.CharField(blank=True, default=b'', max_length=4, verbose_name='Symptom code'), + ), + migrations.AlterField( + model_name='serviceorderitem', + name='comptia_modifier', + field=models.CharField(blank=True, default=b'', max_length=1, verbose_name='Symptom modifier'), + ), + ] diff --git a/servo/migrations/0051_auto_20160318_1607.py b/servo/migrations/0051_auto_20160318_1607.py new file mode 100644 index 0000000..0c9c778 --- /dev/null +++ b/servo/migrations/0051_auto_20160318_1607.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.2 on 2016-03-18 14:07 +from __future__ import unicode_literals + +import django.contrib.postgres.fields +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('servo', '0050_auto_20160229_1634'), + ] + + operations = [ + migrations.AddField( + model_name='orderdevice', + name='repair_strategies', + field=django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=100), help_text=b'Available repair strategies from GSX', null=True, size=None), + ), + migrations.AddField( + model_name='orderdevice', + name='repeat_service', + field=models.BooleanField(default=False), + ), + ] diff --git a/servo/migrations/0052_auto_20160321_1835.py b/servo/migrations/0052_auto_20160321_1835.py new file mode 100644 index 0000000..22725fb --- /dev/null +++ b/servo/migrations/0052_auto_20160321_1835.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.4 on 2016-03-21 16:35 +from __future__ import unicode_literals + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import servo.defaults + + +class Migration(migrations.Migration): + + dependencies = [ + ('servo', '0051_auto_20160318_1607'), + ] + + operations = [ + migrations.AlterField( + model_name='article', + name='created_by', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL), + ), + migrations.AlterField( + model_name='customer', + name='country', + field=models.CharField(blank=True, choices=[('AD', 'Andorra'), ('AE', 'United Arab Emirates'), ('AF', 'Afghanistan'), ('AG', 'Antigua & Barbuda'), ('AI', 'Anguilla'), ('AL', 'Albania'), ('AM', 'Armenia'), ('AO', 'Angola'), ('AQ', 'Antarctica'), ('AR', 'Argentina'), ('AS', 'Samoa (American)'), ('AT', 'Austria'), ('AU', 'Australia'), ('AW', 'Aruba'), ('AX', '\xc5land Islands'), ('AZ', 'Azerbaijan'), ('BA', 'Bosnia & Herzegovina'), ('BB', 'Barbados'), ('BD', 'Bangladesh'), ('BE', 'Belgium'), ('BF', 'Burkina Faso'), ('BG', 'Bulgaria'), ('BH', 'Bahrain'), ('BI', 'Burundi'), ('BJ', 'Benin'), ('BL', 'St Barthelemy'), ('BM', 'Bermuda'), ('BN', 'Brunei'), ('BO', 'Bolivia'), ('BQ', 'Caribbean NL'), ('BR', 'Brazil'), ('BS', 'Bahamas'), ('BT', 'Bhutan'), ('BV', 'Bouvet Island'), ('BW', 'Botswana'), ('BY', 'Belarus'), ('BZ', 'Belize'), ('CA', 'Canada'), ('CC', 'Cocos (Keeling) Islands'), ('CD', 'Congo (Dem. Rep.)'), ('CF', 'Central African Rep.'), ('CG', 'Congo (Rep.)'), ('CH', 'Switzerland'), ('CI', "C\xf4te d'Ivoire"), ('CK', 'Cook Islands'), ('CL', 'Chile'), ('CM', 'Cameroon'), ('CN', 'China'), ('CO', 'Colombia'), ('CR', 'Costa Rica'), ('CU', 'Cuba'), ('CV', 'Cape Verde'), ('CW', 'Curacao'), ('CX', 'Christmas Island'), ('CY', 'Cyprus'), ('CZ', 'Czech Republic'), ('DE', 'Germany'), ('DJ', 'Djibouti'), ('DK', 'Denmark'), ('DM', 'Dominica'), ('DO', 'Dominican Republic'), ('DZ', 'Algeria'), ('EC', 'Ecuador'), ('EE', 'Estonia'), ('EG', 'Egypt'), ('EH', 'Western Sahara'), ('ER', 'Eritrea'), ('ES', 'Spain'), ('ET', 'Ethiopia'), ('FI', 'Finland'), ('FJ', 'Fiji'), ('FK', 'Falkland Islands'), ('FM', 'Micronesia'), ('FO', 'Faroe Islands'), ('FR', 'France'), ('GA', 'Gabon'), ('GB', 'Britain (UK)'), ('GD', 'Grenada'), ('GE', 'Georgia'), ('GF', 'French Guiana'), ('GG', 'Guernsey'), ('GH', 'Ghana'), ('GI', 'Gibraltar'), ('GL', 'Greenland'), ('GM', 'Gambia'), ('GN', 'Guinea'), ('GP', 'Guadeloupe'), ('GQ', 'Equatorial Guinea'), ('GR', 'Greece'), ('GS', 'South Georgia & the South Sandwich Islands'), ('GT', 'Guatemala'), ('GU', 'Guam'), ('GW', 'Guinea-Bissau'), ('GY', 'Guyana'), ('HK', 'Hong Kong'), ('HM', 'Heard Island & McDonald Islands'), ('HN', 'Honduras'), ('HR', 'Croatia'), ('HT', 'Haiti'), ('HU', 'Hungary'), ('ID', 'Indonesia'), ('IE', 'Ireland'), ('IL', 'Israel'), ('IM', 'Isle of Man'), ('IN', 'India'), ('IO', 'British Indian Ocean Territory'), ('IQ', 'Iraq'), ('IR', 'Iran'), ('IS', 'Iceland'), ('IT', 'Italy'), ('JE', 'Jersey'), ('JM', 'Jamaica'), ('JO', 'Jordan'), ('JP', 'Japan'), ('KE', 'Kenya'), ('KG', 'Kyrgyzstan'), ('KH', 'Cambodia'), ('KI', 'Kiribati'), ('KM', 'Comoros'), ('KN', 'St Kitts & Nevis'), ('KP', 'Korea (North)'), ('KR', 'Korea (South)'), ('KW', 'Kuwait'), ('KY', 'Cayman Islands'), ('KZ', 'Kazakhstan'), ('LA', 'Laos'), ('LB', 'Lebanon'), ('LC', 'St Lucia'), ('LI', 'Liechtenstein'), ('LK', 'Sri Lanka'), ('LR', 'Liberia'), ('LS', 'Lesotho'), ('LT', 'Lithuania'), ('LU', 'Luxembourg'), ('LV', 'Latvia'), ('LY', 'Libya'), ('MA', 'Morocco'), ('MC', 'Monaco'), ('MD', 'Moldova'), ('ME', 'Montenegro'), ('MF', 'St Martin (French)'), ('MG', 'Madagascar'), ('MH', 'Marshall Islands'), ('MK', 'Macedonia'), ('ML', 'Mali'), ('MM', 'Myanmar (Burma)'), ('MN', 'Mongolia'), ('MO', 'Macau'), ('MP', 'Northern Mariana Islands'), ('MQ', 'Martinique'), ('MR', 'Mauritania'), ('MS', 'Montserrat'), ('MT', 'Malta'), ('MU', 'Mauritius'), ('MV', 'Maldives'), ('MW', 'Malawi'), ('MX', 'Mexico'), ('MY', 'Malaysia'), ('MZ', 'Mozambique'), ('NA', 'Namibia'), ('NC', 'New Caledonia'), ('NE', 'Niger'), ('NF', 'Norfolk Island'), ('NG', 'Nigeria'), ('NI', 'Nicaragua'), ('NL', 'Netherlands'), ('NO', 'Norway'), ('NP', 'Nepal'), ('NR', 'Nauru'), ('NU', 'Niue'), ('NZ', 'New Zealand'), ('OM', 'Oman'), ('PA', 'Panama'), ('PE', 'Peru'), ('PF', 'French Polynesia'), ('PG', 'Papua New Guinea'), ('PH', 'Philippines'), ('PK', 'Pakistan'), ('PL', 'Poland'), ('PM', 'St Pierre & Miquelon'), ('PN', 'Pitcairn'), ('PR', 'Puerto Rico'), ('PS', 'Palestine'), ('PT', 'Portugal'), ('PW', 'Palau'), ('PY', 'Paraguay'), ('QA', 'Qatar'), ('RE', 'R\xe9union'), ('RO', 'Romania'), ('RS', 'Serbia'), ('RU', 'Russia'), ('RW', 'Rwanda'), ('SA', 'Saudi Arabia'), ('SB', 'Solomon Islands'), ('SC', 'Seychelles'), ('SD', 'Sudan'), ('SE', 'Sweden'), ('SG', 'Singapore'), ('SH', 'St Helena'), ('SI', 'Slovenia'), ('SJ', 'Svalbard & Jan Mayen'), ('SK', 'Slovakia'), ('SL', 'Sierra Leone'), ('SM', 'San Marino'), ('SN', 'Senegal'), ('SO', 'Somalia'), ('SR', 'Suriname'), ('SS', 'South Sudan'), ('ST', 'Sao Tome & Principe'), ('SV', 'El Salvador'), ('SX', 'St Maarten (Dutch)'), ('SY', 'Syria'), ('SZ', 'Swaziland'), ('TC', 'Turks & Caicos Is'), ('TD', 'Chad'), ('TF', 'French Southern & Antarctic Lands'), ('TG', 'Togo'), ('TH', 'Thailand'), ('TJ', 'Tajikistan'), ('TK', 'Tokelau'), ('TL', 'East Timor'), ('TM', 'Turkmenistan'), ('TN', 'Tunisia'), ('TO', 'Tonga'), ('TR', 'Turkey'), ('TT', 'Trinidad & Tobago'), ('TV', 'Tuvalu'), ('TW', 'Taiwan'), ('TZ', 'Tanzania'), ('UA', 'Ukraine'), ('UG', 'Uganda'), ('UM', 'US minor outlying islands'), ('US', 'United States'), ('UY', 'Uruguay'), ('UZ', 'Uzbekistan'), ('VA', 'Vatican City'), ('VC', 'St Vincent'), ('VE', 'Venezuela'), ('VG', 'Virgin Islands (UK)'), ('VI', 'Virgin Islands (US)'), ('VN', 'Vietnam'), ('VU', 'Vanuatu'), ('WF', 'Wallis & Futuna'), ('WS', 'Samoa (western)'), ('YE', 'Yemen'), ('YT', 'Mayotte'), ('ZA', 'South Africa'), ('ZM', 'Zambia'), ('ZW', 'Zimbabwe')], default=servo.defaults.country, max_length=2, verbose_name='Country'), + ), + migrations.AlterField( + model_name='location', + name='timezone', + field=models.CharField(choices=[(b'Africa/Abidjan', b'Africa/Abidjan'), (b'Africa/Accra', b'Africa/Accra'), (b'Africa/Addis_Ababa', b'Africa/Addis_Ababa'), (b'Africa/Algiers', b'Africa/Algiers'), (b'Africa/Asmara', b'Africa/Asmara'), (b'Africa/Bamako', b'Africa/Bamako'), (b'Africa/Bangui', b'Africa/Bangui'), (b'Africa/Banjul', b'Africa/Banjul'), (b'Africa/Bissau', b'Africa/Bissau'), (b'Africa/Blantyre', b'Africa/Blantyre'), (b'Africa/Brazzaville', b'Africa/Brazzaville'), (b'Africa/Bujumbura', b'Africa/Bujumbura'), (b'Africa/Cairo', b'Africa/Cairo'), (b'Africa/Casablanca', b'Africa/Casablanca'), (b'Africa/Ceuta', b'Africa/Ceuta'), (b'Africa/Conakry', b'Africa/Conakry'), (b'Africa/Dakar', b'Africa/Dakar'), (b'Africa/Dar_es_Salaam', b'Africa/Dar_es_Salaam'), (b'Africa/Djibouti', b'Africa/Djibouti'), (b'Africa/Douala', b'Africa/Douala'), (b'Africa/El_Aaiun', b'Africa/El_Aaiun'), (b'Africa/Freetown', b'Africa/Freetown'), (b'Africa/Gaborone', b'Africa/Gaborone'), (b'Africa/Harare', b'Africa/Harare'), (b'Africa/Johannesburg', b'Africa/Johannesburg'), (b'Africa/Juba', b'Africa/Juba'), (b'Africa/Kampala', b'Africa/Kampala'), (b'Africa/Khartoum', b'Africa/Khartoum'), (b'Africa/Kigali', b'Africa/Kigali'), (b'Africa/Kinshasa', b'Africa/Kinshasa'), (b'Africa/Lagos', b'Africa/Lagos'), (b'Africa/Libreville', b'Africa/Libreville'), (b'Africa/Lome', b'Africa/Lome'), (b'Africa/Luanda', b'Africa/Luanda'), (b'Africa/Lubumbashi', b'Africa/Lubumbashi'), (b'Africa/Lusaka', b'Africa/Lusaka'), (b'Africa/Malabo', b'Africa/Malabo'), (b'Africa/Maputo', b'Africa/Maputo'), (b'Africa/Maseru', b'Africa/Maseru'), (b'Africa/Mbabane', b'Africa/Mbabane'), (b'Africa/Mogadishu', b'Africa/Mogadishu'), (b'Africa/Monrovia', b'Africa/Monrovia'), (b'Africa/Nairobi', b'Africa/Nairobi'), (b'Africa/Ndjamena', b'Africa/Ndjamena'), (b'Africa/Niamey', b'Africa/Niamey'), (b'Africa/Nouakchott', b'Africa/Nouakchott'), (b'Africa/Ouagadougou', b'Africa/Ouagadougou'), (b'Africa/Porto-Novo', b'Africa/Porto-Novo'), (b'Africa/Sao_Tome', b'Africa/Sao_Tome'), (b'Africa/Tripoli', b'Africa/Tripoli'), (b'Africa/Tunis', b'Africa/Tunis'), (b'Africa/Windhoek', b'Africa/Windhoek'), (b'America/Adak', b'America/Adak'), (b'America/Anchorage', b'America/Anchorage'), (b'America/Anguilla', b'America/Anguilla'), (b'America/Antigua', b'America/Antigua'), (b'America/Araguaina', b'America/Araguaina'), (b'America/Argentina/Buenos_Aires', b'America/Argentina/Buenos_Aires'), (b'America/Argentina/Catamarca', b'America/Argentina/Catamarca'), (b'America/Argentina/Cordoba', b'America/Argentina/Cordoba'), (b'America/Argentina/Jujuy', b'America/Argentina/Jujuy'), (b'America/Argentina/La_Rioja', b'America/Argentina/La_Rioja'), (b'America/Argentina/Mendoza', b'America/Argentina/Mendoza'), (b'America/Argentina/Rio_Gallegos', b'America/Argentina/Rio_Gallegos'), (b'America/Argentina/Salta', b'America/Argentina/Salta'), (b'America/Argentina/San_Juan', b'America/Argentina/San_Juan'), (b'America/Argentina/San_Luis', b'America/Argentina/San_Luis'), (b'America/Argentina/Tucuman', b'America/Argentina/Tucuman'), (b'America/Argentina/Ushuaia', b'America/Argentina/Ushuaia'), (b'America/Aruba', b'America/Aruba'), (b'America/Asuncion', b'America/Asuncion'), (b'America/Atikokan', b'America/Atikokan'), (b'America/Bahia', b'America/Bahia'), (b'America/Bahia_Banderas', b'America/Bahia_Banderas'), (b'America/Barbados', b'America/Barbados'), (b'America/Belem', b'America/Belem'), (b'America/Belize', b'America/Belize'), (b'America/Blanc-Sablon', b'America/Blanc-Sablon'), (b'America/Boa_Vista', b'America/Boa_Vista'), (b'America/Bogota', b'America/Bogota'), (b'America/Boise', b'America/Boise'), (b'America/Cambridge_Bay', b'America/Cambridge_Bay'), (b'America/Campo_Grande', b'America/Campo_Grande'), (b'America/Cancun', b'America/Cancun'), (b'America/Caracas', b'America/Caracas'), (b'America/Cayenne', b'America/Cayenne'), (b'America/Cayman', b'America/Cayman'), (b'America/Chicago', b'America/Chicago'), (b'America/Chihuahua', b'America/Chihuahua'), (b'America/Costa_Rica', b'America/Costa_Rica'), (b'America/Creston', b'America/Creston'), (b'America/Cuiaba', b'America/Cuiaba'), (b'America/Curacao', b'America/Curacao'), (b'America/Danmarkshavn', b'America/Danmarkshavn'), (b'America/Dawson', b'America/Dawson'), (b'America/Dawson_Creek', b'America/Dawson_Creek'), (b'America/Denver', b'America/Denver'), (b'America/Detroit', b'America/Detroit'), (b'America/Dominica', b'America/Dominica'), (b'America/Edmonton', b'America/Edmonton'), (b'America/Eirunepe', b'America/Eirunepe'), (b'America/El_Salvador', b'America/El_Salvador'), (b'America/Fort_Nelson', b'America/Fort_Nelson'), (b'America/Fortaleza', b'America/Fortaleza'), (b'America/Glace_Bay', b'America/Glace_Bay'), (b'America/Godthab', b'America/Godthab'), (b'America/Goose_Bay', b'America/Goose_Bay'), (b'America/Grand_Turk', b'America/Grand_Turk'), (b'America/Grenada', b'America/Grenada'), (b'America/Guadeloupe', b'America/Guadeloupe'), (b'America/Guatemala', b'America/Guatemala'), (b'America/Guayaquil', b'America/Guayaquil'), (b'America/Guyana', b'America/Guyana'), (b'America/Halifax', b'America/Halifax'), (b'America/Havana', b'America/Havana'), (b'America/Hermosillo', b'America/Hermosillo'), (b'America/Indiana/Indianapolis', b'America/Indiana/Indianapolis'), (b'America/Indiana/Knox', b'America/Indiana/Knox'), (b'America/Indiana/Marengo', b'America/Indiana/Marengo'), (b'America/Indiana/Petersburg', b'America/Indiana/Petersburg'), (b'America/Indiana/Tell_City', b'America/Indiana/Tell_City'), (b'America/Indiana/Vevay', b'America/Indiana/Vevay'), (b'America/Indiana/Vincennes', b'America/Indiana/Vincennes'), (b'America/Indiana/Winamac', b'America/Indiana/Winamac'), (b'America/Inuvik', b'America/Inuvik'), (b'America/Iqaluit', b'America/Iqaluit'), (b'America/Jamaica', b'America/Jamaica'), (b'America/Juneau', b'America/Juneau'), (b'America/Kentucky/Louisville', b'America/Kentucky/Louisville'), (b'America/Kentucky/Monticello', b'America/Kentucky/Monticello'), (b'America/Kralendijk', b'America/Kralendijk'), (b'America/La_Paz', b'America/La_Paz'), (b'America/Lima', b'America/Lima'), (b'America/Los_Angeles', b'America/Los_Angeles'), (b'America/Lower_Princes', b'America/Lower_Princes'), (b'America/Maceio', b'America/Maceio'), (b'America/Managua', b'America/Managua'), (b'America/Manaus', b'America/Manaus'), (b'America/Marigot', b'America/Marigot'), (b'America/Martinique', b'America/Martinique'), (b'America/Matamoros', b'America/Matamoros'), (b'America/Mazatlan', b'America/Mazatlan'), (b'America/Menominee', b'America/Menominee'), (b'America/Merida', b'America/Merida'), (b'America/Metlakatla', b'America/Metlakatla'), (b'America/Mexico_City', b'America/Mexico_City'), (b'America/Miquelon', b'America/Miquelon'), (b'America/Moncton', b'America/Moncton'), (b'America/Monterrey', b'America/Monterrey'), (b'America/Montevideo', b'America/Montevideo'), (b'America/Montserrat', b'America/Montserrat'), (b'America/Nassau', b'America/Nassau'), (b'America/New_York', b'America/New_York'), (b'America/Nipigon', b'America/Nipigon'), (b'America/Nome', b'America/Nome'), (b'America/Noronha', b'America/Noronha'), (b'America/North_Dakota/Beulah', b'America/North_Dakota/Beulah'), (b'America/North_Dakota/Center', b'America/North_Dakota/Center'), (b'America/North_Dakota/New_Salem', b'America/North_Dakota/New_Salem'), (b'America/Ojinaga', b'America/Ojinaga'), (b'America/Panama', b'America/Panama'), (b'America/Pangnirtung', b'America/Pangnirtung'), (b'America/Paramaribo', b'America/Paramaribo'), (b'America/Phoenix', b'America/Phoenix'), (b'America/Port-au-Prince', b'America/Port-au-Prince'), (b'America/Port_of_Spain', b'America/Port_of_Spain'), (b'America/Porto_Velho', b'America/Porto_Velho'), (b'America/Puerto_Rico', b'America/Puerto_Rico'), (b'America/Rainy_River', b'America/Rainy_River'), (b'America/Rankin_Inlet', b'America/Rankin_Inlet'), (b'America/Recife', b'America/Recife'), (b'America/Regina', b'America/Regina'), (b'America/Resolute', b'America/Resolute'), (b'America/Rio_Branco', b'America/Rio_Branco'), (b'America/Santarem', b'America/Santarem'), (b'America/Santiago', b'America/Santiago'), (b'America/Santo_Domingo', b'America/Santo_Domingo'), (b'America/Sao_Paulo', b'America/Sao_Paulo'), (b'America/Scoresbysund', b'America/Scoresbysund'), (b'America/Sitka', b'America/Sitka'), (b'America/St_Barthelemy', b'America/St_Barthelemy'), (b'America/St_Johns', b'America/St_Johns'), (b'America/St_Kitts', b'America/St_Kitts'), (b'America/St_Lucia', b'America/St_Lucia'), (b'America/St_Thomas', b'America/St_Thomas'), (b'America/St_Vincent', b'America/St_Vincent'), (b'America/Swift_Current', b'America/Swift_Current'), (b'America/Tegucigalpa', b'America/Tegucigalpa'), (b'America/Thule', b'America/Thule'), (b'America/Thunder_Bay', b'America/Thunder_Bay'), (b'America/Tijuana', b'America/Tijuana'), (b'America/Toronto', b'America/Toronto'), (b'America/Tortola', b'America/Tortola'), (b'America/Vancouver', b'America/Vancouver'), (b'America/Whitehorse', b'America/Whitehorse'), (b'America/Winnipeg', b'America/Winnipeg'), (b'America/Yakutat', b'America/Yakutat'), (b'America/Yellowknife', b'America/Yellowknife'), (b'Antarctica/Casey', b'Antarctica/Casey'), (b'Antarctica/Davis', b'Antarctica/Davis'), (b'Antarctica/DumontDUrville', b'Antarctica/DumontDUrville'), (b'Antarctica/Macquarie', b'Antarctica/Macquarie'), (b'Antarctica/Mawson', b'Antarctica/Mawson'), (b'Antarctica/McMurdo', b'Antarctica/McMurdo'), (b'Antarctica/Palmer', b'Antarctica/Palmer'), (b'Antarctica/Rothera', b'Antarctica/Rothera'), (b'Antarctica/Syowa', b'Antarctica/Syowa'), (b'Antarctica/Troll', b'Antarctica/Troll'), (b'Antarctica/Vostok', b'Antarctica/Vostok'), (b'Arctic/Longyearbyen', b'Arctic/Longyearbyen'), (b'Asia/Aden', b'Asia/Aden'), (b'Asia/Almaty', b'Asia/Almaty'), (b'Asia/Amman', b'Asia/Amman'), (b'Asia/Anadyr', b'Asia/Anadyr'), (b'Asia/Aqtau', b'Asia/Aqtau'), (b'Asia/Aqtobe', b'Asia/Aqtobe'), (b'Asia/Ashgabat', b'Asia/Ashgabat'), (b'Asia/Baghdad', b'Asia/Baghdad'), (b'Asia/Bahrain', b'Asia/Bahrain'), (b'Asia/Baku', b'Asia/Baku'), (b'Asia/Bangkok', b'Asia/Bangkok'), (b'Asia/Barnaul', b'Asia/Barnaul'), (b'Asia/Beirut', b'Asia/Beirut'), (b'Asia/Bishkek', b'Asia/Bishkek'), (b'Asia/Brunei', b'Asia/Brunei'), (b'Asia/Chita', b'Asia/Chita'), (b'Asia/Choibalsan', b'Asia/Choibalsan'), (b'Asia/Colombo', b'Asia/Colombo'), (b'Asia/Damascus', b'Asia/Damascus'), (b'Asia/Dhaka', b'Asia/Dhaka'), (b'Asia/Dili', b'Asia/Dili'), (b'Asia/Dubai', b'Asia/Dubai'), (b'Asia/Dushanbe', b'Asia/Dushanbe'), (b'Asia/Gaza', b'Asia/Gaza'), (b'Asia/Hebron', b'Asia/Hebron'), (b'Asia/Ho_Chi_Minh', b'Asia/Ho_Chi_Minh'), (b'Asia/Hong_Kong', b'Asia/Hong_Kong'), (b'Asia/Hovd', b'Asia/Hovd'), (b'Asia/Irkutsk', b'Asia/Irkutsk'), (b'Asia/Jakarta', b'Asia/Jakarta'), (b'Asia/Jayapura', b'Asia/Jayapura'), (b'Asia/Jerusalem', b'Asia/Jerusalem'), (b'Asia/Kabul', b'Asia/Kabul'), (b'Asia/Kamchatka', b'Asia/Kamchatka'), (b'Asia/Karachi', b'Asia/Karachi'), (b'Asia/Kathmandu', b'Asia/Kathmandu'), (b'Asia/Khandyga', b'Asia/Khandyga'), (b'Asia/Kolkata', b'Asia/Kolkata'), (b'Asia/Krasnoyarsk', b'Asia/Krasnoyarsk'), (b'Asia/Kuala_Lumpur', b'Asia/Kuala_Lumpur'), (b'Asia/Kuching', b'Asia/Kuching'), (b'Asia/Kuwait', b'Asia/Kuwait'), (b'Asia/Macau', b'Asia/Macau'), (b'Asia/Magadan', b'Asia/Magadan'), (b'Asia/Makassar', b'Asia/Makassar'), (b'Asia/Manila', b'Asia/Manila'), (b'Asia/Muscat', b'Asia/Muscat'), (b'Asia/Nicosia', b'Asia/Nicosia'), (b'Asia/Novokuznetsk', b'Asia/Novokuznetsk'), (b'Asia/Novosibirsk', b'Asia/Novosibirsk'), (b'Asia/Omsk', b'Asia/Omsk'), (b'Asia/Oral', b'Asia/Oral'), (b'Asia/Phnom_Penh', b'Asia/Phnom_Penh'), (b'Asia/Pontianak', b'Asia/Pontianak'), (b'Asia/Pyongyang', b'Asia/Pyongyang'), (b'Asia/Qatar', b'Asia/Qatar'), (b'Asia/Qyzylorda', b'Asia/Qyzylorda'), (b'Asia/Rangoon', b'Asia/Rangoon'), (b'Asia/Riyadh', b'Asia/Riyadh'), (b'Asia/Sakhalin', b'Asia/Sakhalin'), (b'Asia/Samarkand', b'Asia/Samarkand'), (b'Asia/Seoul', b'Asia/Seoul'), (b'Asia/Shanghai', b'Asia/Shanghai'), (b'Asia/Singapore', b'Asia/Singapore'), (b'Asia/Srednekolymsk', b'Asia/Srednekolymsk'), (b'Asia/Taipei', b'Asia/Taipei'), (b'Asia/Tashkent', b'Asia/Tashkent'), (b'Asia/Tbilisi', b'Asia/Tbilisi'), (b'Asia/Tehran', b'Asia/Tehran'), (b'Asia/Thimphu', b'Asia/Thimphu'), (b'Asia/Tokyo', b'Asia/Tokyo'), (b'Asia/Ulaanbaatar', b'Asia/Ulaanbaatar'), (b'Asia/Urumqi', b'Asia/Urumqi'), (b'Asia/Ust-Nera', b'Asia/Ust-Nera'), (b'Asia/Vientiane', b'Asia/Vientiane'), (b'Asia/Vladivostok', b'Asia/Vladivostok'), (b'Asia/Yakutsk', b'Asia/Yakutsk'), (b'Asia/Yekaterinburg', b'Asia/Yekaterinburg'), (b'Asia/Yerevan', b'Asia/Yerevan'), (b'Atlantic/Azores', b'Atlantic/Azores'), (b'Atlantic/Bermuda', b'Atlantic/Bermuda'), (b'Atlantic/Canary', b'Atlantic/Canary'), (b'Atlantic/Cape_Verde', b'Atlantic/Cape_Verde'), (b'Atlantic/Faroe', b'Atlantic/Faroe'), (b'Atlantic/Madeira', b'Atlantic/Madeira'), (b'Atlantic/Reykjavik', b'Atlantic/Reykjavik'), (b'Atlantic/South_Georgia', b'Atlantic/South_Georgia'), (b'Atlantic/St_Helena', b'Atlantic/St_Helena'), (b'Atlantic/Stanley', b'Atlantic/Stanley'), (b'Australia/Adelaide', b'Australia/Adelaide'), (b'Australia/Brisbane', b'Australia/Brisbane'), (b'Australia/Broken_Hill', b'Australia/Broken_Hill'), (b'Australia/Currie', b'Australia/Currie'), (b'Australia/Darwin', b'Australia/Darwin'), (b'Australia/Eucla', b'Australia/Eucla'), (b'Australia/Hobart', b'Australia/Hobart'), (b'Australia/Lindeman', b'Australia/Lindeman'), (b'Australia/Lord_Howe', b'Australia/Lord_Howe'), (b'Australia/Melbourne', b'Australia/Melbourne'), (b'Australia/Perth', b'Australia/Perth'), (b'Australia/Sydney', b'Australia/Sydney'), (b'Canada/Atlantic', b'Canada/Atlantic'), (b'Canada/Central', b'Canada/Central'), (b'Canada/Eastern', b'Canada/Eastern'), (b'Canada/Mountain', b'Canada/Mountain'), (b'Canada/Newfoundland', b'Canada/Newfoundland'), (b'Canada/Pacific', b'Canada/Pacific'), (b'Europe/Amsterdam', b'Europe/Amsterdam'), (b'Europe/Andorra', b'Europe/Andorra'), (b'Europe/Astrakhan', b'Europe/Astrakhan'), (b'Europe/Athens', b'Europe/Athens'), (b'Europe/Belgrade', b'Europe/Belgrade'), (b'Europe/Berlin', b'Europe/Berlin'), (b'Europe/Bratislava', b'Europe/Bratislava'), (b'Europe/Brussels', b'Europe/Brussels'), (b'Europe/Bucharest', b'Europe/Bucharest'), (b'Europe/Budapest', b'Europe/Budapest'), (b'Europe/Busingen', b'Europe/Busingen'), (b'Europe/Chisinau', b'Europe/Chisinau'), (b'Europe/Copenhagen', b'Europe/Copenhagen'), (b'Europe/Dublin', b'Europe/Dublin'), (b'Europe/Gibraltar', b'Europe/Gibraltar'), (b'Europe/Guernsey', b'Europe/Guernsey'), (b'Europe/Helsinki', b'Europe/Helsinki'), (b'Europe/Isle_of_Man', b'Europe/Isle_of_Man'), (b'Europe/Istanbul', b'Europe/Istanbul'), (b'Europe/Jersey', b'Europe/Jersey'), (b'Europe/Kaliningrad', b'Europe/Kaliningrad'), (b'Europe/Kiev', b'Europe/Kiev'), (b'Europe/Lisbon', b'Europe/Lisbon'), (b'Europe/Ljubljana', b'Europe/Ljubljana'), (b'Europe/London', b'Europe/London'), (b'Europe/Luxembourg', b'Europe/Luxembourg'), (b'Europe/Madrid', b'Europe/Madrid'), (b'Europe/Malta', b'Europe/Malta'), (b'Europe/Mariehamn', b'Europe/Mariehamn'), (b'Europe/Minsk', b'Europe/Minsk'), (b'Europe/Monaco', b'Europe/Monaco'), (b'Europe/Moscow', b'Europe/Moscow'), (b'Europe/Oslo', b'Europe/Oslo'), (b'Europe/Paris', b'Europe/Paris'), (b'Europe/Podgorica', b'Europe/Podgorica'), (b'Europe/Prague', b'Europe/Prague'), (b'Europe/Riga', b'Europe/Riga'), (b'Europe/Rome', b'Europe/Rome'), (b'Europe/Samara', b'Europe/Samara'), (b'Europe/San_Marino', b'Europe/San_Marino'), (b'Europe/Sarajevo', b'Europe/Sarajevo'), (b'Europe/Simferopol', b'Europe/Simferopol'), (b'Europe/Skopje', b'Europe/Skopje'), (b'Europe/Sofia', b'Europe/Sofia'), (b'Europe/Stockholm', b'Europe/Stockholm'), (b'Europe/Tallinn', b'Europe/Tallinn'), (b'Europe/Tirane', b'Europe/Tirane'), (b'Europe/Ulyanovsk', b'Europe/Ulyanovsk'), (b'Europe/Uzhgorod', b'Europe/Uzhgorod'), (b'Europe/Vaduz', b'Europe/Vaduz'), (b'Europe/Vatican', b'Europe/Vatican'), (b'Europe/Vienna', b'Europe/Vienna'), (b'Europe/Vilnius', b'Europe/Vilnius'), (b'Europe/Volgograd', b'Europe/Volgograd'), (b'Europe/Warsaw', b'Europe/Warsaw'), (b'Europe/Zagreb', b'Europe/Zagreb'), (b'Europe/Zaporozhye', b'Europe/Zaporozhye'), (b'Europe/Zurich', b'Europe/Zurich'), (b'GMT', b'GMT'), (b'Indian/Antananarivo', b'Indian/Antananarivo'), (b'Indian/Chagos', b'Indian/Chagos'), (b'Indian/Christmas', b'Indian/Christmas'), (b'Indian/Cocos', b'Indian/Cocos'), (b'Indian/Comoro', b'Indian/Comoro'), (b'Indian/Kerguelen', b'Indian/Kerguelen'), (b'Indian/Mahe', b'Indian/Mahe'), (b'Indian/Maldives', b'Indian/Maldives'), (b'Indian/Mauritius', b'Indian/Mauritius'), (b'Indian/Mayotte', b'Indian/Mayotte'), (b'Indian/Reunion', b'Indian/Reunion'), (b'Pacific/Apia', b'Pacific/Apia'), (b'Pacific/Auckland', b'Pacific/Auckland'), (b'Pacific/Bougainville', b'Pacific/Bougainville'), (b'Pacific/Chatham', b'Pacific/Chatham'), (b'Pacific/Chuuk', b'Pacific/Chuuk'), (b'Pacific/Easter', b'Pacific/Easter'), (b'Pacific/Efate', b'Pacific/Efate'), (b'Pacific/Enderbury', b'Pacific/Enderbury'), (b'Pacific/Fakaofo', b'Pacific/Fakaofo'), (b'Pacific/Fiji', b'Pacific/Fiji'), (b'Pacific/Funafuti', b'Pacific/Funafuti'), (b'Pacific/Galapagos', b'Pacific/Galapagos'), (b'Pacific/Gambier', b'Pacific/Gambier'), (b'Pacific/Guadalcanal', b'Pacific/Guadalcanal'), (b'Pacific/Guam', b'Pacific/Guam'), (b'Pacific/Honolulu', b'Pacific/Honolulu'), (b'Pacific/Johnston', b'Pacific/Johnston'), (b'Pacific/Kiritimati', b'Pacific/Kiritimati'), (b'Pacific/Kosrae', b'Pacific/Kosrae'), (b'Pacific/Kwajalein', b'Pacific/Kwajalein'), (b'Pacific/Majuro', b'Pacific/Majuro'), (b'Pacific/Marquesas', b'Pacific/Marquesas'), (b'Pacific/Midway', b'Pacific/Midway'), (b'Pacific/Nauru', b'Pacific/Nauru'), (b'Pacific/Niue', b'Pacific/Niue'), (b'Pacific/Norfolk', b'Pacific/Norfolk'), (b'Pacific/Noumea', b'Pacific/Noumea'), (b'Pacific/Pago_Pago', b'Pacific/Pago_Pago'), (b'Pacific/Palau', b'Pacific/Palau'), (b'Pacific/Pitcairn', b'Pacific/Pitcairn'), (b'Pacific/Pohnpei', b'Pacific/Pohnpei'), (b'Pacific/Port_Moresby', b'Pacific/Port_Moresby'), (b'Pacific/Rarotonga', b'Pacific/Rarotonga'), (b'Pacific/Saipan', b'Pacific/Saipan'), (b'Pacific/Tahiti', b'Pacific/Tahiti'), (b'Pacific/Tarawa', b'Pacific/Tarawa'), (b'Pacific/Tongatapu', b'Pacific/Tongatapu'), (b'Pacific/Wake', b'Pacific/Wake'), (b'Pacific/Wallis', b'Pacific/Wallis'), (b'US/Alaska', b'US/Alaska'), (b'US/Arizona', b'US/Arizona'), (b'US/Central', b'US/Central'), (b'US/Eastern', b'US/Eastern'), (b'US/Hawaii', b'US/Hawaii'), (b'US/Mountain', b'US/Mountain'), (b'US/Pacific', b'US/Pacific'), (b'UTC', b'UTC')], default=b'UTC', max_length=128, verbose_name='Time zone'), + ), + migrations.AlterField( + model_name='user', + name='timezone', + field=models.CharField(choices=[(b'Africa/Abidjan', b'Africa/Abidjan'), (b'Africa/Accra', b'Africa/Accra'), (b'Africa/Addis_Ababa', b'Africa/Addis_Ababa'), (b'Africa/Algiers', b'Africa/Algiers'), (b'Africa/Asmara', b'Africa/Asmara'), (b'Africa/Bamako', b'Africa/Bamako'), (b'Africa/Bangui', b'Africa/Bangui'), (b'Africa/Banjul', b'Africa/Banjul'), (b'Africa/Bissau', b'Africa/Bissau'), (b'Africa/Blantyre', b'Africa/Blantyre'), (b'Africa/Brazzaville', b'Africa/Brazzaville'), (b'Africa/Bujumbura', b'Africa/Bujumbura'), (b'Africa/Cairo', b'Africa/Cairo'), (b'Africa/Casablanca', b'Africa/Casablanca'), (b'Africa/Ceuta', b'Africa/Ceuta'), (b'Africa/Conakry', b'Africa/Conakry'), (b'Africa/Dakar', b'Africa/Dakar'), (b'Africa/Dar_es_Salaam', b'Africa/Dar_es_Salaam'), (b'Africa/Djibouti', b'Africa/Djibouti'), (b'Africa/Douala', b'Africa/Douala'), (b'Africa/El_Aaiun', b'Africa/El_Aaiun'), (b'Africa/Freetown', b'Africa/Freetown'), (b'Africa/Gaborone', b'Africa/Gaborone'), (b'Africa/Harare', b'Africa/Harare'), (b'Africa/Johannesburg', b'Africa/Johannesburg'), (b'Africa/Juba', b'Africa/Juba'), (b'Africa/Kampala', b'Africa/Kampala'), (b'Africa/Khartoum', b'Africa/Khartoum'), (b'Africa/Kigali', b'Africa/Kigali'), (b'Africa/Kinshasa', b'Africa/Kinshasa'), (b'Africa/Lagos', b'Africa/Lagos'), (b'Africa/Libreville', b'Africa/Libreville'), (b'Africa/Lome', b'Africa/Lome'), (b'Africa/Luanda', b'Africa/Luanda'), (b'Africa/Lubumbashi', b'Africa/Lubumbashi'), (b'Africa/Lusaka', b'Africa/Lusaka'), (b'Africa/Malabo', b'Africa/Malabo'), (b'Africa/Maputo', b'Africa/Maputo'), (b'Africa/Maseru', b'Africa/Maseru'), (b'Africa/Mbabane', b'Africa/Mbabane'), (b'Africa/Mogadishu', b'Africa/Mogadishu'), (b'Africa/Monrovia', b'Africa/Monrovia'), (b'Africa/Nairobi', b'Africa/Nairobi'), (b'Africa/Ndjamena', b'Africa/Ndjamena'), (b'Africa/Niamey', b'Africa/Niamey'), (b'Africa/Nouakchott', b'Africa/Nouakchott'), (b'Africa/Ouagadougou', b'Africa/Ouagadougou'), (b'Africa/Porto-Novo', b'Africa/Porto-Novo'), (b'Africa/Sao_Tome', b'Africa/Sao_Tome'), (b'Africa/Tripoli', b'Africa/Tripoli'), (b'Africa/Tunis', b'Africa/Tunis'), (b'Africa/Windhoek', b'Africa/Windhoek'), (b'America/Adak', b'America/Adak'), (b'America/Anchorage', b'America/Anchorage'), (b'America/Anguilla', b'America/Anguilla'), (b'America/Antigua', b'America/Antigua'), (b'America/Araguaina', b'America/Araguaina'), (b'America/Argentina/Buenos_Aires', b'America/Argentina/Buenos_Aires'), (b'America/Argentina/Catamarca', b'America/Argentina/Catamarca'), (b'America/Argentina/Cordoba', b'America/Argentina/Cordoba'), (b'America/Argentina/Jujuy', b'America/Argentina/Jujuy'), (b'America/Argentina/La_Rioja', b'America/Argentina/La_Rioja'), (b'America/Argentina/Mendoza', b'America/Argentina/Mendoza'), (b'America/Argentina/Rio_Gallegos', b'America/Argentina/Rio_Gallegos'), (b'America/Argentina/Salta', b'America/Argentina/Salta'), (b'America/Argentina/San_Juan', b'America/Argentina/San_Juan'), (b'America/Argentina/San_Luis', b'America/Argentina/San_Luis'), (b'America/Argentina/Tucuman', b'America/Argentina/Tucuman'), (b'America/Argentina/Ushuaia', b'America/Argentina/Ushuaia'), (b'America/Aruba', b'America/Aruba'), (b'America/Asuncion', b'America/Asuncion'), (b'America/Atikokan', b'America/Atikokan'), (b'America/Bahia', b'America/Bahia'), (b'America/Bahia_Banderas', b'America/Bahia_Banderas'), (b'America/Barbados', b'America/Barbados'), (b'America/Belem', b'America/Belem'), (b'America/Belize', b'America/Belize'), (b'America/Blanc-Sablon', b'America/Blanc-Sablon'), (b'America/Boa_Vista', b'America/Boa_Vista'), (b'America/Bogota', b'America/Bogota'), (b'America/Boise', b'America/Boise'), (b'America/Cambridge_Bay', b'America/Cambridge_Bay'), (b'America/Campo_Grande', b'America/Campo_Grande'), (b'America/Cancun', b'America/Cancun'), (b'America/Caracas', b'America/Caracas'), (b'America/Cayenne', b'America/Cayenne'), (b'America/Cayman', b'America/Cayman'), (b'America/Chicago', b'America/Chicago'), (b'America/Chihuahua', b'America/Chihuahua'), (b'America/Costa_Rica', b'America/Costa_Rica'), (b'America/Creston', b'America/Creston'), (b'America/Cuiaba', b'America/Cuiaba'), (b'America/Curacao', b'America/Curacao'), (b'America/Danmarkshavn', b'America/Danmarkshavn'), (b'America/Dawson', b'America/Dawson'), (b'America/Dawson_Creek', b'America/Dawson_Creek'), (b'America/Denver', b'America/Denver'), (b'America/Detroit', b'America/Detroit'), (b'America/Dominica', b'America/Dominica'), (b'America/Edmonton', b'America/Edmonton'), (b'America/Eirunepe', b'America/Eirunepe'), (b'America/El_Salvador', b'America/El_Salvador'), (b'America/Fort_Nelson', b'America/Fort_Nelson'), (b'America/Fortaleza', b'America/Fortaleza'), (b'America/Glace_Bay', b'America/Glace_Bay'), (b'America/Godthab', b'America/Godthab'), (b'America/Goose_Bay', b'America/Goose_Bay'), (b'America/Grand_Turk', b'America/Grand_Turk'), (b'America/Grenada', b'America/Grenada'), (b'America/Guadeloupe', b'America/Guadeloupe'), (b'America/Guatemala', b'America/Guatemala'), (b'America/Guayaquil', b'America/Guayaquil'), (b'America/Guyana', b'America/Guyana'), (b'America/Halifax', b'America/Halifax'), (b'America/Havana', b'America/Havana'), (b'America/Hermosillo', b'America/Hermosillo'), (b'America/Indiana/Indianapolis', b'America/Indiana/Indianapolis'), (b'America/Indiana/Knox', b'America/Indiana/Knox'), (b'America/Indiana/Marengo', b'America/Indiana/Marengo'), (b'America/Indiana/Petersburg', b'America/Indiana/Petersburg'), (b'America/Indiana/Tell_City', b'America/Indiana/Tell_City'), (b'America/Indiana/Vevay', b'America/Indiana/Vevay'), (b'America/Indiana/Vincennes', b'America/Indiana/Vincennes'), (b'America/Indiana/Winamac', b'America/Indiana/Winamac'), (b'America/Inuvik', b'America/Inuvik'), (b'America/Iqaluit', b'America/Iqaluit'), (b'America/Jamaica', b'America/Jamaica'), (b'America/Juneau', b'America/Juneau'), (b'America/Kentucky/Louisville', b'America/Kentucky/Louisville'), (b'America/Kentucky/Monticello', b'America/Kentucky/Monticello'), (b'America/Kralendijk', b'America/Kralendijk'), (b'America/La_Paz', b'America/La_Paz'), (b'America/Lima', b'America/Lima'), (b'America/Los_Angeles', b'America/Los_Angeles'), (b'America/Lower_Princes', b'America/Lower_Princes'), (b'America/Maceio', b'America/Maceio'), (b'America/Managua', b'America/Managua'), (b'America/Manaus', b'America/Manaus'), (b'America/Marigot', b'America/Marigot'), (b'America/Martinique', b'America/Martinique'), (b'America/Matamoros', b'America/Matamoros'), (b'America/Mazatlan', b'America/Mazatlan'), (b'America/Menominee', b'America/Menominee'), (b'America/Merida', b'America/Merida'), (b'America/Metlakatla', b'America/Metlakatla'), (b'America/Mexico_City', b'America/Mexico_City'), (b'America/Miquelon', b'America/Miquelon'), (b'America/Moncton', b'America/Moncton'), (b'America/Monterrey', b'America/Monterrey'), (b'America/Montevideo', b'America/Montevideo'), (b'America/Montserrat', b'America/Montserrat'), (b'America/Nassau', b'America/Nassau'), (b'America/New_York', b'America/New_York'), (b'America/Nipigon', b'America/Nipigon'), (b'America/Nome', b'America/Nome'), (b'America/Noronha', b'America/Noronha'), (b'America/North_Dakota/Beulah', b'America/North_Dakota/Beulah'), (b'America/North_Dakota/Center', b'America/North_Dakota/Center'), (b'America/North_Dakota/New_Salem', b'America/North_Dakota/New_Salem'), (b'America/Ojinaga', b'America/Ojinaga'), (b'America/Panama', b'America/Panama'), (b'America/Pangnirtung', b'America/Pangnirtung'), (b'America/Paramaribo', b'America/Paramaribo'), (b'America/Phoenix', b'America/Phoenix'), (b'America/Port-au-Prince', b'America/Port-au-Prince'), (b'America/Port_of_Spain', b'America/Port_of_Spain'), (b'America/Porto_Velho', b'America/Porto_Velho'), (b'America/Puerto_Rico', b'America/Puerto_Rico'), (b'America/Rainy_River', b'America/Rainy_River'), (b'America/Rankin_Inlet', b'America/Rankin_Inlet'), (b'America/Recife', b'America/Recife'), (b'America/Regina', b'America/Regina'), (b'America/Resolute', b'America/Resolute'), (b'America/Rio_Branco', b'America/Rio_Branco'), (b'America/Santarem', b'America/Santarem'), (b'America/Santiago', b'America/Santiago'), (b'America/Santo_Domingo', b'America/Santo_Domingo'), (b'America/Sao_Paulo', b'America/Sao_Paulo'), (b'America/Scoresbysund', b'America/Scoresbysund'), (b'America/Sitka', b'America/Sitka'), (b'America/St_Barthelemy', b'America/St_Barthelemy'), (b'America/St_Johns', b'America/St_Johns'), (b'America/St_Kitts', b'America/St_Kitts'), (b'America/St_Lucia', b'America/St_Lucia'), (b'America/St_Thomas', b'America/St_Thomas'), (b'America/St_Vincent', b'America/St_Vincent'), (b'America/Swift_Current', b'America/Swift_Current'), (b'America/Tegucigalpa', b'America/Tegucigalpa'), (b'America/Thule', b'America/Thule'), (b'America/Thunder_Bay', b'America/Thunder_Bay'), (b'America/Tijuana', b'America/Tijuana'), (b'America/Toronto', b'America/Toronto'), (b'America/Tortola', b'America/Tortola'), (b'America/Vancouver', b'America/Vancouver'), (b'America/Whitehorse', b'America/Whitehorse'), (b'America/Winnipeg', b'America/Winnipeg'), (b'America/Yakutat', b'America/Yakutat'), (b'America/Yellowknife', b'America/Yellowknife'), (b'Antarctica/Casey', b'Antarctica/Casey'), (b'Antarctica/Davis', b'Antarctica/Davis'), (b'Antarctica/DumontDUrville', b'Antarctica/DumontDUrville'), (b'Antarctica/Macquarie', b'Antarctica/Macquarie'), (b'Antarctica/Mawson', b'Antarctica/Mawson'), (b'Antarctica/McMurdo', b'Antarctica/McMurdo'), (b'Antarctica/Palmer', b'Antarctica/Palmer'), (b'Antarctica/Rothera', b'Antarctica/Rothera'), (b'Antarctica/Syowa', b'Antarctica/Syowa'), (b'Antarctica/Troll', b'Antarctica/Troll'), (b'Antarctica/Vostok', b'Antarctica/Vostok'), (b'Arctic/Longyearbyen', b'Arctic/Longyearbyen'), (b'Asia/Aden', b'Asia/Aden'), (b'Asia/Almaty', b'Asia/Almaty'), (b'Asia/Amman', b'Asia/Amman'), (b'Asia/Anadyr', b'Asia/Anadyr'), (b'Asia/Aqtau', b'Asia/Aqtau'), (b'Asia/Aqtobe', b'Asia/Aqtobe'), (b'Asia/Ashgabat', b'Asia/Ashgabat'), (b'Asia/Baghdad', b'Asia/Baghdad'), (b'Asia/Bahrain', b'Asia/Bahrain'), (b'Asia/Baku', b'Asia/Baku'), (b'Asia/Bangkok', b'Asia/Bangkok'), (b'Asia/Barnaul', b'Asia/Barnaul'), (b'Asia/Beirut', b'Asia/Beirut'), (b'Asia/Bishkek', b'Asia/Bishkek'), (b'Asia/Brunei', b'Asia/Brunei'), (b'Asia/Chita', b'Asia/Chita'), (b'Asia/Choibalsan', b'Asia/Choibalsan'), (b'Asia/Colombo', b'Asia/Colombo'), (b'Asia/Damascus', b'Asia/Damascus'), (b'Asia/Dhaka', b'Asia/Dhaka'), (b'Asia/Dili', b'Asia/Dili'), (b'Asia/Dubai', b'Asia/Dubai'), (b'Asia/Dushanbe', b'Asia/Dushanbe'), (b'Asia/Gaza', b'Asia/Gaza'), (b'Asia/Hebron', b'Asia/Hebron'), (b'Asia/Ho_Chi_Minh', b'Asia/Ho_Chi_Minh'), (b'Asia/Hong_Kong', b'Asia/Hong_Kong'), (b'Asia/Hovd', b'Asia/Hovd'), (b'Asia/Irkutsk', b'Asia/Irkutsk'), (b'Asia/Jakarta', b'Asia/Jakarta'), (b'Asia/Jayapura', b'Asia/Jayapura'), (b'Asia/Jerusalem', b'Asia/Jerusalem'), (b'Asia/Kabul', b'Asia/Kabul'), (b'Asia/Kamchatka', b'Asia/Kamchatka'), (b'Asia/Karachi', b'Asia/Karachi'), (b'Asia/Kathmandu', b'Asia/Kathmandu'), (b'Asia/Khandyga', b'Asia/Khandyga'), (b'Asia/Kolkata', b'Asia/Kolkata'), (b'Asia/Krasnoyarsk', b'Asia/Krasnoyarsk'), (b'Asia/Kuala_Lumpur', b'Asia/Kuala_Lumpur'), (b'Asia/Kuching', b'Asia/Kuching'), (b'Asia/Kuwait', b'Asia/Kuwait'), (b'Asia/Macau', b'Asia/Macau'), (b'Asia/Magadan', b'Asia/Magadan'), (b'Asia/Makassar', b'Asia/Makassar'), (b'Asia/Manila', b'Asia/Manila'), (b'Asia/Muscat', b'Asia/Muscat'), (b'Asia/Nicosia', b'Asia/Nicosia'), (b'Asia/Novokuznetsk', b'Asia/Novokuznetsk'), (b'Asia/Novosibirsk', b'Asia/Novosibirsk'), (b'Asia/Omsk', b'Asia/Omsk'), (b'Asia/Oral', b'Asia/Oral'), (b'Asia/Phnom_Penh', b'Asia/Phnom_Penh'), (b'Asia/Pontianak', b'Asia/Pontianak'), (b'Asia/Pyongyang', b'Asia/Pyongyang'), (b'Asia/Qatar', b'Asia/Qatar'), (b'Asia/Qyzylorda', b'Asia/Qyzylorda'), (b'Asia/Rangoon', b'Asia/Rangoon'), (b'Asia/Riyadh', b'Asia/Riyadh'), (b'Asia/Sakhalin', b'Asia/Sakhalin'), (b'Asia/Samarkand', b'Asia/Samarkand'), (b'Asia/Seoul', b'Asia/Seoul'), (b'Asia/Shanghai', b'Asia/Shanghai'), (b'Asia/Singapore', b'Asia/Singapore'), (b'Asia/Srednekolymsk', b'Asia/Srednekolymsk'), (b'Asia/Taipei', b'Asia/Taipei'), (b'Asia/Tashkent', b'Asia/Tashkent'), (b'Asia/Tbilisi', b'Asia/Tbilisi'), (b'Asia/Tehran', b'Asia/Tehran'), (b'Asia/Thimphu', b'Asia/Thimphu'), (b'Asia/Tokyo', b'Asia/Tokyo'), (b'Asia/Ulaanbaatar', b'Asia/Ulaanbaatar'), (b'Asia/Urumqi', b'Asia/Urumqi'), (b'Asia/Ust-Nera', b'Asia/Ust-Nera'), (b'Asia/Vientiane', b'Asia/Vientiane'), (b'Asia/Vladivostok', b'Asia/Vladivostok'), (b'Asia/Yakutsk', b'Asia/Yakutsk'), (b'Asia/Yekaterinburg', b'Asia/Yekaterinburg'), (b'Asia/Yerevan', b'Asia/Yerevan'), (b'Atlantic/Azores', b'Atlantic/Azores'), (b'Atlantic/Bermuda', b'Atlantic/Bermuda'), (b'Atlantic/Canary', b'Atlantic/Canary'), (b'Atlantic/Cape_Verde', b'Atlantic/Cape_Verde'), (b'Atlantic/Faroe', b'Atlantic/Faroe'), (b'Atlantic/Madeira', b'Atlantic/Madeira'), (b'Atlantic/Reykjavik', b'Atlantic/Reykjavik'), (b'Atlantic/South_Georgia', b'Atlantic/South_Georgia'), (b'Atlantic/St_Helena', b'Atlantic/St_Helena'), (b'Atlantic/Stanley', b'Atlantic/Stanley'), (b'Australia/Adelaide', b'Australia/Adelaide'), (b'Australia/Brisbane', b'Australia/Brisbane'), (b'Australia/Broken_Hill', b'Australia/Broken_Hill'), (b'Australia/Currie', b'Australia/Currie'), (b'Australia/Darwin', b'Australia/Darwin'), (b'Australia/Eucla', b'Australia/Eucla'), (b'Australia/Hobart', b'Australia/Hobart'), (b'Australia/Lindeman', b'Australia/Lindeman'), (b'Australia/Lord_Howe', b'Australia/Lord_Howe'), (b'Australia/Melbourne', b'Australia/Melbourne'), (b'Australia/Perth', b'Australia/Perth'), (b'Australia/Sydney', b'Australia/Sydney'), (b'Canada/Atlantic', b'Canada/Atlantic'), (b'Canada/Central', b'Canada/Central'), (b'Canada/Eastern', b'Canada/Eastern'), (b'Canada/Mountain', b'Canada/Mountain'), (b'Canada/Newfoundland', b'Canada/Newfoundland'), (b'Canada/Pacific', b'Canada/Pacific'), (b'Europe/Amsterdam', b'Europe/Amsterdam'), (b'Europe/Andorra', b'Europe/Andorra'), (b'Europe/Astrakhan', b'Europe/Astrakhan'), (b'Europe/Athens', b'Europe/Athens'), (b'Europe/Belgrade', b'Europe/Belgrade'), (b'Europe/Berlin', b'Europe/Berlin'), (b'Europe/Bratislava', b'Europe/Bratislava'), (b'Europe/Brussels', b'Europe/Brussels'), (b'Europe/Bucharest', b'Europe/Bucharest'), (b'Europe/Budapest', b'Europe/Budapest'), (b'Europe/Busingen', b'Europe/Busingen'), (b'Europe/Chisinau', b'Europe/Chisinau'), (b'Europe/Copenhagen', b'Europe/Copenhagen'), (b'Europe/Dublin', b'Europe/Dublin'), (b'Europe/Gibraltar', b'Europe/Gibraltar'), (b'Europe/Guernsey', b'Europe/Guernsey'), (b'Europe/Helsinki', b'Europe/Helsinki'), (b'Europe/Isle_of_Man', b'Europe/Isle_of_Man'), (b'Europe/Istanbul', b'Europe/Istanbul'), (b'Europe/Jersey', b'Europe/Jersey'), (b'Europe/Kaliningrad', b'Europe/Kaliningrad'), (b'Europe/Kiev', b'Europe/Kiev'), (b'Europe/Lisbon', b'Europe/Lisbon'), (b'Europe/Ljubljana', b'Europe/Ljubljana'), (b'Europe/London', b'Europe/London'), (b'Europe/Luxembourg', b'Europe/Luxembourg'), (b'Europe/Madrid', b'Europe/Madrid'), (b'Europe/Malta', b'Europe/Malta'), (b'Europe/Mariehamn', b'Europe/Mariehamn'), (b'Europe/Minsk', b'Europe/Minsk'), (b'Europe/Monaco', b'Europe/Monaco'), (b'Europe/Moscow', b'Europe/Moscow'), (b'Europe/Oslo', b'Europe/Oslo'), (b'Europe/Paris', b'Europe/Paris'), (b'Europe/Podgorica', b'Europe/Podgorica'), (b'Europe/Prague', b'Europe/Prague'), (b'Europe/Riga', b'Europe/Riga'), (b'Europe/Rome', b'Europe/Rome'), (b'Europe/Samara', b'Europe/Samara'), (b'Europe/San_Marino', b'Europe/San_Marino'), (b'Europe/Sarajevo', b'Europe/Sarajevo'), (b'Europe/Simferopol', b'Europe/Simferopol'), (b'Europe/Skopje', b'Europe/Skopje'), (b'Europe/Sofia', b'Europe/Sofia'), (b'Europe/Stockholm', b'Europe/Stockholm'), (b'Europe/Tallinn', b'Europe/Tallinn'), (b'Europe/Tirane', b'Europe/Tirane'), (b'Europe/Ulyanovsk', b'Europe/Ulyanovsk'), (b'Europe/Uzhgorod', b'Europe/Uzhgorod'), (b'Europe/Vaduz', b'Europe/Vaduz'), (b'Europe/Vatican', b'Europe/Vatican'), (b'Europe/Vienna', b'Europe/Vienna'), (b'Europe/Vilnius', b'Europe/Vilnius'), (b'Europe/Volgograd', b'Europe/Volgograd'), (b'Europe/Warsaw', b'Europe/Warsaw'), (b'Europe/Zagreb', b'Europe/Zagreb'), (b'Europe/Zaporozhye', b'Europe/Zaporozhye'), (b'Europe/Zurich', b'Europe/Zurich'), (b'GMT', b'GMT'), (b'Indian/Antananarivo', b'Indian/Antananarivo'), (b'Indian/Chagos', b'Indian/Chagos'), (b'Indian/Christmas', b'Indian/Christmas'), (b'Indian/Cocos', b'Indian/Cocos'), (b'Indian/Comoro', b'Indian/Comoro'), (b'Indian/Kerguelen', b'Indian/Kerguelen'), (b'Indian/Mahe', b'Indian/Mahe'), (b'Indian/Maldives', b'Indian/Maldives'), (b'Indian/Mauritius', b'Indian/Mauritius'), (b'Indian/Mayotte', b'Indian/Mayotte'), (b'Indian/Reunion', b'Indian/Reunion'), (b'Pacific/Apia', b'Pacific/Apia'), (b'Pacific/Auckland', b'Pacific/Auckland'), (b'Pacific/Bougainville', b'Pacific/Bougainville'), (b'Pacific/Chatham', b'Pacific/Chatham'), (b'Pacific/Chuuk', b'Pacific/Chuuk'), (b'Pacific/Easter', b'Pacific/Easter'), (b'Pacific/Efate', b'Pacific/Efate'), (b'Pacific/Enderbury', b'Pacific/Enderbury'), (b'Pacific/Fakaofo', b'Pacific/Fakaofo'), (b'Pacific/Fiji', b'Pacific/Fiji'), (b'Pacific/Funafuti', b'Pacific/Funafuti'), (b'Pacific/Galapagos', b'Pacific/Galapagos'), (b'Pacific/Gambier', b'Pacific/Gambier'), (b'Pacific/Guadalcanal', b'Pacific/Guadalcanal'), (b'Pacific/Guam', b'Pacific/Guam'), (b'Pacific/Honolulu', b'Pacific/Honolulu'), (b'Pacific/Johnston', b'Pacific/Johnston'), (b'Pacific/Kiritimati', b'Pacific/Kiritimati'), (b'Pacific/Kosrae', b'Pacific/Kosrae'), (b'Pacific/Kwajalein', b'Pacific/Kwajalein'), (b'Pacific/Majuro', b'Pacific/Majuro'), (b'Pacific/Marquesas', b'Pacific/Marquesas'), (b'Pacific/Midway', b'Pacific/Midway'), (b'Pacific/Nauru', b'Pacific/Nauru'), (b'Pacific/Niue', b'Pacific/Niue'), (b'Pacific/Norfolk', b'Pacific/Norfolk'), (b'Pacific/Noumea', b'Pacific/Noumea'), (b'Pacific/Pago_Pago', b'Pacific/Pago_Pago'), (b'Pacific/Palau', b'Pacific/Palau'), (b'Pacific/Pitcairn', b'Pacific/Pitcairn'), (b'Pacific/Pohnpei', b'Pacific/Pohnpei'), (b'Pacific/Port_Moresby', b'Pacific/Port_Moresby'), (b'Pacific/Rarotonga', b'Pacific/Rarotonga'), (b'Pacific/Saipan', b'Pacific/Saipan'), (b'Pacific/Tahiti', b'Pacific/Tahiti'), (b'Pacific/Tarawa', b'Pacific/Tarawa'), (b'Pacific/Tongatapu', b'Pacific/Tongatapu'), (b'Pacific/Wake', b'Pacific/Wake'), (b'Pacific/Wallis', b'Pacific/Wallis'), (b'US/Alaska', b'US/Alaska'), (b'US/Arizona', b'US/Arizona'), (b'US/Central', b'US/Central'), (b'US/Eastern', b'US/Eastern'), (b'US/Hawaii', b'US/Hawaii'), (b'US/Mountain', b'US/Mountain'), (b'US/Pacific', b'US/Pacific'), (b'UTC', b'UTC')], default=b'Europe/Tallinn', help_text='Your current timezone', max_length=128, verbose_name='Time zone'), + ), + ] diff --git a/servo/models/note.py b/servo/models/note.py index ed8b944..40ce021 100644 --- a/servo/models/note.py +++ b/servo/models/note.py @@ -24,6 +24,7 @@ from django.contrib.contenttypes.fields import GenericRelation from django.template.defaultfilters import truncatechars from django.db.models.signals import pre_delete, post_save +from django.contrib.postgres.fields import ArrayField from mptt.managers import TreeManager from mptt.models import MPTTModel, TreeForeignKey @@ -144,6 +145,18 @@ class Note(MPTTModel): tpl = template.Template(tpl) return tpl.render(template.Context(ctx)) + def get_sender(self): + return self.sender + + def get_creation_date(self): + return self.created_at + + def get_body(self): + return self.body + + def get_title(self): + return self.subject + def render_subject(self, ctx): """ Renders this Markdown body @@ -162,7 +175,7 @@ class Note(MPTTModel): note.parent = self note.order = self.order note.escalation = self.escalation - + def zip_attachments(self): pass @@ -325,7 +338,7 @@ class Note(MPTTModel): def mailto(self): """ Returns the email recipients of this note - Don't use validate_email because addresses may also be in + Don't use validate_email because addresses may also be in Name format (replies to emails) """ to = [] @@ -395,7 +408,7 @@ class Note(MPTTModel): for f in self.attachments.all(): msg.attach_file(f.content.path) - + msg.send() for r in recipients: @@ -458,9 +471,9 @@ class Note(MPTTModel): if not sms_gw: raise ValueError(_("SMS gateway not configured")) - + msg = Message(note=self, recipient=number, created_by=user, body=self.body) - + if sms_gw == 'hqsms': from servo.messaging.sms import HQSMSProvider HQSMSProvider(number, self, msg).send() @@ -523,7 +536,7 @@ class Note(MPTTModel): self.save() - if len(messages) < 1: + if len(messages) < 1: messages = [_('Note saved')] return ', '.join([force_text(m) for m in messages]) @@ -575,7 +588,7 @@ class Message(models.Model): default=METHODS[0][0] ) error = models.TextField() - + def send(self): result = None self.recipient = self.recipient.strip() @@ -600,6 +613,69 @@ class Message(models.Model): unique_together = ('note', 'recipient') +class Article(models.Model): + """ + GSX Communications article or a bit of local news + """ + created_by = models.ForeignKey(User, null=True) + gsx_id = models.CharField(max_length=20, default='', editable=False) + date_created = models.DateField(editable=False) + date_published = models.DateField(null=True) + title = models.TextField(default=_('New Article')) + summary = models.TextField(default='') + content = models.TextField(default='') + PRIORITY_CHOICES = ( + ('HIGH', _('High')), + ('MEDIUM', _('Medium')), + ('LOW', _('Low')), + ) + priority = models.CharField(max_length=128, + choices=PRIORITY_CHOICES, + default=PRIORITY_CHOICES[0][0] + ) + url = models.URLField(default='') + product_model = ArrayField(models.CharField(max_length=128), + null=True, + editable=False) + read_by = ArrayField(models.IntegerField(), null=True) + flagged_by = ArrayField(models.IntegerField(), null=True) + + def get_creation_date(self): + return self.date_created + + def get_sender(self): + return self.created_by or 'GSX' + + def get_body(self): + return self.title + + def get_title(self): + return self.title + + @classmethod + def from_gsx(cls, article): + """ + Create a local Article from a GSX comms article + """ + from datetime import date + from servo.lib.utils import unescape + aid = article.articleID + + if cls.objects.filter(gsx_id=aid): + raise ValueError('Article %s already exists' % aid) + + a = Article(gsx_id=aid, priority=article.priority) + a.date_created = article.createdDate + a.date_published = date.today() + a.title = unescape(article.articleTitle) + a.summary = unescape(article.articleSummary) + + return a + + class Meta: + app_label = "servo" + + @receiver(pre_delete, sender=Note) def clean_files(sender, instance, **kwargs): instance.attachments.all().delete() @@ -614,4 +690,3 @@ def note_saved(sender, instance, created, **kwargs): if user is not order.user: msg = truncatechars(instance.body, 75) order.notify("note_added", msg, user) - diff --git a/servo/models/order.py b/servo/models/order.py index 8d8eddd..b155f14 100644 --- a/servo/models/order.py +++ b/servo/models/order.py @@ -7,6 +7,7 @@ from django.conf import settings from django.utils import timezone from django.utils.translation import ugettext_lazy as _ +from django.contrib.postgres.fields import ArrayField from django.contrib.contenttypes.fields import GenericRelation from django.dispatch import receiver @@ -1111,9 +1112,16 @@ class OrderDevice(models.Model): order = models.ForeignKey(Order) device = models.ForeignKey(Device) should_report = models.BooleanField(default=True) + repeat_service = models.BooleanField(default=False) + repair_strategies = ArrayField(models.CharField(max_length=100), + help_text='Available repair strategies from GSX', + null=True) def is_repeat_service(self): - from django.utils import timezone + """ + Returns true if this is a repeat (< 30 days from last) service + for this device + """ created_at = self.order.created_at tlimit = timezone.now() - timedelta(days=30) orders = Order.objects.filter(orderdevice__device=self.device, diff --git a/servo/stats/forms.py b/servo/stats/forms.py index e0a3426..ab1b7fc 100644 --- a/servo/stats/forms.py +++ b/servo/stats/forms.py @@ -96,3 +96,14 @@ class NewStatsForm(forms.Form): widget=DatepickerInput(attrs={'class': "input-small"}), initial=default_end_date ) + + +class DeviceStatsForm(forms.Form): + start_date = forms.DateField( + widget=DatepickerInput(attrs={'class': "input-small"}), + initial=default_start_date + ) + end_date = forms.DateField( + widget=DatepickerInput(attrs={'class': "input-small"}), + initial=default_end_date + ) diff --git a/servo/templates/notes/list_notes.html b/servo/templates/notes/list_notes.html index fdbc853..30fdb3d 100755 --- a/servo/templates/notes/list_notes.html +++ b/servo/templates/notes/list_notes.html @@ -35,6 +35,7 @@
    {% endblock note_buttons %} diff --git a/servo/templates/notes/view_note.html b/servo/templates/notes/view_note.html index 05000f6..8f51406 100755 --- a/servo/templates/notes/view_note.html +++ b/servo/templates/notes/view_note.html @@ -8,8 +8,8 @@ {% endblock note_buttons %} diff --git a/servo/urls/note.py b/servo/urls/note.py index 98bf1bb..5f74de3 100644 --- a/servo/urls/note.py +++ b/servo/urls/note.py @@ -19,7 +19,7 @@ urlpatterns = [ name="notes-create_to_customer"), url(r'^(?P\d+)/toggle/tag/(?P\d+)/$', toggle_tag, name="notes-toggle_tag"), - url(r'^(?P\d+)/toggle/(?P[a-z]+)/$', toggle_flag, + url(r'^(?P\w+)/(?P\d+)/toggle_(?P[a-z]+)/$', toggle_flag, name="notes-toggle_flag"), url(r'^(?P\d+)/reply/$', edit, name="notes-reply"), url(r'^(?P\d+)/edit/$', edit, name="notes-edit"), diff --git a/servo/views/note.py b/servo/views/note.py index 416e845..162b297 100644 --- a/servo/views/note.py +++ b/servo/views/note.py @@ -59,8 +59,7 @@ def prep_list_view(request, kind): all_notes = Note.objects.all().order_by("-created_at") if kind == "articles": - all_notes = Article.objects.all() - #all_notes = all_notes.filter(order=None).order_by("is_read", "-created_at") + all_notes = Article.objects.all().order_by('-date_created') if kind == "inbox": all_notes = all_notes.filter(order=None).order_by("is_read", "-created_at") if kind == "sent": @@ -287,7 +286,18 @@ def templates(request, template_id=None): return render(request, 'notes/templates.html', {'templates': templates}) -def toggle_flag(request, pk, flag): +def toggle_flag(request, kind, pk, flag): + if kind == 'articles': + note = get_object_or_404(Article, pk=pk) + if flag == 'flagged': + note.toggle_flagged(request.user) + return HttpResponse(note.get_flagged_title(request.user)) + if flag == 'read': + note.toggle_read(request.user) + return HttpResponse(note.get_read_title(request.user)) + + return HttpResponse(getattr(note, 'get_%s_title' % flag)()) + field = 'is_%s' % flag note = get_object_or_404(Note, pk=pk) attr = getattr(note, field) @@ -318,12 +328,15 @@ def list_notes(request, kind="inbox"): def view_note(request, kind, pk): + data = prep_list_view(request, kind) + if kind == 'articles': note = get_object_or_404(Article, pk=pk) + data['read_title'] = note.get_read_title(request.user) + data['flagged_title'] = note.get_flagged_title(request.user) else: note = get_object_or_404(Note, pk=pk) - data = prep_list_view(request, kind) data['title'] = note.get_title() data['note'] = note -- cgit v1.2.3 From 82e1fe63447f5c4d33d8a3ed7c365e7eab1006c0 Mon Sep 17 00:00:00 2001 From: Filipp Lepalaan Date: Sun, 1 May 2016 19:03:53 +0300 Subject: May '16 GSX update changes --- servo/models/common.py | 4 +++- servo/models/device.py | 15 +++++++++++++-- servo/models/repair.py | 5 +++-- servo/urls/note.py | 2 +- servo/views/api.py | 2 +- servo/views/order.py | 2 +- servo/views/search.py | 7 ++++--- 7 files changed, 26 insertions(+), 11 deletions(-) diff --git a/servo/models/common.py b/servo/models/common.py index 4d91296..7a1c79c 100644 --- a/servo/models/common.py +++ b/servo/models/common.py @@ -223,9 +223,11 @@ class GsxAccount(models.Model): def get_shipto_choices(cls): return cls.objects.values_list('ship_to', 'ship_to') - @classmethod def get_default_account(cls): + """ + Returns the default GSX account without connecting to it + """ from servo.lib.utils import empty act_pk = Configuration.conf('gsx_account') diff --git a/servo/models/device.py b/servo/models/device.py index d422f92..0e244fc 100644 --- a/servo/models/device.py +++ b/servo/models/device.py @@ -289,7 +289,7 @@ class Device(models.Model): return gsxws.Product(self.sn) @classmethod - def from_gsx(cls, sn, device=None, cached=True): + def from_gsx(cls, sn, device=None, cached=True, user=None): """ Initialize new Device with warranty info from GSX Or update existing one @@ -308,7 +308,14 @@ class Device(models.Model): raise ValueError(_(u"Invalid input for warranty check: %s") % sn) product = gsxws.Product(sn) - wty = product.warranty() + + if user and user.location: + ship_to = user.location.gsx_shipto + else: + gsx_act = GsxAccount.get_default_account() + ship_to = gsx_act.ship_to + + wty = product.warranty(ship_to=gsx_act.ship_to) model = product.model() if device is None: @@ -440,6 +447,10 @@ class Device(models.Model): return diags.fetch() def get_warranty(self): + """ + Returns latest warranty info from GSX without + updating the Device record + """ return gsxws.Product(self.sn).warranty() def get_repairs(self): diff --git a/servo/models/repair.py b/servo/models/repair.py index 2836759..93b348d 100644 --- a/servo/models/repair.py +++ b/servo/models/repair.py @@ -285,7 +285,8 @@ class Repair(models.Model): self.connect_gsx(self.created_by) product = gsxws.Product(self.device.sn) parts = [(p.code, p.comptia_code,) for p in self.order.get_parts()] - return product.warranty(parts, self.get_received_date()) + return product.warranty(parts, self.get_received_date(), + ship_to=self.gsx_account.ship_to) def is_open(self): return self.completed_at is None @@ -518,7 +519,7 @@ class Repair(models.Model): User can also be different from the one who initially created the repair. """ account = user or self.created_by - self.gsx_account.connect(account) + return self.gsx_account.connect(account) def set_status(self, new_status, user): """ diff --git a/servo/urls/note.py b/servo/urls/note.py index 5f74de3..e68bba3 100644 --- a/servo/urls/note.py +++ b/servo/urls/note.py @@ -19,7 +19,7 @@ urlpatterns = [ name="notes-create_to_customer"), url(r'^(?P\d+)/toggle/tag/(?P\d+)/$', toggle_tag, name="notes-toggle_tag"), - url(r'^(?P\w+)/(?P\d+)/toggle_(?P[a-z]+)/$', toggle_flag, + url(r'^(?P\w+)?/(?P\d+)/toggle_(?P[a-z]+)/$', toggle_flag, name="notes-toggle_flag"), url(r'^(?P\d+)/reply/$', edit, name="notes-reply"), url(r'^(?P\d+)/edit/$', edit, name="notes-edit"), diff --git a/servo/views/api.py b/servo/views/api.py index 9d2ba76..c8253bc 100644 --- a/servo/views/api.py +++ b/servo/views/api.py @@ -309,7 +309,7 @@ def warranty(request): try: GsxAccount.default(request.user) except Exception as e: - return error('Cannot connect to GSX (check user name and password)') + return error('Cannot connect to GSX (check username and password)') try: result = Device.from_gsx(sn, cached=False) diff --git a/servo/views/order.py b/servo/views/order.py index b4838f7..2ae34a1 100644 --- a/servo/views/order.py +++ b/servo/views/order.py @@ -631,7 +631,7 @@ def device_from_product(request, pk, item_id): try: GsxAccount.default(request.user, order.queue) - device = Device.from_gsx(soi.sn) + device = Device.from_gsx(soi.sn, user=request.user) device.save() event = order.add_device(device, request.user) messages.success(request, event) diff --git a/servo/views/search.py b/servo/views/search.py index 7640839..43f840f 100644 --- a/servo/views/search.py +++ b/servo/views/search.py @@ -21,6 +21,7 @@ from servo.models import (Note, Device, Product, def search_gsx(request, what, param, query): """ The first phase of a GSX search. Sets up the GSX connection. + @TODO: Should this be in Device.from_gsx()? """ title = _(u'Search results for "%s"') % query @@ -62,13 +63,13 @@ def get_gsx_search_results(request, what, param, query): return render(request, "orders/list.html", locals()) if what == "warranty": - # Update wty info if been here before + # Update wty info if device has been serviced before try: device = Device.objects.get(sn__exact=query) device.update_gsx_details() except Exception: try: - device = Device.from_gsx(query) + device = Device.from_gsx(query, user=request.user) except Exception as e: return render(request, error_template, {'message': e}) @@ -117,11 +118,11 @@ def get_gsx_search_results(request, what, param, query): 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 + # @TODO: move the encoding hack to py-gsxws d['customerName'] = p.customerName.encode('utf-8') d['repairStatus'] = p.repairStatus results.append(d) -- cgit v1.2.3