views.py 10.6 KB
Newer Older
Skia's avatar
Skia committed
1 2
from datetime import datetime, timedelta
from collections import OrderedDict
3
import pytz
Skia's avatar
Skia committed
4

Skia's avatar
Skia committed
5 6 7 8 9 10
from django.shortcuts import render
from django.views.generic import ListView, DetailView, RedirectView, TemplateView
from django.views.generic.edit import UpdateView, CreateView, DeleteView, ProcessFormView, FormMixin
from django.forms.models import modelform_factory
from django.forms import CheckboxSelectMultiple
from django.utils.translation import ugettext as _
Skia's avatar
Skia committed
11
from django.utils import dateparse
12
from django.core.urlresolvers import reverse_lazy
Skia's avatar
Skia committed
13
from django.conf import settings
14
from django.db import transaction
15
from django import forms
Skia's avatar
Skia committed
16 17

from core.models import Page
18
from club.models import Club
Skia's avatar
Skia committed
19 20
from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin, CanCreateMixin
from launderette.models import Launderette, Token, Machine, Slot
Skia's avatar
Skia committed
21
from subscription.views import get_subscriber
22 23
from counter.models import Counter, Customer
from counter.views import GetUserForm
Skia's avatar
Skia committed
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39

# For users

class LaunderetteMainView(TemplateView):
    """Main presentation view"""
    template_name = 'launderette/launderette_main.jinja'

    def get_context_data(self, **kwargs):
        """ Add page to the context """
        kwargs = super(LaunderetteMainView, self).get_context_data(**kwargs)
        kwargs['page'] = Page.objects.filter(name='launderette').first()
        return kwargs

class LaunderetteBookMainView(CanViewMixin, ListView):
    """Choose which launderette to book"""
    model = Launderette
Skia's avatar
Skia committed
40
    template_name = 'launderette/launderette_book_choose.jinja'
Skia's avatar
Skia committed
41

42
class LaunderetteBookView(CanViewMixin, DetailView):
Skia's avatar
Skia committed
43 44 45 46 47
    """Display the launderette schedule"""
    model = Launderette
    pk_url_kwarg = "launderette_id"
    template_name = 'launderette/launderette_book.jinja'

48 49 50 51 52
    def get(self, request, *args, **kwargs):
        self.slot_type = "BOTH"
        self.machines = {}
        return super(LaunderetteBookView, self).get(request, *args, **kwargs)

Skia's avatar
Skia committed
53
    def post(self, request, *args, **kwargs):
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
        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()
Skia's avatar
Skia committed
75 76
        return super(LaunderetteBookView, self).get(request, *args, **kwargs)

77 78 79 80 81 82 83 84 85
    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

Skia's avatar
Skia committed
86 87 88 89 90 91 92 93 94 95 96
    @staticmethod
    def date_iterator(startDate, endDate, delta=timedelta(days=1)):
        currentDate = startDate
        while currentDate < endDate:
            yield currentDate
            currentDate += delta

    def get_context_data(self, **kwargs):
        """ Add page to the context """
        kwargs = super(LaunderetteBookView, self).get_context_data(**kwargs)
        kwargs['planning'] = OrderedDict()
97 98
        kwargs['slot_type'] = self.slot_type
        start_date = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0, tzinfo=pytz.UTC)
Skia's avatar
Skia committed
99 100 101 102
        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
103 104 105 106 107 108 109
                if self.slot_type == "BOTH" and self.check_slot("WASHING", h) and self.check_slot("DRYING", h + timedelta(hours=1)):
                    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:
Skia's avatar
Skia committed
110 111 112 113
                    kwargs['planning'][date].append(h)
                else:
                    kwargs['planning'][date].append(None)
        return kwargs
Skia's avatar
Skia committed
114 115 116

# For admins

117
class LaunderetteListView(CanEditPropMixin, ListView):
Skia's avatar
Skia committed
118 119 120 121
    """Choose which launderette to administer"""
    model = Launderette
    template_name = 'launderette/launderette_list.jinja'

122
class LaunderetteEditView(CanEditPropMixin, UpdateView):
Skia's avatar
Skia committed
123 124 125
    """Edit a launderette"""
    model = Launderette
    pk_url_kwarg = "launderette_id"
126
    fields = ['name']
Skia's avatar
Skia committed
127 128 129 130 131
    template_name = 'core/edit.jinja'

class LaunderetteCreateView(CanCreateMixin, CreateView):
    """Create a new launderette"""
    model = Launderette
132
    fields = ['name']
Skia's avatar
Skia committed
133
    template_name = 'core/create.jinja'
134

135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222
    def form_valid(self, form):
        club = Club.objects.filter(unix_name=settings.SITH_LAUNDERETTE_MANAGER['unix_name']).first()
        c = Counter(name=form.instance.name, club=club, type='OFFICE')
        c.save()
        form.instance.counter = c
        return super(LaunderetteCreateView, self).form_valid(form)

class LaunderetteDetailView(CanEditPropMixin, DetailView):
    """The admin page of the launderette"""
    model = Launderette
    pk_url_kwarg = "launderette_id"
    template_name = 'launderette/launderette_detail.jinja'

class LaunderetteMainClickView(DetailView, ProcessFormView, FormMixin):
    """The click page of the launderette"""
    model = Launderette
    pk_url_kwarg = "launderette_id"
    template_name = 'counter/counter_main.jinja'
    form_class = GetUserForm # Form to enter a client code and get the corresponding user id

    def get_context_data(self, **kwargs):
        """
        We handle here the login form for the barman
        """
        if self.request.method == 'POST':
            self.object = self.get_object()
        kwargs = super(LaunderetteMainClickView, self).get_context_data(**kwargs)
        kwargs['counter'] = self.object.counter
        kwargs['form'] = self.get_form()
        kwargs['barmen'] = [self.request.user]
        if 'last_basket' in self.request.session.keys():
            kwargs['last_basket'] = self.request.session.pop('last_basket')
            kwargs['last_customer'] = self.request.session.pop('last_customer')
            kwargs['last_total'] = self.request.session.pop('last_total')
            kwargs['new_customer_amount'] = self.request.session.pop('new_customer_amount')
        return kwargs

    def form_valid(self, form):
        """
        We handle here the redirection, passing the user id of the asked customer
        """
        self.kwargs['user_id'] = form.cleaned_data['user_id']
        return super(LaunderetteMainClickView, self).form_valid(form)

    def get_success_url(self):
        return reverse_lazy('launderette:click', args=self.args, kwargs=self.kwargs)

class LaunderetteClickView(CanEditMixin, DetailView):
    """The click page of the launderette"""
    model = Launderette
    pk_url_kwarg = "launderette_id"
    template_name = 'launderette/launderette_click.jinja'

    def generate_form(self):
        fields = OrderedDict()
        for s in self.subscriber.slots.all():
            fields["%s-%s-%s-%s" % (s.user, s.start_date, s.type, s.machine)] = forms.CharField(max_length=5,
                    label="%s - %s" % (s.get_type_display(), s.start_date))
        return type('ClickForm', (forms.BaseForm,), { 'base_fields': fields })()

    def get(self, request, *args, **kwargs):
        """Simple get view"""
        self.customer = Customer.objects.filter(user__id=self.kwargs['user_id']).first()
        self.subscriber = get_subscriber(self.customer.user)
        request.session['not_enough'] = False
        return super(LaunderetteClickView, self).get(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        """ Handle the many possibilities of the post request """
        self.object = self.get_object()
        self.customer = Customer.objects.filter(user__id=self.kwargs['user_id']).first()
        self.subscriber = get_subscriber(self.customer.user)
        request.session['not_enough'] = False
        context = self.get_context_data(object=self.object)
        return self.render_to_response(context)


    def get_context_data(self, **kwargs):
        """
        We handle here the login form for the barman
        """
        kwargs = super(LaunderetteClickView, self).get_context_data(**kwargs)
        kwargs['counter'] = self.object.counter
        kwargs['customer'] = self.customer
        kwargs['form'] = self.generate_form()
        return kwargs


223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253

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