aboutsummaryrefslogtreecommitdiffstats
path: root/servo/views/admin.py
diff options
context:
space:
mode:
authorFilipp Lepalaan <filipp@mac.com>2015-08-04 10:11:24 +0300
committerFilipp Lepalaan <filipp@mac.com>2015-08-04 10:11:24 +0300
commit63b0fc6269b38edf7234b9f151b80d81f614c0a3 (patch)
tree555de3068f33f8dddb4619349bbea7d9b7c822fd /servo/views/admin.py
downloadServo-63b0fc6269b38edf7234b9f151b80d81f614c0a3.tar.gz
Servo-63b0fc6269b38edf7234b9f151b80d81f614c0a3.tar.bz2
Servo-63b0fc6269b38edf7234b9f151b80d81f614c0a3.zip
Initial commit
First public commit
Diffstat (limited to 'servo/views/admin.py')
-rw-r--r--servo/views/admin.py778
1 files changed, 778 insertions, 0 deletions
diff --git a/servo/views/admin.py b/servo/views/admin.py
new file mode 100644
index 0000000..91f73a9
--- /dev/null
+++ b/servo/views/admin.py
@@ -0,0 +1,778 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2013, First Party Software
+# All rights reserved.
+
+# Redistribution and use in source and binary forms, with or without modification,
+# are permitted provided that the following conditions are met:
+
+# 1. Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+
+# 2. Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+# OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+
+import gsxws
+
+from django.db import IntegrityError, transaction
+
+from django.core.cache import cache
+from django.contrib import messages
+from django.shortcuts import render, redirect, get_object_or_404
+
+from django.conf import settings as app_settings
+from django.utils.translation import ugettext as _
+
+from django.contrib.admin.views.decorators import staff_member_required
+from django.contrib.auth.models import Group
+
+from django.forms.models import (inlineformset_factory,
+ modelform_factory,
+ modelformset_factory,)
+
+from servo.forms.admin import *
+from servo.models.common import *
+from servo.models.repair import Checklist, ChecklistItem
+from servo.models.account import User, Group
+from servo.models.product import ShippingMethod
+
+
+def prep_list_view(model):
+ title = model._meta.verbose_name_plural
+ object_list = model.objects.all()
+ return locals()
+
+
+@staff_member_required
+def list_gsx_accounts(request):
+ object_list = GsxAccount.objects.all()
+ title = GsxAccount._meta.verbose_name_plural
+
+ if object_list.count() > 0:
+ return redirect(object_list[0].get_admin_url())
+
+ return render(request, 'admin/gsx/index.html', locals())
+
+
+@staff_member_required
+def edit_gsx_account(request, pk=None):
+ object_list = GsxAccount.objects.all()
+ title = GsxAccount._meta.verbose_name_plural
+
+ if pk is None:
+ act = GsxAccount()
+ else:
+ act = GsxAccount.objects.get(pk=pk)
+
+ form = GsxAccountForm(instance=act)
+
+ if request.method == 'POST':
+ form = GsxAccountForm(request.POST, instance=act)
+ if form.is_valid():
+ try:
+ act = form.save()
+ cache.delete('gsx_session')
+ try:
+ act.test()
+ messages.success(request, _(u'%s saved') % act.title)
+ return redirect(list_gsx_accounts)
+ except gsxws.GsxError, e:
+ messages.warning(request, e)
+ except IntegrityError:
+ transaction.rollback()
+ msg = _('GSX account for this sold-to and environment already exists')
+ messages.error(request, msg)
+
+ return render(request, 'admin/gsx/form.html', locals())
+
+
+@staff_member_required
+def delete_gsx_account(request, pk=None):
+ act = GsxAccount.objects.get(pk=pk)
+ if request.method == 'POST':
+ try:
+ act.delete()
+ messages.success(request, _("GSX account deleted"))
+ except Exception, e:
+ messages.error(request, e)
+
+ return redirect(list_gsx_accounts)
+
+ return render(request, 'admin/gsx/remove.html', {'action': request.path})
+
+
+@staff_member_required
+def checklists(request):
+ object_list = Checklist.objects.all()
+ title = Checklist._meta.verbose_name_plural
+
+ if object_list.count() > 0:
+ return redirect(object_list[0].get_admin_url())
+
+ return render(request, 'admin/checklist/index.html', locals())
+
+
+@staff_member_required
+def edit_checklist(request, pk=None):
+ object_list = Checklist.objects.all()
+ title = Checklist._meta.verbose_name_plural
+ ChecklistItemFormset = inlineformset_factory(Checklist, ChecklistItem, exclude=[])
+
+ if pk is None:
+ checklist = Checklist()
+ else:
+ checklist = Checklist.objects.get(pk=pk)
+
+ form = ChecklistForm(instance=checklist)
+ formset = ChecklistItemFormset(instance=checklist)
+
+ if request.method == 'POST':
+ form = ChecklistForm(request.POST, instance=checklist)
+
+ if form.is_valid():
+ checklist = form.save()
+ formset = ChecklistItemFormset(request.POST, instance=checklist)
+
+ if formset.is_valid():
+ formset.save()
+ messages.success(request, _('Checklist saved'))
+ return redirect(checklist.get_admin_url())
+
+ return render(request, 'admin/checklist/form.html', locals())
+
+
+@staff_member_required
+def delete_checklist(request, pk):
+ checklist = Checklist.objects.get(pk=pk)
+
+ if request.method == 'POST':
+ checklist.delete()
+ messages.success(request, _('Checklist deleted'))
+ return redirect(checklists)
+
+ action = str(request.path)
+ title = _('Really delete this checklist?')
+ explanation = _('This will also delete all checklist values.')
+
+ return render(request, 'generic/delete.html', locals())
+
+
+@staff_member_required
+def tags(request, type=None):
+ if type is None:
+ type = Tag.TYPES[0][0]
+
+ title = Checklist._meta.verbose_name_plural
+ object_list = Tag.objects.filter(type=type)
+
+ if object_list.count() > 0:
+ return redirect(object_list[0].get_admin_url())
+
+ types = Tag.TYPES
+
+ return render(request, 'admin/tags/index.html', locals())
+
+
+@staff_member_required
+def edit_tag(request, type, pk=None):
+ if pk is None:
+ tag = Tag(type=type)
+ else:
+ tag = Tag.objects.get(pk=pk)
+
+ TagForm = modelform_factory(Tag, exclude=[])
+ form = TagForm(instance=tag)
+
+ if request.method == 'POST':
+ form = TagForm(request.POST, instance=tag)
+
+ if form.is_valid():
+ tag = form.save()
+ messages.success(request, _(u'Tag %s saved') % tag.title)
+ return redirect(edit_tag, tag.type, tag.pk)
+
+ types = Tag.TYPES
+ title = Tag._meta.verbose_name_plural
+ object_list = Tag.objects.filter(type=type)
+ return render(request, 'admin/tags/form.html', locals())
+
+
+@staff_member_required
+def delete_tag(request, pk):
+ tag = Tag.objects.get(pk=pk)
+
+ if request.method == 'POST':
+ tag.delete()
+ messages.success(request, _('Tag deleted'))
+ return redirect(tags, type=tag.type)
+
+ title = _('Really delete this tag?')
+ action = str(request.path)
+
+ return render(request, 'generic/delete.html', locals())
+
+
+@staff_member_required
+def settings(request):
+ title = _('System Settings')
+ ShippingMethodFormset = modelformset_factory(ShippingMethod,
+ can_delete=True,
+ extra=0,
+ exclude=[])
+ formset = ShippingMethodFormset(queryset=ShippingMethod.objects.all())
+
+ if request.method == 'POST':
+ form = SettingsForm(request.POST, request.FILES)
+
+ if not form.is_valid():
+ messages.error(request, _('Check your settings'))
+ return render(request, 'admin/settings.html', locals())
+
+ config = form.save()
+
+ if request.POST.get('update_prices'):
+ from servo.models import Product
+ for p in Product.objects.filter(fixed_price=False):
+ p.set_stock_sales_price()
+ p.set_exchange_sales_price()
+ p.save()
+
+ # formset = ShippingMethodFormset(request.POST)
+
+ # if not formset.is_valid():
+ # messages.error(request, _('Error in shipping method settings'))
+ # return render(request, 'admin/settings.html', locals())
+
+ # formset.save()
+
+ messages.success(request, _('Settings saved'))
+ return redirect(settings)
+
+ config = Configuration.conf()
+ form = SettingsForm(initial=config)
+
+ return render(request, 'admin/settings.html', locals())
+
+
+@staff_member_required
+def statuses(request):
+ object_list = Status.objects.all()
+ title = Status._meta.verbose_name_plural
+ if object_list.count() > 0:
+ return redirect(edit_status, object_list[0].pk)
+
+ return render(request, 'admin/statuses/index.html', locals())
+
+
+@staff_member_required
+def edit_status(request, pk=None):
+ if pk is None:
+ status = Status()
+ else:
+ status = Status.objects.get(pk=pk)
+
+ header = _(u'Statuses')
+ object_list = Status.objects.all()
+ form = StatusForm(instance=status)
+ title = Status._meta.verbose_name_plural
+
+ if request.method == 'POST':
+ form = StatusForm(request.POST, instance=status)
+ if form.is_valid():
+ status = form.save()
+ messages.success(request, _(u'%s saved') % status.title)
+ return redirect(edit_status, status.pk)
+
+ return render(request, 'admin/statuses/form.html', locals())
+
+
+@staff_member_required
+def remove_status(request, pk):
+ status = Status.objects.get(pk=pk)
+ action = request.path
+
+ if request.method == 'POST':
+ status.delete()
+ messages.success(request, _(u'%s deleted') % status.title)
+ return redirect(statuses)
+
+ return render(request, 'admin/statuses/remove.html', locals())
+
+
+@staff_member_required
+def fields(request, type='customer'):
+ data = prep_list_view(Property)
+ data['type'] = type
+ data['types'] = Property.TYPES
+ data['object_list'] = Property.objects.filter(type=type)
+
+ if data['object_list'].count() > 0:
+ field = data['object_list'][0]
+ return redirect(edit_field, field.type, field.pk)
+
+ return render(request, 'admin/fields/index.html', data)
+
+
+@staff_member_required
+def edit_field(request, type, pk=None):
+ if pk is None:
+ field = Property(type=type)
+ else:
+ field = Property.objects.get(pk=pk)
+
+ FieldForm = modelform_factory(Property, exclude=[])
+
+ types = Property.TYPES
+ title = Property._meta.verbose_name_plural
+ object_list = Property.objects.filter(type=type)
+ form = FieldForm(instance=field)
+
+ if request.method == 'POST':
+ form = FieldForm(request.POST, instance=field)
+
+ if form.is_valid():
+ field = form.save()
+ messages.success(request, _(u'Field saved'))
+ return redirect(field.get_admin_url())
+
+ return render(request, 'admin/fields/form.html', locals())
+
+
+@staff_member_required
+def delete_field(request, pk=None):
+ field = Property.objects.get(pk=pk)
+
+ if request.method == 'POST':
+ field.delete()
+ messages.success(request, _(u'Field deleted'))
+ return redirect(fields, type=field.type)
+
+ data = {'title': _('Really delete this field?')}
+ data['action'] = request.path
+
+ return render(request, 'generic/delete.html', data)
+
+
+@staff_member_required
+def list_templates(request):
+ object_list = Template.objects.all()
+ title = Template._meta.verbose_name_plural
+ if object_list.count() > 0:
+ return redirect(object_list[0].get_admin_url())
+ return render(request, "admin/templates/list_templates.html", locals())
+
+
+@staff_member_required
+def edit_template(request, pk=None):
+
+ if pk is None:
+ template = Template()
+ else:
+ template = Template.objects.get(pk=pk)
+
+ form = TemplateForm(instance=template)
+
+ if request.method == 'POST':
+ form = TemplateForm(request.POST, instance=template)
+
+ if form.is_valid():
+ template = form.save()
+ messages.success(request, _(u'Template %s saved') % template.title)
+ # generic view...
+ return redirect(template.get_admin_url())
+
+ form = form
+ object_list = Template.objects.all()
+ title = Template._meta.verbose_name_plural
+ return render(request, 'admin/templates/form.html', locals())
+
+
+@staff_member_required
+def delete_template(request, pk):
+ template = Template.objects.get(pk=pk)
+
+ if request.method == 'POST':
+ template.delete()
+ messages.success(request, _(u'Template %s deleted') % template.title)
+ return redirect(list_templates)
+
+ title = _('Really delete this template?')
+ action = str(request.path)
+ return render(request, 'generic/delete.html', locals())
+
+
+@staff_member_required
+def list_users(request):
+ object_list = User.objects.filter(is_visible=True)
+ title = User._meta.verbose_name_plural
+ locations = Location.objects.all()
+
+ if object_list.count() > 0:
+ return redirect(object_list[0].get_admin_url())
+
+ return render(request, 'admin/users/index.html', locals())
+
+
+@staff_member_required
+def list_groups(request):
+ object_list = Group.objects.all()
+ title = _('Users & Groups')
+
+ return render(request, 'admin/users/groups.html', locals())
+
+
+@staff_member_required
+def edit_group(request, pk=None):
+ title = _(u'Edit Group')
+ object_list = Group.objects.all()
+
+ if pk is None:
+ group = Group()
+ form = GroupForm(instance=group)
+ else:
+ group = Group.objects.get(pk=pk)
+ title = group.name
+ form = GroupForm(instance=group)
+
+ if request.method == 'POST':
+ form = GroupForm(request.POST, instance=group)
+ if form.is_valid():
+ form.save()
+ messages.success(request, _(u'Group saved'))
+ return redirect(list_groups)
+
+ return render(request, 'admin/users/group_form.html', locals())
+
+
+@staff_member_required
+def delete_group(request, pk):
+ group = Group.objects.get(pk=pk)
+
+ if request.method == "POST":
+ group.delete()
+ messages.success(request, _("Group deleted"))
+ return redirect(list_groups)
+
+ data = {'action': request.path}
+
+ return render(request, "admin/users/delete_group.html", data)
+
+
+@staff_member_required
+def delete_user(request, user_id):
+ user = User.objects.get(pk=user_id)
+
+ if request.method == "POST":
+ try:
+ user.delete()
+ messages.success(request, _("User deleted"))
+ except Exception, e:
+ messages.error(request, e)
+
+ return redirect(list_users)
+
+ return render(request, "admin/users/remove.html", locals())
+
+
+@staff_member_required
+def delete_user_token(request, user_id):
+ user = User.objects.get(pk=user_id)
+ user.delete_tokens()
+ messages.success(request, _('API tokens deleted'))
+ return redirect(edit_user, user.pk)
+
+
+@staff_member_required
+def create_user_token(request, user_id):
+ user = User.objects.get(pk=user_id)
+ token = user.create_token()
+ messages.success(request, _('API token created'))
+ return redirect(edit_user, user.pk)
+
+
+@staff_member_required
+def edit_user(request, pk=None):
+ if pk is None:
+ user = User(site_id=app_settings.SITE_ID)
+ user.location = request.user.location
+ user.locale = request.user.locale
+ user.region = request.user.region
+ user.timezone = request.user.timezone
+ else:
+ user = User.objects.get(pk=pk)
+
+ form = UserForm(instance=user)
+
+ if request.method == "POST":
+ form = UserForm(request.POST, instance=user)
+ if form.is_valid():
+ user = form.save()
+ User.refresh_nomail()
+ if request.POST.get('password1'):
+ user.set_password(request.POST['password1'])
+ user.save()
+ messages.success(request, _(u"User %s saved") % user.get_name())
+ return redirect(edit_user, user.pk)
+ else:
+ messages.error(request, _("Error in user profile data"))
+
+ object_list = User.objects.filter(is_visible=True)
+
+ if request.GET.get('l'):
+ object_list = object_list.filter(locations__pk=request.GET['l'])
+
+ title = User._meta.verbose_name_plural
+ locations = Location.objects.all()
+
+ if len(object_list) > 0:
+ header = _(u'%d users') % len(object_list)
+
+ return render(request, "admin/users/form.html", locals())
+
+
+@staff_member_required
+def locations(request):
+ object_list = Location.objects.all()
+ title = Location._meta.verbose_name_plural
+
+ if object_list.count() > 0:
+ return redirect(object_list[0].get_admin_url())
+
+ return render(request, 'admin/locations/index.html', locals())
+
+
+@staff_member_required
+def edit_location(request, pk=None):
+ header = _('Locations')
+ object_list = Location.objects.all()
+ title = Location._meta.verbose_name_plural
+
+ if pk is None:
+ location = Location()
+ location.timezone = request.user.timezone
+ else:
+ location = Location.objects.get(pk=pk)
+
+ form = LocationForm(instance=location)
+
+ if request.method == 'POST':
+ form = LocationForm(request.POST, request.FILES, instance=location)
+ if form.is_valid():
+ try:
+ location = form.save()
+ messages.success(request, _(u'Location %s saved') % location.title)
+ return redirect(location.get_admin_url())
+ except Exception:
+ pass # just show the form with the error
+
+ return render(request, 'admin/locations/form.html', locals())
+
+
+@staff_member_required
+def delete_location(request, pk):
+ location = Location.objects.get(pk=pk)
+
+ if request.method == 'POST':
+ try:
+ location.delete()
+ messages.success(request, _(u'%s deleted') % location.title)
+ except Exception, e:
+ messages.error(request, e)
+
+ return redirect(locations)
+
+ title = _(u'Really delete this location?')
+ explanation = _(u'This will not delete the orders at this location')
+ action = request.path
+
+ return render(request, 'generic/delete.html', locals())
+
+
+@staff_member_required
+def queues(request):
+ data = prep_list_view(Queue)
+ if data['object_list'].count() > 0:
+ return redirect(data['object_list'][0].get_admin_url())
+ data['subtitle'] = _('Create, edit and delete service queues')
+ return render(request, 'admin/queues/index.html', data)
+
+
+@staff_member_required
+def edit_queue(request, pk=None):
+
+ StatusFormSet = inlineformset_factory(Queue, QueueStatus, extra=1, exclude=[])
+
+ if pk is None:
+ queue = Queue()
+ locations = request.user.locations.all()
+ form = QueueForm(initial={'locations': locations})
+ else:
+ queue = Queue.objects.get(pk=pk)
+ form = QueueForm(instance=queue, initial={'users': queue.user_set.all()})
+
+ title = _(u'Queues')
+ object_list = Queue.objects.all()
+ formset = StatusFormSet(instance=queue)
+
+ if request.method == 'POST':
+ form = QueueForm(request.POST, request.FILES, instance=queue)
+
+ if form.is_valid():
+ try:
+ queue = form.save()
+ queue.user_set = form.cleaned_data['users']
+ queue.save()
+ except Exception as e:
+ messages.error(request, _('Failed to save queue'))
+ return render(request, 'admin/queues/form.html', locals())
+
+ formset = StatusFormSet(request.POST, instance=queue)
+
+ if formset.is_valid():
+ formset.save()
+ messages.success(request, _(u'%s queue saved') % queue.title)
+ return redirect(queue.get_admin_url())
+ else:
+ messages.error(request, formset.errors)
+ else:
+ messages.error(request, form.errors)
+
+ return render(request, 'admin/queues/form.html', locals())
+
+
+@staff_member_required
+def delete_queue(request, pk=None):
+ queue = Queue.objects.get(pk=pk)
+
+ if request.method == 'POST':
+ try:
+ queue.delete()
+ messages.success(request, _("Queue deleted"))
+ except Queue.ProtectedError:
+ messages.error(request, _("Cannot delete queue"))
+
+ return redirect(queues)
+
+ return render(request, 'admin/queues/remove.html', locals())
+
+
+@staff_member_required
+def notifications(request):
+ data = {'title': _(u'Notifications')}
+ return render(request, 'admin/notifications/index.html', data)
+
+
+@staff_member_required
+def edit_notification(request, nid):
+ return render(request, 'admin/notifications/form.html')
+
+
+def list_sites(request):
+ if not request.user.is_superuser:
+ messages.error(request, _(u"Access denied"))
+ return redirect('/login/')
+
+ data = {'sites': Site.objects.all()}
+ data['title'] = _(u"Manage Sites")
+
+ return render(request, "admin/sites/index.html", data)
+
+
+def edit_site(request, pk=None):
+ if not request.user.is_superuser:
+ messages.add_message(request, messages.ERROR, _(u"Access denied"))
+ return redirect('/login/')
+
+ site = Site()
+ data = {'title': _(u"New Site")}
+
+ if pk is not None:
+ site = Site.objects.get(pk=pk)
+ data['title'] = site.name
+
+ SiteForm = modelform_factory(Site, exclude=[])
+ form = SiteForm(instance=site)
+
+ if request.method == "POST":
+
+ form = SiteForm(request.POST, instance=site)
+
+ if form.is_valid():
+ form.save()
+ messages.add_message(request, messages.SUCCESS, _(u"Site saved"))
+ return redirect(list_sites)
+
+ data['form'] = form
+ data['sites'] = Site.objects.all()
+
+ return render(request, "admin/sites/edit_site.html", data)
+
+
+def upload_users(request):
+ """
+ """
+ action = request.path
+ form = UserUploadForm()
+ title = _('Upload Users')
+
+ if request.method == 'POST':
+ form = UserUploadForm(request.POST, request.FILES)
+ if form.is_valid():
+ try:
+ users = form.save()
+ messages.success(request, _('%d users imported') % len(users))
+ except Exception, e:
+ messages.error(request, e)
+ else:
+ messages.error(request, form.errors)
+
+ return redirect(list_users)
+
+ return render(request, "admin/users/upload_users.html", locals())
+
+
+class Backup(object):
+ @classmethod
+ def all(cls):
+ from glob import glob
+ return [cls(s) for s in glob("backups/*.gz")]
+
+ def __init__(self, path):
+ import os
+ self.path = path
+ self.filename = os.path.basename(path)
+ self.filesize = os.path.getsize(path)
+
+ def get_wrapper(self):
+ from django.core.servers.basehttp import FileWrapper
+ return FileWrapper(file(self.path))
+
+ def get_response(self):
+ from django.http import HttpResponse
+ wrapper = self.get_wrapper()
+ response = HttpResponse(wrapper, content_type='application/force-download')
+ response['Content-Disposition'] = 'attachment; filename=%s' % self.filename
+ response['Content-Length'] = self.filesize
+ return response
+
+def backups(request):
+
+ if request.GET.get('dl'):
+ backup = Backup("backups/%s" % request.GET['dl'])
+ return backup.get_response()
+
+ title = _('Backups')
+ backups = Backup.all()
+ return render(request, "admin/backups.html", locals())