aboutsummaryrefslogtreecommitdiff
path: root/app/dispatch
diff options
context:
space:
mode:
Diffstat (limited to 'app/dispatch')
-rw-r--r--app/dispatch/migrations/0008_load_load_number.py21
-rw-r--r--app/dispatch/models.py1
-rw-r--r--app/dispatch/templates/dispatch/base.html19
-rw-r--r--app/dispatch/templates/dispatch/companies/detail.html57
-rw-r--r--app/dispatch/templates/dispatch/companies/list.html2
-rw-r--r--app/dispatch/templates/dispatch/drivers/detail.html63
-rw-r--r--app/dispatch/templates/dispatch/drivers/edit.html15
-rw-r--r--app/dispatch/templates/dispatch/drivers/list.html34
-rw-r--r--app/dispatch/templates/dispatch/loads/list.html85
-rw-r--r--app/dispatch/templatetags/__init__.py0
-rw-r--r--app/dispatch/templatetags/dynamic_key.py7
-rw-r--r--app/dispatch/urls.py5
-rw-r--r--app/dispatch/views.py99
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