Commit 70021391 authored by Skia's avatar Skia

Finish the launderette click view

parent 2cf39671
Pipeline #81 failed with stage
in 2 minutes
......@@ -17,8 +17,7 @@
{# if the user is member of a club, he can view the subscription state #}
<p>
{% if get_subscriber(profile).is_subscribed() %}
{% trans subscription_end=get_subscriber(profile).subscriptions.last().subscription_end %}
User is subscriber until {{ subscription_end }}{% endtrans %}
{% trans subscription_end=get_subscriber(profile).subscriptions.last().subscription_end %}User is subscriber until {{ subscription_end }}{% endtrans %}
{% else %}
{% trans %}User is not subscribed. {% endtrans %}
<a href="{{ url('subscription:subscription') }}?member={{ profile.id }}">{% trans %}New subscription{% endtrans %}</a>
......
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('counter', '0011_counter_sellers'),
]
operations = [
migrations.AddField(
model_name='refilling',
name='is_validated',
field=models.BooleanField(default=False, verbose_name='is validated'),
),
migrations.AddField(
model_name='selling',
name='is_validated',
field=models.BooleanField(default=False, verbose_name='is validated'),
),
migrations.AddField(
model_name='selling',
name='label',
field=models.CharField(max_length=30, default='troll', verbose_name='label'),
preserve_default=False,
),
migrations.AlterField(
model_name='selling',
name='product',
field=models.ForeignKey(related_name='sellings', to='counter.Product', blank=True),
),
]
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('counter', '0012_auto_20160801_2016'),
]
operations = [
migrations.AlterField(
model_name='selling',
name='product',
field=models.ForeignKey(to='counter.Product', null=True, related_name='sellings', blank=True),
),
]
from django.db import models
from django.db import models, DataError
from django.utils.translation import ugettext_lazy as _
from django.utils import timezone
from django.conf import settings
from django.core.urlresolvers import reverse
from django.forms import ValidationError
from datetime import timedelta
from random import randrange
......@@ -32,6 +33,11 @@ class Customer(models.Model):
def generate_account_id():
return randrange(0, 4000) # TODO: improve me!
def save(self, *args, **kwargs):
if self.amount < 0:
raise ValidationError(_("Not enough money"))
super(Customer, self).save(*args, **kwargs)
class ProductType(models.Model):
"""
This describes a product type
......@@ -190,6 +196,7 @@ class Refilling(models.Model):
choices=settings.SITH_COUNTER_PAYMENT_METHOD, default='cash')
bank = models.CharField(_('bank'), max_length=255,
choices=settings.SITH_COUNTER_BANK, default='other')
is_validated = models.BooleanField(_('is validated'), default=False)
class Meta:
verbose_name = _("refilling")
......@@ -202,38 +209,41 @@ class Refilling(models.Model):
def save(self, *args, **kwargs):
self.full_clean()
self.customer.amount += self.amount
self.customer.save()
if not self.is_validated:
self.customer.amount += self.amount
self.customer.save()
self.is_validated = True
super(Refilling, self).save(*args, **kwargs)
class Selling(models.Model):
"""
Handle the sellings
"""
product = models.ForeignKey(Product, related_name="sellings", blank=False)
label = models.CharField(_("label"), max_length=30)
product = models.ForeignKey(Product, related_name="sellings", null=True, blank=True)
counter = models.ForeignKey(Counter, related_name="sellings", blank=False)
unit_price = CurrencyField(_('unit price'))
quantity = models.IntegerField(_('quantity'))
seller = models.ForeignKey(User, related_name="sellings_as_operator", blank=False)
customer = models.ForeignKey(Customer, related_name="buyings", blank=False)
date = models.DateTimeField(_('date'), auto_now=True)
is_validated = models.BooleanField(_('is validated'), default=False)
class Meta:
verbose_name = _("selling")
def __str__(self):
return "Selling: %d x %s (%f) for %s" % (self.quantity, self.product.name,
return "Selling: %d x %s (%f) for %s" % (self.quantity, self.label,
self.quantity*self.unit_price, self.customer.user.get_display_name())
def save(self, *args, **kwargs):
self.full_clean()
self.customer.amount -= self.quantity * self.unit_price
self.customer.save()
if not self.is_validated:
self.customer.amount -= self.quantity * self.unit_price
self.customer.save()
self.is_validated = True
super(Selling, self).save(*args, **kwargs)
# def get_absolute_url(self):
# return reverse('counter:details', kwargs={'counter_id': self.id})
class Permanency(models.Model):
"""
This class aims at storing a traceability of who was barman where and when
......
......@@ -35,7 +35,7 @@
<tr>
<td>{% trans %}Date{% endtrans %}</td>
<td>{% trans %}Barman{% endtrans %}</td>
<td>{% trans %}Product{% endtrans %}</td>
<td>{% trans %}Label{% endtrans %}</td>
<td>{% trans %}Quantity{% endtrans %}</td>
<td>{% trans %}Total{% endtrans %}</td>
</tr>
......@@ -45,7 +45,7 @@
<tr>
<td>{{ i.date|localtime|date(DATETIME_FORMAT) }} - {{ i.date|localtime|time(DATETIME_FORMAT) }}</td>
<td>{{ i.seller }}</td>
<td>{{ i.product }}</td>
<td>{{ i.label }}</td>
<td>{{ i.quantity }}</td>
<td>{{ i.quantity * i.unit_price }}</td>
</tr>
......
......@@ -13,9 +13,11 @@ from django.conf import settings
from django.db import DataError, transaction
import re
from datetime import date, timedelta
from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin, CanCreateMixin
from subscription.models import Subscriber
from subscription.views import get_subscriber
from counter.models import Counter, Customer, Product, Selling, Refilling, ProductType
class GetUserForm(forms.Form):
......@@ -28,7 +30,7 @@ class GetUserForm(forms.Form):
"""
code = forms.CharField(label="Code", max_length=10, required=False)
id = forms.IntegerField(label="ID", required=False)
# TODO: add a nice JS widget to search for users
# TODO: add a nice JS widget to search for users
def as_p(self):
self.fields['code'].widget.attrs['autofocus'] = True
......@@ -36,14 +38,16 @@ class GetUserForm(forms.Form):
def clean(self):
cleaned_data = super(GetUserForm, self).clean()
user = None
cus = None
if cleaned_data['code'] != "":
user = Customer.objects.filter(account_id=cleaned_data['code']).first()
cus = Customer.objects.filter(account_id=cleaned_data['code']).first()
elif cleaned_data['id'] is not None:
user = Customer.objects.filter(user=cleaned_data['id']).first()
if user is None:
cus = Customer.objects.filter(user=cleaned_data['id']).first()
sub = get_subscriber(cus.user) if cus is not None else None
if cus is None or sub is None or (date.today() - sub.subscriptions.last().subscription_end) > timedelta(days=90):
raise forms.ValidationError(_("User not found"))
cleaned_data['user_id'] = user.user.id
cleaned_data['user_id'] = cus.user.id
cleaned_data['user'] = cus.user
return cleaned_data
class RefillForm(forms.ModelForm):
......@@ -238,7 +242,7 @@ class CounterClick(DetailView):
if uprice * infos['qty'] > self.customer.amount:
raise DataError(_("You have not enough money to buy all the basket"))
request.session['last_basket'].append("%d x %s" % (infos['qty'], p.name))
s = Selling(product=p, counter=self.object, unit_price=uprice,
s = Selling(label=p.name, product=p, counter=self.object, unit_price=uprice,
quantity=infos['qty'], seller=self.operator, customer=self.customer)
s.save()
request.session['last_customer'] = self.customer.user.get_display_name()
......
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('counter', '0011_counter_sellers'),
('launderette', '0007_auto_20160801_1929'),
]
operations = [
migrations.AddField(
model_name='token',
name='product',
field=models.ForeignKey(related_name='tokens', to='counter.Product', default=1, verbose_name='product'),
preserve_default=False,
),
]
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('launderette', '0008_token_product'),
]
operations = [
migrations.RemoveField(
model_name='token',
name='product',
),
]
......@@ -80,6 +80,9 @@ class Token(models.Model):
return True
return False
def __str__(self):
return self.__class__._meta.verbose_name + " " + self.get_type_display() + " #" + self.name + " (" + self.launderette.name + ")"
class Slot(models.Model):
start_date = models.DateTimeField(_('start date'))
type = models.CharField(_('type'), max_length=10, choices=[('WASHING', _('Washing')), ('DRYING', _('Drying'))])
......@@ -91,9 +94,6 @@ class Slot(models.Model):
verbose_name = _('Slot')
ordering = ['start_date']
def full_clean(self):
return super(Slot, self).full_clean()
def __str__(self):
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)
......
......@@ -21,7 +21,8 @@ from club.models import Club
from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin, CanCreateMixin
from launderette.models import Launderette, Token, Machine, Slot
from subscription.views import get_subscriber
from counter.models import Counter, Customer
from subscription.models import Subscriber
from counter.models import Counter, Customer, Selling
from counter.views import GetUserForm
# For users
......@@ -147,12 +148,35 @@ class LaunderetteDetailView(CanEditPropMixin, DetailView):
pk_url_kwarg = "launderette_id"
template_name = 'launderette/launderette_detail.jinja'
class GetLaunderetteUserForm(GetUserForm):
def clean(self):
cleaned_data = super(GetLaunderetteUserForm, self).clean()
sub = get_subscriber(cleaned_data['user'])
if sub.slots.all().count() <= 0:
raise forms.ValidationError(_("User has booked no slot"))
return cleaned_data
class LaunderetteMainClickView(CanEditMixin, BaseFormView, DetailView):
"""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
form_class = GetLaunderetteUserForm # Form to enter a client code and get the corresponding user id
def get(self, request, *args, **kwargs):
self.object = self.get_object()
return super(LaunderetteMainClickView, self).get(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
self.object = self.get_object()
return super(LaunderetteMainClickView, self).post(request, *args, **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_context_data(self, **kwargs):
"""
......@@ -169,19 +193,39 @@ class LaunderetteMainClickView(CanEditMixin, BaseFormView, DetailView):
kwargs['new_customer_amount'] = self.request.session.pop('new_customer_amount', None)
return kwargs
def form_valid(self, form):
"""
We handle here the redirection, passing the user id of the asked customer
"""
self.object = self.get_object()
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 ClickTokenForm(forms.BaseForm):
pass
def clean(self):
with transaction.atomic():
operator = Subscriber.objects.filter(id=self.operator_id).first()
customer = Customer.objects.filter(user__id=self.subscriber_id).first()
counter = Counter.objects.filter(id=self.counter_id).first()
subscriber = get_subscriber(customer.user)
self.last_basket = {
'last_basket': [],
'last_customer': customer.user.get_display_name(),
}
total = 0
for k,t in self.cleaned_data.items():
if t is not None:
slot_id = int(k[5:])
slot = Slot.objects.filter(id=slot_id).first()
slot.token = t
slot.save()
t.user = subscriber
t.borrow_date = datetime.now().replace(tzinfo=pytz.UTC)
t.save()
price = settings.SITH_LAUNDERETTE_PRICES[t.type]
s = Selling(label="Jeton "+t.get_type_display()+" N°"+t.name, product=None, counter=counter, unit_price=price,
quantity=1, seller=operator, customer=customer)
s.save()
total += price
self.last_basket['last_basket'].append("Jeton "+t.get_type_display()+" N°"+t.name)
self.last_basket['new_customer_amount'] = str(customer.amount)
self.last_basket['last_total'] = str(total)
return self.cleaned_data
class LaunderetteClickView(CanEditMixin, DetailView, BaseFormView):
"""The click page of the launderette"""
......@@ -196,30 +240,29 @@ class LaunderetteClickView(CanEditMixin, DetailView, BaseFormView):
def clean_field(self2):
t_name = str(self2.data[field_name])
if t_name != "":
t = Token.objects.filter(name=str(self2.data[field_name]), type=slot.type, launderette=self.object).first()
t = Token.objects.filter(name=str(self2.data[field_name]), type=slot.type, launderette=self.object,
user=None).first()
if t is None:
raise forms.ValidationError(_("Token not found"))
return t
return clean_field
for s in self.subscriber.slots.filter(token=None).all():
field_name = "slot-%s" % (str(s.id))
fields[field_name] = forms.CharField(max_length=5, required=False,
label="%s - %s" % (s.get_type_display(), defaultfilters.date(s.start_date, "j N Y H:i")))
# XXX l10n settings.DATETIME_FORMAT did'nt work here :/
# XXX l10n settings.DATETIME_FORMAT didn't work here :/
kwargs["clean_"+field_name] = clean_field_factory(field_name, s)
def clean_form(self2):
raise forms.ValidationError(_("Not enough money"))
return self2.cleaned_data
kwargs['subscriber_id'] = self.subscriber.id
kwargs['counter_id'] = self.object.counter.id
kwargs['operator_id'] = self.operator.id
kwargs['base_fields'] = fields
kwargs['clean'] = clean_form
return type('ClickForm', (ClickTokenForm,), kwargs)
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)
self.operator = request.user
return super(LaunderetteClickView, self).get(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
......@@ -227,13 +270,14 @@ class LaunderetteClickView(CanEditMixin, DetailView, BaseFormView):
self.object = self.get_object()
self.customer = Customer.objects.filter(user__id=self.kwargs['user_id']).first()
self.subscriber = get_subscriber(self.customer.user)
self.operator = request.user
return super(LaunderetteClickView, self).post(request, *args, **kwargs)
def form_valid(self, form):
"""
We handle here the redirection, passing the user id of the asked customer
"""
self.request.session['last_basket'] = ["GUY"]
self.request.session.update(form.last_basket)
return super(LaunderetteClickView, self).form_valid(form)
def get_context_data(self, **kwargs):
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment