Improve launderette plannings and admin part

This commit is contained in:
Skia
2016-07-29 13:00:32 +02:00
parent fc170cfc49
commit ba48adab6d
10 changed files with 232 additions and 115 deletions

View File

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('launderette', '0002_auto_20160729_0138'),
]
operations = [
migrations.AddField(
model_name='machine',
name='type',
field=models.CharField(choices=[('WASHING', 'Washing'), ('DRYING', 'Drying')], max_length=10, default='WASHING', verbose_name='type'),
preserve_default=False,
),
]

View File

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
from django.utils.timezone import utc
import datetime
class Migration(migrations.Migration):
dependencies = [
('launderette', '0003_machine_type'),
]
operations = [
migrations.AddField(
model_name='token',
name='start_date',
field=models.DateTimeField(default=datetime.datetime(2016, 7, 29, 10, 46, 13, 675691, tzinfo=utc), verbose_name='start date'),
preserve_default=False,
),
]

View File

@ -35,6 +35,7 @@ class Launderette(models.Model):
class Machine(models.Model):
name = models.CharField(_('name'), max_length=30)
launderette = models.ForeignKey(Launderette, related_name='machines', verbose_name=_('launderette'))
type = models.CharField(_('type'), max_length=10, choices=[('WASHING', _('Washing')), ('DRYING', _('Drying'))])
is_working = models.BooleanField(_('is working'), default=True)
class Meta:
@ -49,12 +50,16 @@ class Machine(models.Model):
return False
def __str__(self):
return "%s - Launderette: %s - Working: %s" % (self.name, self.launderette, self.is_working)
return "%s %s" % (self._meta.verbose_name, self.name)
def get_absolute_url(self):
return reverse('launderette:launderette_details', kwargs={"launderette_id": self.launderette.id})
class Token(models.Model):
name = models.IntegerField(_('name'))
launderette = models.ForeignKey(Launderette, related_name='tokens', verbose_name=_('launderette'))
type = models.CharField(_('type'), max_length=10, choices=[('WASHING', _('Washing')), ('DRYING', _('Drying'))])
start_date = models.DateTimeField(_('start date'))
class Meta:
verbose_name = _('Token')
@ -81,6 +86,7 @@ class Slot(models.Model):
return super(Slot, self).full_clean()
def __str__(self):
return str(self.user) + " - " + str(self.start_date)
return "User: %s - Date: %s - Type: %s - Machine: %s - Token: %s" % (self.user, self.start_date, self.get_type_display(),
self.machine.name, self.token)

View File

@ -7,13 +7,29 @@
{% macro choose(date) %}
<form method="post" action="{{ url('launderette:book_slot', launderette_id=launderette.id) }}" class="inline" style="display:inline">
{% csrf_token %}
<button type="submit" name="slot" value="{{ localtime(date).isoformat() }}"> {% trans %}Choose{% endtrans %} </button>
<input type="hidden" name="slot_type" value="{{ slot_type }}">
<button type="submit" name="slot" value="{{ date.isoformat() }}">{% trans %}Choose{% endtrans %}</button>
</form>
{% endmacro %}
{% block content %}
{% if request.user.is_in_group(settings.SITH_MAIN_MEMBERS_GROUP) %}
<h3>{{ launderette }}</h3>
<p>
<form method="post" action="{{ url('launderette:book_slot', launderette_id=launderette.id) }}"
class="inline" style="display:inline">
{% csrf_token %}
<button type="submit" name="slot_type" value="BOTH" {% if slot_type == "BOTH" -%}style="background: #FF0"{% endif %}>{% trans %}Washing and drying{% endtrans %}</button>
</form>
<form method="post" action="{{ url('launderette:book_slot', launderette_id=launderette.id) }}" class="inline" style="display:inline">
{% csrf_token %}
<button type="submit" name="slot_type" value="WASHING" {% if slot_type == "WASHING" -%}style="background: #FF0"{% endif %}>{% trans %}Washing{% endtrans %}</button>
</form>
<form method="post" action="{{ url('launderette:book_slot', launderette_id=launderette.id) }}" class="inline" style="display:inline">
{% csrf_token %}
<button type="submit" name="slot_type" value="DRYING" {% if slot_type == "DRYING" -%}style="background: #FF0"{% endif %}>{% trans %}Drying{% endtrans %}</button>
</form>
</p>
<table>
<thead>
<tr>
@ -28,7 +44,7 @@
{% for hours in planning.values() %}
<td>
{% if hours[i] %}
{{ hours[i]|localtime|time(TIME_FORMAT) }} {{ choose(hours[i]) }}
{{ hours[i]|time(TIME_FORMAT) }} {{ choose(hours[i]) }}
{% endif %}
</td>
{% endfor %}
@ -36,7 +52,6 @@
{% endfor %}
</tbody>
</table>
{% endif %}
{% endblock %}

View File

@ -5,7 +5,14 @@
{% endblock %}
{% block content %}
Admin
<h3>{% trans %}Machines{% endtrans %}</h3>
<p><a href="{{ url('launderette:machine_new') }}?launderette={{ launderette.id }}">{% trans %}New machine{% endtrans %}</a></p>
<ul>
{% for m in launderette.machines.all() %}
<li><a href="{{ url('launderette:machine_edit', machine_id=m.id) }}">{{ m }}</a> -
<a href="{{ url('launderette:machine_delete', machine_id=m.id) }}">{% trans %}Delete{% endtrans %}</a></li>
{% endfor %}
</ul>
{% endblock %}

View File

@ -11,6 +11,9 @@ urlpatterns = [
url(r'^admin/(?P<launderette_id>[0-9]+)$', LaunderetteDetailView.as_view(), name='launderette_details'),
url(r'^admin/(?P<launderette_id>[0-9]+)/edit$', LaunderetteEditView.as_view(), name='launderette_edit'),
url(r'^admin/new$', LaunderetteCreateView.as_view(), name='launderette_new'),
url(r'^admin/machine/new$', MachineCreateView.as_view(), name='machine_new'),
url(r'^admin/machine/(?P<machine_id>[0-9]+)/edit$', MachineEditView.as_view(), name='machine_edit'),
url(r'^admin/machine/(?P<machine_id>[0-9]+)/delete$', MachineDeleteView.as_view(), name='machine_delete'),
]

View File

@ -1,5 +1,6 @@
from datetime import datetime, timedelta
from collections import OrderedDict
import pytz
from django.shortcuts import render
from django.views.generic import ListView, DetailView, RedirectView, TemplateView
@ -7,9 +8,10 @@ from django.views.generic.edit import UpdateView, CreateView, DeleteView, Proces
from django.forms.models import modelform_factory
from django.forms import CheckboxSelectMultiple
from django.utils.translation import ugettext as _
from django.utils.timezone import make_aware
from django.utils import dateparse
from django.core.urlresolvers import reverse_lazy
from django.conf import settings
from django.db import transaction
from core.models import Page
from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin, CanCreateMixin
@ -33,27 +35,50 @@ class LaunderetteBookMainView(CanViewMixin, ListView):
model = Launderette
template_name = 'launderette/launderette_book_choose.jinja'
class LaunderetteBookView(DetailView):
class LaunderetteBookView(CanViewMixin, DetailView):
"""Display the launderette schedule"""
model = Launderette
pk_url_kwarg = "launderette_id"
template_name = 'launderette/launderette_book.jinja'
def post(self, request, *args, **kwargs):
self.object = self.get_object()
if 'slot' in request.POST.keys() and request.user.is_authenticated():
subscriber = get_subscriber(request.user)
if subscriber.is_subscribed():
date = dateparse.parse_datetime(request.POST['slot'])
for m in self.object.machines.filter(is_working=True).all():
slot = Slot.objects.filter(start_date=date, machine=m).first()
print(slot)
if slot is None:
Slot(user=subscriber, start_date=date, machine=m, type="WASHING").save()
print("Saved")
break
def get(self, request, *args, **kwargs):
self.slot_type = "BOTH"
self.machines = {}
return super(LaunderetteBookView, self).get(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
self.slot_type = "BOTH"
self.machines = {}
with transaction.atomic():
self.object = self.get_object()
if 'slot_type' in request.POST.keys():
self.slot_type = request.POST['slot_type']
if 'slot' in request.POST.keys() and request.user.is_authenticated():
self.subscriber = get_subscriber(request.user)
if self.subscriber.is_subscribed():
self.date = dateparse.parse_datetime(request.POST['slot']).replace(tzinfo=pytz.UTC)
if self.slot_type == "WASHING":
if self.check_slot(self.slot_type):
Slot(user=self.subscriber, start_date=self.date, machine=self.machines[self.slot_type], type=self.slot_type).save()
elif self.slot_type == "DRYING":
if self.check_slot(self.slot_type):
Slot(user=self.subscriber, start_date=self.date, machine=self.machines[self.slot_type], type=self.slot_type).save()
else:
if self.check_slot("WASHING") and self.check_slot("DRYING", self.date + timedelta(hours=1)):
Slot(user=self.subscriber, start_date=self.date, machine=self.machines["WASHING"], type="WASHING").save()
Slot(user=self.subscriber, start_date=self.date + timedelta(hours=1),
machine=self.machines["DRYING"], type="DRYING").save()
return super(LaunderetteBookView, self).get(request, *args, **kwargs)
def check_slot(self, type, date=None):
if date is None: date = self.date
for m in self.object.machines.filter(is_working=True, type=type).all():
slot = Slot.objects.filter(start_date=date, machine=m).first()
if slot is None:
self.machines[type] = m
return True
return False
@staticmethod
def date_iterator(startDate, endDate, delta=timedelta(days=1)):
currentDate = startDate
@ -65,16 +90,20 @@ class LaunderetteBookView(DetailView):
""" Add page to the context """
kwargs = super(LaunderetteBookView, self).get_context_data(**kwargs)
kwargs['planning'] = OrderedDict()
start_date = make_aware(datetime.now().replace(hour=0, minute=0, second=0, microsecond=0))
kwargs['slot_type'] = self.slot_type
start_date = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0, tzinfo=pytz.UTC)
for date in LaunderetteBookView.date_iterator(start_date, start_date+timedelta(days=6), timedelta(days=1)):
kwargs['planning'][date] = []
for h in LaunderetteBookView.date_iterator(date, date+timedelta(days=1), timedelta(hours=1)):
free = False
for m in self.object.machines.filter(is_working=True).all():
s = Slot.objects.filter(start_date=h, machine=m).first()
if s is None:
free = True
if free and make_aware(datetime.now()) < h:
if self.slot_type == "BOTH" and self.check_slot("WASHING", h) and self.check_slot("DRYING", h + timedelta(hours=1)):
print("GUY")
free = True
elif self.slot_type == "WASHING" and self.check_slot("WASHING", h):
free = True
elif self.slot_type == "DRYING" and self.check_slot("DRYING", h):
free = True
if free and datetime.now().replace(tzinfo=pytz.UTC) < h:
kwargs['planning'][date].append(h)
else:
kwargs['planning'][date].append(None)
@ -105,5 +134,37 @@ class LaunderetteEditView(CanViewMixin, UpdateView):
class LaunderetteCreateView(CanCreateMixin, CreateView):
"""Create a new launderette"""
model = Launderette
fields = ['name', 'sellers']
fields = ['name']
template_name = 'core/create.jinja'
class MachineEditView(CanEditPropMixin, UpdateView):
"""Edit a machine"""
model = Machine
pk_url_kwarg = "machine_id"
fields = ['name', 'launderette', 'type', 'is_working']
template_name = 'core/edit.jinja'
class MachineDeleteView(CanEditPropMixin, DeleteView):
"""Edit a machine"""
model = Machine
pk_url_kwarg = "machine_id"
template_name = 'core/delete_confirm.jinja'
success_url = reverse_lazy('launderette:launderette_list')
class MachineCreateView(CanCreateMixin, CreateView):
"""Create a new machine"""
model = Machine
fields = ['name', 'launderette', 'type']
template_name = 'core/create.jinja'
def get_initial(self):
ret = super(MachineCreateView, self).get_initial()
if 'launderette' in self.request.GET.keys():
obj = Launderette.objects.filter(id=int(self.request.GET['launderette'])).first()
if obj is not None:
ret['launderette'] = obj.id
return ret