from django.shortcuts import render, redirect from django.http import HttpResponse from django.template import loader from django.core.urlresolvers import reverse import django.contrib.auth as auth from django.conf import settings # Create your views here. from django.views.generic import TemplateView,ListView from django.views.generic.detail import DetailView from django.views.generic.edit import CreateView, UpdateView, DeleteView from django.core.urlresolvers import reverse_lazy from dispatch.models import Company, Load, Paperwork from dispatch.forms import AddPaperworkForm from django.contrib.auth.models import User from django.contrib.auth.mixins import UserPassesTestMixin from django.http import HttpResponseRedirect from datetime import datetime, timedelta from django.utils import formats from dateutil import rrule def home(request): return redirect(reverse('load_list')) def get_week_dates(date=None): week_dates = {} if date == None: date = formats.date_format(datetime.now(), "SHORT_DATE_FORMAT") dt = datetime.strptime(date, '%m/%d/%Y') weekday = dt.weekday() if weekday == 6: week_dates['start_date'] = dt else: weekday = weekday + 1 week_dates['start_date'] = dt - timedelta(days=weekday) week_dates['end_date'] = week_dates['start_date'] + timedelta(days=6) week_dates['next_week'] = week_dates['end_date'] + timedelta(days=1) week_dates['previous_week'] = week_dates['start_date'] - timedelta(days=1) return week_dates def split_loads_by_day(loads,start_date,end_date): split_loads = {} for date in rrule.rrule(rrule.DAILY,dtstart=start_date, until=end_date): str_date = formats.date_format(date, "SHORT_DATE_FORMAT") if date not in split_loads: split_loads[date] = loads.filter(date=date) return split_loads class LoadDateSort(DetailView): def get_context_data(self, **kwargs): context = super(DetailView, self).get_context_data(**kwargs) week_dates = get_week_dates(self.request.GET.get('date',None)) loads = self.get_object().load_set.filter(date__range=(week_dates['start_date'], week_dates['end_date'])).prefetch_related('company') context['loads'] = split_loads_by_day(loads,week_dates['start_date'], week_dates['end_date']) context['week_dates'] = week_dates return context class FilteredListView(ListView): def get_queryset(self): base_qs = super(FilteredListView, self).get_queryset() if not self.request.user.is_superuser: return base_qs.filter(user=self.request.user) return base_qs class FilteredUpdateView(UpdateView): def get_queryset(self): base_qs = super(FilteredUpdateView, self).get_queryset() if not self.request.user.is_superuser: return base_qs.filter(user=self.request.user) return base_qs class FilteredDeleteView(DeleteView): def get_queryset(self): base_qs = super(FilteredDeleteView, self).get_queryset() if not self.request.user.is_superuser: return base_qs.filter(user=self.request.user) return base_qs # Driver CRUD class DriverList(UserPassesTestMixin, ListView): template_name = "dispatch/drivers/list.html" model = User def test_func(self): return self.request.user.is_superuser class DriverDetail(UserPassesTestMixin, LoadDateSort): template_name = "dispatch/drivers/detail.html" model = User def test_func(self): # Seems a little hacky at first but it works! return self.request.user.is_superuser or \ self.get_object().pk is self.request.user.id def get_context_data(self, **kwargs): # Shit gets fucky with super() really fast, but this seems to work context = super(DriverDetail, self).get_context_data(**kwargs) stats = {}; stats['count'], stats['average'], stats['sum'] = (0,0,0) stats['incomplete_loads'] = 0 loads_by_date = context['loads'] for d in loads_by_date: # Iterate over the array for the given date for l in loads_by_date[d]: stats['count'] += 1 stats['sum'] += l.amount if l.amount == 0: stats['incomplete_loads'] += 1 if stats['sum'] is not 0 and stats['count'] is not 0: stats['average'] = stats['sum']/stats['count'] # Add our stats to the context so we can use it in the template context['stats'] = stats return context class DriverUpdate(UserPassesTestMixin, UpdateView): template_name = "dispatch/drivers/edit.html" model = User success_url = reverse_lazy('driver_list') fields = ['username', 'first_name','last_name','email','groups', 'is_active'] def test_func(self): # Seems a little hacky at first but it works! return self.request.user.is_superuser or \ self.get_object().pk is self.request.user.id # Company CRUD class CompanyList(ListView): template_name = "dispatch/companies/list.html" model = Company class CompanyCreate(UserPassesTestMixin, CreateView): template_name = "dispatch/companies/create.html" model = Company success_url = reverse_lazy('company_list') fields = ['name', 'address', 'phone_number','email_address'] def test_func(self): return self.request.user.is_superuser class CompanyDetail(LoadDateSort): template_name = "dispatch/companies/detail.html" model = Company class CompanyUpdate(UserPassesTestMixin, UpdateView): template_name = "dispatch/companies/edit.html" model = Company success_url = reverse_lazy('company_list') fields = ['name', 'address', 'phone_number','email_address'] def test_func(self): return self.request.user.is_superuser class CompanyDelete(UserPassesTestMixin, DeleteView): template_name = "dispatch/companies/delete.html" model = Company success_url = reverse_lazy('company_list') def test_func(self): return self.request.user.is_superuser # Load CRUD class LoadList(FilteredListView): template_name = "dispatch/loads/list.html" model = Load def get_queryset(self): base_qs = super(LoadList, self).get_queryset() wd = get_week_dates(self.request.GET.get('date',None)) return base_qs.filter(date__range=(wd['start_date'], wd['end_date'])) def get_context_data(self, **kwargs): context = super(LoadList, self).get_context_data(**kwargs) wd = get_week_dates(self.request.GET.get('date',None)) context['week_dates'] = wd context['loads'] = split_loads_by_day(self.object_list,wd['start_date'],wd['end_date']) return context class LoadCreate(CreateView): template_name = "dispatch/loads/create.html" model = Load fields = ['date', 'company', 'load_number', 'description', 'delivered_to', 'amount'] def get(self,request): if request.user.is_superuser: self.fields.insert(1,'user') return super(LoadCreate, self).get(request) def form_valid(self, form): if not self.request.user.is_superuser: load = form.save(commit=False) load.user = self.request.user return super(LoadCreate, self).form_valid(form) class LoadDetail(DetailView): template_name = "dispatch/loads/detail.html" model = Load def get_context_data(self, **kwargs): context = super(LoadDetail, self).get_context_data(**kwargs) context['paperwork_list'] = Paperwork.objects.filter(load=context['object']) return context class LoadUpdate(FilteredUpdateView): template_name = "dispatch/loads/edit.html" model = Load fields = ['date', 'company','load_number','description', 'delivered_to', 'amount'] def get(self,request,pk): if request.user.is_superuser: self.fields.insert(1,'user') return super(LoadUpdate, self).get(request) def form_valid(self, form): if not self.request.user.is_superuser: load = form.save(commit=False) load.user = self.request.user return super(LoadUpdate, self).form_valid(form) class LoadDelete(UserPassesTestMixin, FilteredDeleteView): template_name = "dispatch/loads/delete.html" model = Load success_url = reverse_lazy('load_list') def test_func(self): return self.request.user.is_superuser # Paperwork Uploads def PaperworkUpload(request, load_id): l = Load.objects.get(pk=load_id) if request.method == 'POST': form = AddPaperworkForm(request.POST, request.FILES) if form.is_valid(): pw = form.save(commit=False) pw.load = l pw.save() return redirect(reverse('load_detail', kwargs={'pk': load_id})) else: form = AddPaperworkForm() ctx = { 'form': form, 'load': l } return render(request, 'dispatch/paperwork/add.html', ctx) def PaperworkDelete(request, load_id, pk): # TODO: Someday we should return the errors deleting the file, if any try: p = Paperwork.objects.get(pk=pk) p.delete() except Exception as e: print(e) return redirect(reverse('load_detail', kwargs={'pk': load_id}))