diff options
| author | Kyle Blanker <kyle@stridet.com> | 2017-09-13 14:04:47 -0400 |
|---|---|---|
| committer | Kyle Blanker <kyle@stridet.com> | 2017-09-13 14:04:47 -0400 |
| commit | 0be25b7fed14e59ebb7ac52930a8284535eb4276 (patch) | |
| tree | 9f4e0e78df7f15bdc037d582100c7736536c5a41 /app | |
| parent | 207be6ecd78719808836b49af4878c60b61e7d0a (diff) | |
| download | dispatch-tracker-0be25b7fed14e59ebb7ac52930a8284535eb4276.tar.gz dispatch-tracker-0be25b7fed14e59ebb7ac52930a8284535eb4276.tar.xz | |
Setup driver, company details to show loads, loads list now shows per week as well
Diffstat (limited to 'app')
| -rw-r--r-- | app/dispatch/migrations/0008_load_load_number.py | 21 | ||||
| -rw-r--r-- | app/dispatch/models.py | 1 | ||||
| -rw-r--r-- | app/dispatch/templates/dispatch/base.html | 19 | ||||
| -rw-r--r-- | app/dispatch/templates/dispatch/companies/detail.html | 57 | ||||
| -rw-r--r-- | app/dispatch/templates/dispatch/companies/list.html | 2 | ||||
| -rw-r--r-- | app/dispatch/templates/dispatch/drivers/detail.html | 63 | ||||
| -rw-r--r-- | app/dispatch/templates/dispatch/drivers/edit.html | 15 | ||||
| -rw-r--r-- | app/dispatch/templates/dispatch/drivers/list.html | 34 | ||||
| -rw-r--r-- | app/dispatch/templates/dispatch/loads/list.html | 85 | ||||
| -rw-r--r-- | app/dispatch/templatetags/__init__.py | 0 | ||||
| -rw-r--r-- | app/dispatch/templatetags/dynamic_key.py | 7 | ||||
| -rw-r--r-- | app/dispatch/urls.py | 5 | ||||
| -rw-r--r-- | app/dispatch/views.py | 99 |
13 files changed, 368 insertions, 40 deletions
diff --git a/app/dispatch/migrations/0008_load_load_number.py b/app/dispatch/migrations/0008_load_load_number.py new file mode 100644 index 0000000..b671b87 --- /dev/null +++ b/app/dispatch/migrations/0008_load_load_number.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.5 on 2017-09-13 17:05 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('dispatch', '0007_auto_20170715_2105'), + ] + + operations = [ + migrations.AddField( + model_name='load', + name='load_number', + field=models.CharField(default="", max_length=64), + preserve_default=False, + ), + ] diff --git a/app/dispatch/models.py b/app/dispatch/models.py index f97c42b..f024d46 100644 --- a/app/dispatch/models.py +++ b/app/dispatch/models.py @@ -24,6 +24,7 @@ class Contact(models.Model): return "{f} {l} ( {c} )".format(c=self.works_for, f=self.first_name, l=self.last_name) class Load(models.Model): + load_number = models.CharField(max_length=64,default="") date = models.DateField() user = models.ForeignKey(settings.AUTH_USER_MODEL) company = models.ForeignKey(Company) diff --git a/app/dispatch/templates/dispatch/base.html b/app/dispatch/templates/dispatch/base.html index 37c8830..de28d7a 100644 --- a/app/dispatch/templates/dispatch/base.html +++ b/app/dispatch/templates/dispatch/base.html @@ -17,9 +17,16 @@ font-size: 2rem; margin: 0; } + h2 { + font-size: 1.75rem; + + } main { padding: 16px; } + .helptext{ + display: none; + } </style> </head> <body> @@ -28,7 +35,7 @@ <div class="nav-wrapper container"><a id="logo-container" href="{% url 'home' %}" class="brand-logo">Dispatch Tracker</a> <ul class="right hide-on-med-and-down"> {% if user.is_authenticated %} - <li><a href="#">Drivers</a></li> + <li><a href="{% url 'driver_list' %}">Drivers</a></li> <li><a href="{% url 'load_list' %}">Loads</a></li> <li><a href="{% url 'company_list' %}">Companies</a></li> <li><a href="#">Contacts</a></li> @@ -86,6 +93,16 @@ <script> $('select').material_select(); + $(document).ready(function() { + $('input[type=checkbox]').each(function() { + $(this).addClass('filled-in'); + if(this.nextSibling.nodeName != 'label') { + $(this).after('<label for="'+this.id+'">' + jQuery(this).prev().html().replace(':','') + '</label>') ; + jQuery(this).prev().remove(); + } + }) + }) + $('nav li').find('a[href="' + window.location.pathname +'"]').parent().addClass('active'); </script> </body> </html> diff --git a/app/dispatch/templates/dispatch/companies/detail.html b/app/dispatch/templates/dispatch/companies/detail.html index e939fdb..053f62b 100644 --- a/app/dispatch/templates/dispatch/companies/detail.html +++ b/app/dispatch/templates/dispatch/companies/detail.html @@ -4,7 +4,60 @@ {% block content %} <div class="row"> <div class="col s12 m6"> - <h1>{{ object.name }} details</h1> + <h1>Company: {{ object.name }}</h1> + <h2>Loads for {{start_date}} - {{end_date}}</h2> </div> -</div> +</div> + +<div class="row"> + <div class="col s6 left-align"> + <a href="{% url 'company_detail' object.id %}?date={{previous_week}}" class="btn blue"><i class="material-icons left">arrow_back</i> Prev</a> + </div> + <div class="col s6 right-align"> + <a href="{% url 'company_detail' object.id %}?date={{next_week}}" class="btn blue"><i class="material-icons right">arrow_forward</i> Next</a> + </div> +</div> + +{% load dynamic_key %} +{% for date in loads %} + <div class="row"> + <div class="col s12 card"> + <div class="card-content"> + <span class="card-title">{{date}}</span> + <table class="striped bordered"> + <thead> + <tr> + <th>Driver</th> + <th>Amount</th> + </tr> + </thead> + <tbody> + {% for load in loads|keyvalue:date %} + <tr class="green lighten-4"> + <td><a href="{% url 'driver_detail' load.user.id %}">{{ load.user.first_name }} {{ load.user.last_name }}</a></td> + <td>{{ load.amount }}</td> + <td class="right-align"> + <a href="{% url 'load_edit' load.id %}" class="btn orange">Edit</a> + <a href="{% url 'load_detail' load.id %}" class="btn blue">View</a> + </td> + </tr> + {% empty %} + <tr class="yellow lighten-4"><td colspan="4">No load.</td></tr> + {% endfor %} + </tbody> + </table> + </div> + </div> + </div> +{% endfor %} + +<div class="row"> + <div class="col s6 left-align"> + <a href="{% url 'company_detail' object.id %}?date={{previous_week}}" class="btn blue"><i class="material-icons left">arrow_back</i> Prev</a> + </div> + <div class="col s6 right-align"> + <a href="{% url 'company_detail' object.id %}?date={{next_week}}" class="btn blue"><i class="material-icons right">arrow_forward</i> Next</a> + </div> +</div> + {% endblock %} diff --git a/app/dispatch/templates/dispatch/companies/list.html b/app/dispatch/templates/dispatch/companies/list.html index 48612d9..9399276 100644 --- a/app/dispatch/templates/dispatch/companies/list.html +++ b/app/dispatch/templates/dispatch/companies/list.html @@ -10,7 +10,7 @@ <a href="{% url 'company_new' %}" class="btn green">Add Company</a> </div> </div> -<table class="striped"> +<table class="striped bordered"> <thead> <tr> <th>Name</th> diff --git a/app/dispatch/templates/dispatch/drivers/detail.html b/app/dispatch/templates/dispatch/drivers/detail.html new file mode 100644 index 0000000..598d01e --- /dev/null +++ b/app/dispatch/templates/dispatch/drivers/detail.html @@ -0,0 +1,63 @@ +{% extends 'dispatch/base.html' %} + + +{% block content %} +<div class="row"> + <div class="col s12 m6"> + <h1>Driver: {{ object.first_name }} {{ object.last_name }}</h1> + <h2>Loads for {{start_date}} - {{end_date}}</h2> + </div> +</div> + +<div class="row"> + <div class="col s6 left-align"> + <a href="{% url 'driver_detail' object.id %}?date={{previous_week}}" class="btn blue"><i class="material-icons left">arrow_back</i> Prev</a> + </div> + <div class="col s6 right-align"> + <a href="{% url 'driver_detail' object.id %}?date={{next_week}}" class="btn blue"><i class="material-icons right">arrow_forward</i> Next</a> + </div> +</div> + +{% load dynamic_key %} +{% for date in loads %} + <div class="row"> + <div class="col s12 card"> + <div class="card-content"> + <span class="card-title">{{date}}</span> + <table class="striped bordered"> + <thead> + <tr> + <th>Company</th> + <th>Amount</th> + </tr> + </thead> + <tbody> + {% for load in loads|keyvalue:date %} + <tr class="green lighten-4"> + <td><a href="{% url 'company_detail' load.company.id %}">{{ load.company.name }}</a></td> + <td>{{ load.amount }}</td> + <td class="right-align"> + <a href="{% url 'load_edit' load.id %}" class="btn orange">Edit</a> + <a href="{% url 'load_detail' load.id %}" class="btn blue">View</a> + </td> + </tr> + {% empty %} + <tr class="yellow lighten-4"><td colspan="4">No load.</td></tr> + {% endfor %} + </tbody> + </table> + </div> + </div> + </div> +{% endfor %} + +<div class="row"> + <div class="col s6 left-align"> + <a href="{% url 'driver_detail' object.id %}?date={{previous_week}}" class="btn blue"><i class="material-icons left">arrow_back</i> Prev</a> + </div> + <div class="col s6 right-align"> + <a href="{% url 'driver_detail' object.id %}?date={{next_week}}" class="btn blue"><i class="material-icons right">arrow_forward</i> Next</a> + </div> +</div> + +{% endblock %} diff --git a/app/dispatch/templates/dispatch/drivers/edit.html b/app/dispatch/templates/dispatch/drivers/edit.html new file mode 100644 index 0000000..fe8460d --- /dev/null +++ b/app/dispatch/templates/dispatch/drivers/edit.html @@ -0,0 +1,15 @@ +{% extends 'dispatch/base.html' %} + + +{% block content %} +<div class="row"> + <div class="col s12 m6"> + <h1>{{object.name}}</h1> + </div> +</div> + +<form action="" method="post">{% csrf_token %} + {{ form.as_p }} + <input type="submit" class="btn blue" value="Update" /> +</form> +{% endblock %} diff --git a/app/dispatch/templates/dispatch/drivers/list.html b/app/dispatch/templates/dispatch/drivers/list.html new file mode 100644 index 0000000..efc6141 --- /dev/null +++ b/app/dispatch/templates/dispatch/drivers/list.html @@ -0,0 +1,34 @@ +{% extends 'dispatch/base.html' %} + + +{% block content %} +<div class="row"> + <div class="col s12 m6"> + <h1>Drivers</h1> + </div> +</div> +<table class="striped bordered"> + <thead> + <tr> + <th>First Name</th> + <th>Last Name</th> + <th>Email</th> + </tr> + </thead> + <tbody> + {% for driver in object_list %} + <tr> + <td>{{ driver.first_name }}</td> + <td>{{ driver.last_name }}</td> + <td>{{ driver.email }}</td> + <td class="right-align"> + <a href="{% url 'driver_edit' driver.id %}" class="btn orange">Edit</a> + <a href="{% url 'driver_detail' driver.id %}" class="btn blue">View</a> + </td> + </tr> + {% empty %} + <tr><td colspan="4">No drivers yet.</td></tr> + {% endfor %} + </tbody> +</table> +{% endblock %} diff --git a/app/dispatch/templates/dispatch/loads/list.html b/app/dispatch/templates/dispatch/loads/list.html index 8129907..d4caf71 100644 --- a/app/dispatch/templates/dispatch/loads/list.html +++ b/app/dispatch/templates/dispatch/loads/list.html @@ -2,42 +2,65 @@ {% block content %} + <div class="row"> <div class="col s12 m6"> - <h1>Loads</h1> + <h1>Loads for {{start_date}} - {{end_date}}</h1> </div> <div class="col s12 m6 right-align"> <a href="{% url 'load_new' %}" class="btn green">Add Load</a> </div> </div> -<table class="striped"> - <thead> - <tr> - {% if user.is_superuser %} - <td>Driver</td> - {% endif %} - <th>Date</th> - <th>Company</th> - <th>Amount</th> - </tr> - </thead> - <tbody> - {% for load in object_list %} - <tr> - {% if user.is_superuser %} - <td>{{ load.user.first_name }} {{ load.user.last_name }}</td> - {% endif %} - <td>{{ load.date }}</td> - <td>{{ load.company.name }}</td> - <td>{{ load.amount }}</td> - <td class="right-align"> - <a href="{% url 'load_edit' load.id %}" class="btn orange">Edit</a> - <a href="{% url 'load_detail' load.id %}" class="btn blue">View</a> - </td> - </tr> - {% empty %} - <tr><td colspan="4">No loads yet.</td></tr> - {% endfor %} - </tbody> -</table> +<div class="row"> + <div class="col s6 left-align"> + <a href="{% url 'load_list' %}?date={{previous_week}}" class="btn blue"><i class="material-icons left">arrow_back</i> Prev</a> + </div> + <div class="col s6 right-align"> + <a href="{% url 'load_list' %}?date={{next_week}}" class="btn blue"><i class="material-icons right">arrow_forward</i> Next</a> + </div> +</div> +{% load dynamic_key %} +{% for date in loads %} + <div class="row"> + <div class="col s12 card"> + <div class="card-content"> + <span class="card-title">{{date}}</span> + <table class="striped bordered"> + <thead> + <tr> + <th>Driver</th> + <th>Company</th> + <th>Load Number</th> + <th>Amount</th> + </tr> + </thead> + <tbody> + {% for load in loads|keyvalue:date %} + <tr class="green lighten-4"> + <td><a href="{% url 'driver_detail' load.user.id %}">{{ load.user.first_name }} {{ load.user.last_name }}</a></td> + <td><a href="{% url 'company_detail' load.company.id %}">{{ load.company.name }}</a></td> + <td>{{ load.load_number }}</td> + <td>{{ load.amount }}</td> + <td class="right-align"> + <a href="{% url 'load_edit' load.id %}" class="btn orange">Edit</a> + <a href="{% url 'load_detail' load.id %}" class="btn blue">View</a> + </td> + </tr> + {% empty %} + <tr class="yellow lighten-4"><td colspan="4">No load.</td></tr> + {% endfor %} + </tbody> + </table> + </div> + </div> + </div> +{% endfor %} +<div class="row"> + <div class="col s6 left-align"> + <a href="{% url 'load_list' %}?date={{previous_week}}" class="btn blue"><i class="material-icons left">arrow_back</i> Prev</a> + </div> + <div class="col s6 right-align"> + <a href="{% url 'load_list' %}?date={{next_week}}" class="btn blue"><i class="material-icons right">arrow_forward</i> Next</a> + </div> +</div> {% endblock %} diff --git a/app/dispatch/templatetags/__init__.py b/app/dispatch/templatetags/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/app/dispatch/templatetags/__init__.py diff --git a/app/dispatch/templatetags/dynamic_key.py b/app/dispatch/templatetags/dynamic_key.py new file mode 100644 index 0000000..6a79707 --- /dev/null +++ b/app/dispatch/templatetags/dynamic_key.py @@ -0,0 +1,7 @@ +from django import template + +register = template.Library() + +@register.filter +def keyvalue(dict, key): + return dict[key]
\ No newline at end of file diff --git a/app/dispatch/urls.py b/app/dispatch/urls.py index 3d33940..c895674 100644 --- a/app/dispatch/urls.py +++ b/app/dispatch/urls.py @@ -10,6 +10,11 @@ urlpatterns = [ url(r'^%s$' % settings.LOGIN_URL, authviews.LoginView.as_view(template_name="dispatch/login.html"), name='login'), url(r'^logout/$', authviews.LogoutView.as_view(next_page='/'), name='logout'), + url(r'^drivers/$', views.DriverList.as_view(), name='driver_list'), + url(r'^drivers/view/(?P<pk>\d+)$', views.DriverDetail.as_view(), name='driver_detail'), + url(r'^drivers/edit/(?P<pk>\d+)$', views.DriverUpdate.as_view(), name='driver_edit'), + url(r'^drivers/delete/(?P<pk>\d+)$', views.DriverDelete.as_view(), name='driver_delete'), + url(r'^companies/$', views.CompanyList.as_view(), name='company_list'), url(r'^companies/new$', views.CompanyCreate.as_view(), name='company_new'), url(r'^companies/view/(?P<pk>\d+)$', views.CompanyDetail.as_view(), name='company_detail'), diff --git a/app/dispatch/views.py b/app/dispatch/views.py index 8101ac0..f487ef7 100644 --- a/app/dispatch/views.py +++ b/app/dispatch/views.py @@ -10,10 +10,39 @@ 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 +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 render(request,"dispatch/index.html") +def get_week_dates(date=None): + 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: + start_date = dt + else: + weekday = weekday + 1 + start_date = dt - timedelta(days=weekday) + end_date = start_date + timedelta(days=6) + next_week = end_date + timedelta(days=1) + previous_week = start_date - timedelta(days=1) + return start_date, end_date, next_week, previous_week + +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): + print(date) + str_date = formats.date_format(date, "SHORT_DATE_FORMAT") + if str_date not in split_loads: + split_loads[str_date] = loads.filter(date=date) + return split_loads class FilteredListView(ListView): def get_queryset(self): @@ -36,6 +65,54 @@ class FilteredDeleteView(DeleteView): 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 LoadDateSort(DetailView): + def get_context_data(self, **kwargs): + context = super(DetailView, self).get_context_data(**kwargs) + start_date, end_date, next_week, previous_week = get_week_dates(self.request.GET.get('date',None)) + loads = self.get_object().load_set.filter(date__range=(start_date, end_date)).prefetch_related('company') + context['loads'] = split_loads_by_day(loads,start_date,end_date) + context['start_date'] = formats.date_format(start_date, "SHORT_DATE_FORMAT") + context['end_date'] = formats.date_format(end_date, "SHORT_DATE_FORMAT") + context['next_week'] = formats.date_format(next_week, "SHORT_DATE_FORMAT") + context['previous_week'] = formats.date_format(previous_week, "SHORT_DATE_FORMAT") + return context + +class DriverDetail(LoadDateSort): + template_name = "dispatch/drivers/detail.html" + model = User + + def test_func(self): + return self.request.user.is_superuser + +class DriverUpdate(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): + return self.request.user.is_superuser + +class DriverDelete(DeleteView): + template_name = "dispatch/loads/delete.html" + model = User + success_url = reverse_lazy('driver_list') + + def test_func(self): + return self.request.user.is_superuser + +# Company CRUD + class CompanyList(ListView): template_name = "dispatch/companies/list.html" model = Company @@ -46,14 +123,10 @@ class CompanyCreate(CreateView): success_url = reverse_lazy('company_list') fields = ['name', 'address', 'phone_number','email_address'] -class CompanyDetail(DetailView): +class CompanyDetail(LoadDateSort): template_name = "dispatch/companies/detail.html" model = Company - def get_context_data(self, **kwargs): - context = super(CompanyDetail, self).get_context_data(**kwargs) - return context - class CompanyUpdate(UpdateView): template_name = "dispatch/loads/edit.html" model = Company @@ -71,6 +144,22 @@ class LoadList(FilteredListView): template_name = "dispatch/loads/list.html" model = Load + + def get_queryset(self): + base_qs = super(LoadList, self).get_queryset() + start_date, end_date, next_week, previous_week = get_week_dates(self.request.GET.get('date',None)) + return base_qs.filter(date__range=(start_date, end_date)) + + def get_context_data(self, **kwargs): + context = super(LoadList, self).get_context_data(**kwargs) + start_date, end_date, next_week, previous_week = get_week_dates(self.request.GET.get('date',None)) + context['start_date'] = formats.date_format(start_date, "SHORT_DATE_FORMAT") + context['end_date'] = formats.date_format(end_date, "SHORT_DATE_FORMAT") + context['next_week'] = formats.date_format(next_week, "SHORT_DATE_FORMAT") + context['previous_week'] = formats.date_format(previous_week, "SHORT_DATE_FORMAT") + context['loads'] = split_loads_by_day(self.object_list,start_date,end_date) + return context + class LoadCreate(CreateView): template_name = "dispatch/loads/create.html" model = Load |
