Improve launderette, need to finish the click view

This commit is contained in:
Skia 2016-08-01 16:36:16 +02:00
parent ba48adab6d
commit 4d8e7b0875
13 changed files with 237 additions and 24 deletions

View File

@ -44,6 +44,10 @@ class Command(BaseCommand):
bar_club = Club(name=settings.SITH_BAR_MANAGER['name'], unix_name=settings.SITH_BAR_MANAGER['unix_name'], bar_club = Club(name=settings.SITH_BAR_MANAGER['name'], unix_name=settings.SITH_BAR_MANAGER['unix_name'],
address=settings.SITH_BAR_MANAGER['address']) address=settings.SITH_BAR_MANAGER['address'])
bar_club.save() bar_club.save()
launderette_club = Club(name=settings.SITH_LAUNDERETTE_MANAGER['name'],
unix_name=settings.SITH_LAUNDERETTE_MANAGER['unix_name'],
address=settings.SITH_LAUNDERETTE_MANAGER['address'])
launderette_club.save()
for b in settings.SITH_COUNTER_BARS: for b in settings.SITH_COUNTER_BARS:
g = Group(name=b[1]+" admin") g = Group(name=b[1]+" admin")
g.save() g.save()
@ -63,6 +67,12 @@ class Command(BaseCommand):
Welcome to the wiki page! Welcome to the wiki page!
""").save() """).save()
p = Page(name="launderette")
p.set_lock(root)
p.save()
p.set_lock(root)
PageRev(page=p, title="", author=root, content="").save()
# Here we add a lot of test datas, that are not necessary for the Sith, but that provide a basic development environment # Here we add a lot of test datas, that are not necessary for the Sith, but that provide a basic development environment
if not options['prod']: if not options['prod']:
# Adding user Skia # Adding user Skia

View File

@ -86,7 +86,6 @@ class PageCreateView(CanEditPropMixin, CreateView):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(PageCreateView, self).get_context_data(**kwargs) context = super(PageCreateView, self).get_context_data(**kwargs)
print(context)
context['new_page'] = True context['new_page'] = True
return context return context

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 = [
('subscription', '0002_auto_20160718_1805'),
('counter', '0010_auto_20160728_1820'),
]
operations = [
migrations.AddField(
model_name='counter',
name='sellers',
field=models.ManyToManyField(verbose_name='sellers', to='subscription.Subscriber', related_name='counters', blank=True),
),
]

View File

@ -10,6 +10,8 @@ from random import randrange
from club.models import Club from club.models import Club
from accounting.models import CurrencyField from accounting.models import CurrencyField
from core.models import Group, User from core.models import Group, User
from subscription.models import Subscriber
from subscription.views import get_subscriber
class Customer(models.Model): class Customer(models.Model):
""" """
@ -94,6 +96,7 @@ class Counter(models.Model):
type = models.CharField(_('subscription type'), type = models.CharField(_('subscription type'),
max_length=255, max_length=255,
choices=[('BAR',_('Bar')), ('OFFICE',_('Office')), ('EBOUTIC',_('Eboutic'))]) choices=[('BAR',_('Bar')), ('OFFICE',_('Office')), ('EBOUTIC',_('Eboutic'))])
sellers = models.ManyToManyField(Subscriber, verbose_name=_('sellers'), related_name='counters', blank=True)
edit_groups = models.ManyToManyField(Group, related_name="editable_counters", blank=True) edit_groups = models.ManyToManyField(Group, related_name="editable_counters", blank=True)
view_groups = models.ManyToManyField(Group, related_name="viewable_counters", blank=True) view_groups = models.ManyToManyField(Group, related_name="viewable_counters", blank=True)
barmen_session = {} barmen_session = {}
@ -102,8 +105,8 @@ class Counter(models.Model):
verbose_name = _('counter') verbose_name = _('counter')
def __getattribute__(self, name): def __getattribute__(self, name):
if name == "owner_group": if name == "edit_groups":
return Group.objects.filter(name=self.club.unix_name+settings.SITH_BOARD_SUFFIX).first() return Group.objects.filter(name=self.club.unix_name+settings.SITH_BOARD_SUFFIX).all()
return object.__getattribute__(self, name) return object.__getattribute__(self, name)
def __str__(self): def __str__(self):
@ -114,11 +117,14 @@ class Counter(models.Model):
return reverse('eboutic:main') return reverse('eboutic:main')
return reverse('counter:details', kwargs={'counter_id': self.id}) return reverse('counter:details', kwargs={'counter_id': self.id})
def can_be_edited_by(self, user): def is_owned_by(self, user):
return user.is_in_group(settings.SITH_GROUPS['counter-admin']['name']) return user.is_in_group(settings.SITH_GROUPS['counter-admin']['name'])
def can_be_viewed_by(self, user): def can_be_viewed_by(self, user):
return user.is_in_group(settings.SITH_MAIN_BOARD_GROUP) if self.type == "BAR" or self.type == "EBOUTIC":
return True
sub = get_subscriber(request.user)
return user.is_in_group(settings.SITH_MAIN_BOARD_GROUP) or sub in self.sellers
def add_barman(counter_id, user_id): def add_barman(counter_id, user_id):
""" """

View File

@ -16,6 +16,10 @@
</form> </form>
{% endmacro %} {% endmacro %}
{% block title %}
{{ counter }}
{% endblock %}
{% block content %} {% block content %}
<h3>{% trans %}Counter{% endtrans %}</h3> <h3>{% trans %}Counter{% endtrans %}</h3>
<h4>{{ counter }}</h4> <h4>{{ counter }}</h4>

View File

@ -25,7 +25,7 @@
{% endif %} {% endif %}
{% if barmen %} {% if barmen %}
<p>{% trans %}Enter client code:{% endtrans %}</p> <p>{% trans %}Enter client code:{% endtrans %}</p>
<form method="post" action="{{ url('counter:details', counter_id=counter.id) }}"> <form method="post" action="">
{% csrf_token %} {% csrf_token %}
{{ form.as_p() }} {{ form.as_p() }}
<p><input type="submit" value="{% trans %}validate{% endtrans %}" /></p> <p><input type="submit" value="{% trans %}validate{% endtrans %}" /></p>

View File

@ -322,7 +322,7 @@ class CounterListView(CanViewMixin, ListView):
model = Counter model = Counter
template_name = 'counter/counter_list.jinja' template_name = 'counter/counter_list.jinja'
class CounterEditView(CanEditMixin, UpdateView): class CounterEditView(CanEditPropMixin, UpdateView):
""" """
Edit a counter's main informations (for the counter's admin) Edit a counter's main informations (for the counter's admin)
""" """
@ -352,7 +352,7 @@ class CounterDeleteView(CanEditMixin, DeleteView):
# Product management # Product management
class ProductTypeListView(CanViewMixin, ListView): class ProductTypeListView(CanEditPropMixin, ListView):
""" """
A list view for the admins A list view for the admins
""" """
@ -376,7 +376,7 @@ class ProductTypeEditView(CanEditPropMixin, UpdateView):
fields = ['name', 'description', 'icon'] fields = ['name', 'description', 'icon']
pk_url_kwarg = "type_id" pk_url_kwarg = "type_id"
class ProductListView(CanViewMixin, ListView): class ProductListView(CanEditPropMixin, ListView):
""" """
A list view for the admins A list view for the admins
""" """

View File

@ -0,0 +1,54 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('counter', '0011_counter_sellers'),
('subscription', '0002_auto_20160718_1805'),
('launderette', '0004_token_start_date'),
]
operations = [
migrations.AlterModelOptions(
name='slot',
options={'verbose_name': 'Slot', 'ordering': ['start_date']},
),
migrations.RemoveField(
model_name='launderette',
name='sellers',
),
migrations.AddField(
model_name='launderette',
name='counter',
field=models.OneToOneField(related_name='launderette', default=1, verbose_name='counter', to='counter.Counter'),
preserve_default=False,
),
migrations.AddField(
model_name='token',
name='borrow_date',
field=models.DateTimeField(null=True, verbose_name='borrow date'),
),
migrations.AddField(
model_name='token',
name='user',
field=models.ForeignKey(related_name='tokens', default=1, verbose_name='user', to='subscription.Subscriber'),
preserve_default=False,
),
migrations.AlterField(
model_name='token',
name='name',
field=models.CharField(max_length=5, verbose_name='name'),
),
migrations.AlterUniqueTogether(
name='token',
unique_together=set([('name', 'launderette', 'type')]),
),
migrations.RemoveField(
model_name='token',
name='start_date',
),
]

View File

@ -4,13 +4,15 @@ from django.conf import settings
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from core.models import User from core.models import User
from counter.models import Counter
from subscription.models import Subscriber from subscription.models import Subscriber
from subscription.views import get_subscriber
# Create your models here. # Create your models here.
class Launderette(models.Model): class Launderette(models.Model):
name = models.CharField(_('name'), max_length=30) name = models.CharField(_('name'), max_length=30)
sellers = models.ManyToManyField(Subscriber, verbose_name=_('sellers'), related_name='launderettes', blank=True) counter = models.OneToOneField(Counter, verbose_name=_('counter'), related_name='launderette')
class Meta: class Meta:
verbose_name = _('Launderette') verbose_name = _('Launderette')
@ -23,6 +25,10 @@ class Launderette(models.Model):
return True return True
return False return False
def can_be_edited_by(self, user):
sub = get_subscriber(request.user)
return sub in self.sellers.all()
def can_be_viewed_by(self, user): def can_be_viewed_by(self, user):
return user.is_in_group(settings.SITH_MAIN_MEMBERS_GROUP) return user.is_in_group(settings.SITH_MAIN_MEMBERS_GROUP)
@ -56,13 +62,15 @@ class Machine(models.Model):
return reverse('launderette:launderette_details', kwargs={"launderette_id": self.launderette.id}) return reverse('launderette:launderette_details', kwargs={"launderette_id": self.launderette.id})
class Token(models.Model): class Token(models.Model):
name = models.IntegerField(_('name')) name = models.CharField(_('name'), max_length=5)
launderette = models.ForeignKey(Launderette, related_name='tokens', verbose_name=_('launderette')) launderette = models.ForeignKey(Launderette, related_name='tokens', verbose_name=_('launderette'))
type = models.CharField(_('type'), max_length=10, choices=[('WASHING', _('Washing')), ('DRYING', _('Drying'))]) type = models.CharField(_('type'), max_length=10, choices=[('WASHING', _('Washing')), ('DRYING', _('Drying'))])
start_date = models.DateTimeField(_('start date')) borrow_date = models.DateTimeField(_('borrow date'), null=True)
user = models.ForeignKey(Subscriber, related_name='tokens', verbose_name=_('user'))
class Meta: class Meta:
verbose_name = _('Token') verbose_name = _('Token')
unique_together = ('name', 'launderette', 'type')
def is_owned_by(self, user): def is_owned_by(self, user):
""" """
@ -81,6 +89,7 @@ class Slot(models.Model):
class Meta: class Meta:
verbose_name = _('Slot') verbose_name = _('Slot')
ordering = ['start_date']
def full_clean(self): def full_clean(self):
return super(Slot, self).full_clean() return super(Slot, self).full_clean()

View File

@ -0,0 +1,17 @@
{% extends "core/base.jinja" %}
{% block title %}
{{ counter }}
{% endblock %}
{% block content %}
<h3>{% trans counter_name=counter %}{{ counter_name }} counter{% endtrans %}</h3>
<div>
Counter: {{ counter }}
<form method="post" action="{{ url('launderette:click', launderette_id=launderette.id, user_id=customer.user.id) }}" class="inline" style="display:inline">
{% csrf_token %}
{{ form.as_p() }}
<p><input type="submit" value="{% trans %}Go{% endtrans %}" /></p>
</form>
</div>
{% endblock %}

View File

@ -5,6 +5,15 @@
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<h3>{% trans %}Selling{% endtrans %}</h3>
<p><a href="{{ url('launderette:main_click', launderette_id=launderette.id) }}">{% trans %}Sell{% endtrans %}</a></p>
<h3>{% trans %}Tokens{% endtrans %}</h3>
<ul>
{% for t in launderette.tokens.all() %}
<li>{{ t }}</li>
{% endfor %}
</ul>
<hr>
<h3>{% trans %}Machines{% endtrans %}</h3> <h3>{% trans %}Machines{% endtrans %}</h3>
<p><a href="{{ url('launderette:machine_new') }}?launderette={{ launderette.id }}">{% trans %}New machine{% endtrans %}</a></p> <p><a href="{{ url('launderette:machine_new') }}?launderette={{ launderette.id }}">{% trans %}New machine{% endtrans %}</a></p>
<ul> <ul>

View File

@ -7,6 +7,8 @@ urlpatterns = [
url(r'^$', LaunderetteMainView.as_view(), name='launderette_main'), url(r'^$', LaunderetteMainView.as_view(), name='launderette_main'),
url(r'^book$', LaunderetteBookMainView.as_view(), name='book_main'), url(r'^book$', LaunderetteBookMainView.as_view(), name='book_main'),
url(r'^book/(?P<launderette_id>[0-9]+)$', LaunderetteBookView.as_view(), name='book_slot'), url(r'^book/(?P<launderette_id>[0-9]+)$', LaunderetteBookView.as_view(), name='book_slot'),
url(r'^(?P<launderette_id>[0-9]+)/click$', LaunderetteMainClickView.as_view(), name='main_click'),
url(r'^(?P<launderette_id>[0-9]+)/click/(?P<user_id>[0-9]+)$', LaunderetteClickView.as_view(), name='click'),
url(r'^admin$', LaunderetteListView.as_view(), name='launderette_list'), url(r'^admin$', LaunderetteListView.as_view(), name='launderette_list'),
url(r'^admin/(?P<launderette_id>[0-9]+)$', LaunderetteDetailView.as_view(), name='launderette_details'), 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/(?P<launderette_id>[0-9]+)/edit$', LaunderetteEditView.as_view(), name='launderette_edit'),

View File

@ -12,11 +12,15 @@ from django.utils import dateparse
from django.core.urlresolvers import reverse_lazy from django.core.urlresolvers import reverse_lazy
from django.conf import settings from django.conf import settings
from django.db import transaction from django.db import transaction
from django import forms
from core.models import Page from core.models import Page
from club.models import Club
from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin, CanCreateMixin from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin, CanCreateMixin
from launderette.models import Launderette, Token, Machine, Slot from launderette.models import Launderette, Token, Machine, Slot
from subscription.views import get_subscriber from subscription.views import get_subscriber
from counter.models import Counter, Customer
from counter.views import GetUserForm
# For users # For users
@ -97,7 +101,6 @@ class LaunderetteBookView(CanViewMixin, DetailView):
for h in LaunderetteBookView.date_iterator(date, date+timedelta(days=1), timedelta(hours=1)): for h in LaunderetteBookView.date_iterator(date, date+timedelta(days=1), timedelta(hours=1)):
free = False free = False
if self.slot_type == "BOTH" and self.check_slot("WASHING", h) and self.check_slot("DRYING", h + timedelta(hours=1)): if self.slot_type == "BOTH" and self.check_slot("WASHING", h) and self.check_slot("DRYING", h + timedelta(hours=1)):
print("GUY")
free = True free = True
elif self.slot_type == "WASHING" and self.check_slot("WASHING", h): elif self.slot_type == "WASHING" and self.check_slot("WASHING", h):
free = True free = True
@ -107,28 +110,20 @@ class LaunderetteBookView(CanViewMixin, DetailView):
kwargs['planning'][date].append(h) kwargs['planning'][date].append(h)
else: else:
kwargs['planning'][date].append(None) kwargs['planning'][date].append(None)
print("Taken")
return kwargs return kwargs
# For admins # For admins
class LaunderetteListView(CanViewMixin, ListView): class LaunderetteListView(CanEditPropMixin, ListView):
"""Choose which launderette to administer""" """Choose which launderette to administer"""
model = Launderette model = Launderette
template_name = 'launderette/launderette_list.jinja' template_name = 'launderette/launderette_list.jinja'
class LaunderetteDetailView(CanViewMixin, DetailView): class LaunderetteEditView(CanEditPropMixin, UpdateView):
"""The admin page of the launderette"""
model = Launderette
pk_url_kwarg = "launderette_id"
template_name = 'launderette/launderette_detail.jinja'
class LaunderetteEditView(CanViewMixin, UpdateView):
"""Edit a launderette""" """Edit a launderette"""
model = Launderette model = Launderette
pk_url_kwarg = "launderette_id" pk_url_kwarg = "launderette_id"
form_class = modelform_factory(Launderette, fields=['name', 'sellers'], fields = ['name']
widgets={'sellers':CheckboxSelectMultiple})
template_name = 'core/edit.jinja' template_name = 'core/edit.jinja'
class LaunderetteCreateView(CanCreateMixin, CreateView): class LaunderetteCreateView(CanCreateMixin, CreateView):
@ -137,6 +132,94 @@ class LaunderetteCreateView(CanCreateMixin, CreateView):
fields = ['name'] fields = ['name']
template_name = 'core/create.jinja' template_name = 'core/create.jinja'
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
class MachineEditView(CanEditPropMixin, UpdateView): class MachineEditView(CanEditPropMixin, UpdateView):
"""Edit a machine""" """Edit a machine"""