Finish the launderette click view

This commit is contained in:
Skia 2016-08-02 00:32:55 +02:00
parent 2cf39671e2
commit 7002139176
12 changed files with 330 additions and 171 deletions

View File

@ -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>

View File

@ -0,0 +1,35 @@
# -*- 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),
),
]

View File

@ -0,0 +1,19 @@
# -*- 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),
),
]

View File

@ -1,8 +1,9 @@
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()
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()
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

View File

@ -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>

View File

@ -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()

View File

@ -0,0 +1,21 @@
# -*- 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,
),
]

View File

@ -0,0 +1,18 @@
# -*- 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',
),
]

View File

@ -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)

View File

@ -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()+""+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()+""+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):

Binary file not shown.

View File

@ -6,7 +6,7 @@
msgid ""
msgstr ""
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-07-29 12:46+0200\n"
"POT-Creation-Date: 2016-08-02 00:28+0200\n"
"PO-Revision-Date: 2016-07-18\n"
"Last-Translator: Skia <skia@libskia.so>\n"
"Language-Team: AE info <ae.info@utbm.fr>\n"
@ -17,9 +17,9 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#: accounting/models.py:32 accounting/models.py:55 accounting/models.py:94
#: club/models.py:18 counter/models.py:38 counter/models.py:63
#: counter/models.py:91 launderette/models.py:12 launderette/models.py:36
#: launderette/models.py:59
#: club/models.py:18 counter/models.py:46 counter/models.py:71
#: counter/models.py:99 launderette/models.py:14 launderette/models.py:42
#: launderette/models.py:65
msgid "name"
msgstr "nom"
@ -31,12 +31,12 @@ msgstr "IBAN"
msgid "account number"
msgstr "numero de compte"
#: accounting/models.py:92 club/models.py:109 counter/models.py:237
#: launderette/models.py:62 launderette/models.py:76
#: accounting/models.py:92 club/models.py:109 counter/models.py:253
#: launderette/models.py:87
msgid "start date"
msgstr "date de début"
#: accounting/models.py:93 club/models.py:110 counter/models.py:238
#: accounting/models.py:93 club/models.py:110 counter/models.py:254
msgid "end date"
msgstr "date de fin"
@ -44,8 +44,8 @@ msgstr "date de fin"
msgid "is closed"
msgstr "est fermé"
#: accounting/models.py:97 accounting/models.py:136 counter/models.py:21
#: counter/models.py:179
#: accounting/models.py:97 accounting/models.py:136 counter/models.py:24
#: counter/models.py:191
msgid "amount"
msgstr "montant"
@ -57,12 +57,12 @@ msgstr "montant effectif"
msgid "number"
msgstr "numéro"
#: accounting/models.py:137 core/models.py:463 counter/models.py:182
#: counter/models.py:213 eboutic/models.py:13 eboutic/models.py:46
#: accounting/models.py:137 core/models.py:463 counter/models.py:194
#: counter/models.py:229 eboutic/models.py:13 eboutic/models.py:46
msgid "date"
msgstr "date"
#: accounting/models.py:138 accounting/models.py:198
#: accounting/models.py:138 accounting/models.py:198 counter/models.py:222
msgid "label"
msgstr "intitulé"
@ -70,7 +70,7 @@ msgstr "intitulé"
msgid "remark"
msgstr "remarque"
#: accounting/models.py:140 counter/models.py:183 eboutic/models.py:48
#: accounting/models.py:140 counter/models.py:195 eboutic/models.py:48
#: subscription/models.py:34
msgid "payment method"
msgstr "méthode de paiement"
@ -92,7 +92,7 @@ msgstr ""
"La date ne peut pas être avant la date de début du journal, qui est\n"
"%(start_date)s."
#: accounting/models.py:197 counter/models.py:66
#: accounting/models.py:197 counter/models.py:74
msgid "code"
msgstr "code"
@ -158,7 +158,7 @@ msgstr "Éditer"
#: accounting/templates/accounting/bank_account_details.jinja:19
#: accounting/templates/accounting/bank_account_list.jinja:16
#: core/templates/core/group_list.jinja:13
#: launderette/templates/launderette/launderette_detail.jinja:13
#: launderette/templates/launderette/launderette_detail.jinja:22
msgid "Delete"
msgstr "Supprimer"
@ -267,6 +267,7 @@ msgid "Date"
msgstr "Date"
#: accounting/templates/accounting/journal_details.jinja:22
#: counter/templates/counter/user_account.jinja:38
msgid "Label"
msgstr "Intitulé"
@ -315,7 +316,7 @@ msgid "You can not make loops in clubs"
msgstr "Vous ne pouvez pas faire de boucles dans les clubs"
#: club/models.py:107 eboutic/models.py:12 eboutic/models.py:45
#: launderette/models.py:80
#: launderette/models.py:69 launderette/models.py:91
msgid "user"
msgstr "nom d'utilisateur"
@ -327,8 +328,8 @@ msgstr "club"
msgid "role"
msgstr "rôle"
#: club/models.py:113 core/models.py:27 counter/models.py:39
#: counter/models.py:64
#: club/models.py:113 core/models.py:27 counter/models.py:47
#: counter/models.py:72
msgid "description"
msgstr "description"
@ -598,7 +599,7 @@ msgid "Confirm"
msgstr "Confirmation"
#: core/templates/core/delete_confirm.jinja:8
#: counter/templates/counter/counter_click.jinja:67
#: counter/templates/counter/counter_click.jinja:71
msgid "Cancel"
msgstr "Annuler"
@ -631,9 +632,7 @@ msgstr "Hello, world! Vous êtes sur la page d'accueil utilisant Jinja2."
#: core/templates/core/login.jinja:6
msgid "Your username and password didn't match. Please try again."
msgstr ""
"Votre nom d'utilisateur et votre mot de passe ne correspondent pas. Merci de "
"réessayer."
msgstr "Votre nom d'utilisateur et votre mot de passe ne correspondent pas. Merci de réessayer."
#: core/templates/core/login.jinja:11
msgid ""
@ -684,9 +683,7 @@ msgstr "La créer ?"
#: core/templates/core/page_detail.jinja:5
#, python-format
msgid "This may not be the last update, you are seeing revision %(rev_id)s!"
msgstr ""
"Ceci n'est peut-être pas la dernière version de la page. Vous consultez la "
"version %(rev_id)s."
msgstr "Ceci n'est peut-être pas la dernière version de la page. Vous consultez la version %(rev_id)s."
#: core/templates/core/page_hist.jinja:6
msgid "Page history"
@ -769,9 +766,7 @@ msgstr ""
#: core/templates/core/password_reset_email.jinja:4
msgid "Please go to the following page and choose a new password:"
msgstr ""
"Merci de vous rendre sur la page suivante et de choisir un nouveau mot de "
"passe :"
msgstr "Merci de vous rendre sur la page suivante et de choisir un nouveau mot de passe :"
#: core/templates/core/password_reset_email.jinja:8
msgid "Your username, in case you've forgotten: "
@ -796,11 +791,8 @@ msgid "Welcome %(user_name)s!"
msgstr "Bienvenue, %(user_name)s!"
#: core/templates/core/register.jinja:10
msgid ""
"You successfully registred and you will soon receive a confirmation mail."
msgstr ""
"Vous vous êtes correctement enregistré, et vous devriez recevoir rapidement "
"un email de confirmation."
msgid "You successfully registred and you will soon receive a confirmation mail."
msgstr "Vous vous êtes correctement enregistré, et vous devriez recevoir rapidement un email de confirmation."
#: core/templates/core/register.jinja:12
#, python-format
@ -830,19 +822,14 @@ msgid "Born: "
msgstr "Né le : "
#: core/templates/core/user_detail.jinja:20
#, python-format
msgid ""
"\n"
"User is subscriber until %(subscription_end)s"
msgstr ""
"\n"
"L'utilisateur est cotisant jusqu'au %(subscription_end)s"
msgid "User is subscriber until %(subscription_end)s"
msgstr "L'utilisateur est cotisant jusqu'au %(subscription_end)s"
#: core/templates/core/user_detail.jinja:23
#: core/templates/core/user_detail.jinja:22
msgid "User is not subscribed. "
msgstr "L'utilisateur n'est pas cotisant."
#: core/templates/core/user_detail.jinja:24
#: core/templates/core/user_detail.jinja:23
#: subscription/templates/subscription/subscription.jinja:4
#: subscription/templates/subscription/subscription.jinja:8
msgid "New subscription"
@ -883,7 +870,7 @@ msgid "Subscriptions"
msgstr "Cotisations"
#: core/templates/core/user_tools.jinja:19
#: core/templates/core/user_tools.jinja:21 launderette/models.py:16
#: core/templates/core/user_tools.jinja:21 launderette/models.py:18
#: launderette/templates/launderette/launderette_book.jinja:4
#: launderette/templates/launderette/launderette_book_choose.jinja:4
#: launderette/templates/launderette/launderette_main.jinja:4
@ -918,130 +905,140 @@ msgstr "Comptabilité générale"
msgid "Club account: "
msgstr "Compte club : "
#: counter/models.py:20
#: counter/models.py:23
msgid "account id"
msgstr "numéro de compte"
#: counter/models.py:24
#: counter/models.py:27
msgid "customer"
msgstr "client"
#: counter/models.py:25
#: counter/models.py:28
msgid "customers"
msgstr "clients"
#: counter/models.py:43 eboutic/models.py:77
#: counter/models.py:38 counter/templates/counter/counter_click.jinja:46
msgid "Not enough money"
msgstr "Solde insuffisant"
#: counter/models.py:51 eboutic/models.py:77
msgid "product type"
msgstr "type du produit"
#: counter/models.py:67
#: counter/models.py:75
msgid "purchase price"
msgstr "prix d'achat"
#: counter/models.py:68
#: counter/models.py:76
msgid "selling price"
msgstr "prix de vente"
#: counter/models.py:69
#: counter/models.py:77
msgid "special selling price"
msgstr "prix de vente spécial"
#: counter/models.py:74
#: counter/models.py:82
msgid "product"
msgstr "produit"
#: counter/models.py:94 subscription/models.py:29
#: counter/models.py:102 subscription/models.py:29
msgid "subscription type"
msgstr "type d'inscription"
#: counter/models.py:96
#: counter/models.py:104
msgid "Bar"
msgstr "Bar"
#: counter/models.py:96
#: counter/models.py:104
msgid "Office"
msgstr "Bureau"
#: counter/models.py:96 eboutic/templates/eboutic/eboutic_main.jinja:20
#: counter/models.py:104 eboutic/templates/eboutic/eboutic_main.jinja:20
#: eboutic/templates/eboutic/eboutic_makecommand.jinja:4
#: eboutic/templates/eboutic/eboutic_payment_result.jinja:4
msgid "Eboutic"
msgstr "Eboutic"
#: counter/models.py:102
#: counter/models.py:105
msgid "sellers"
msgstr "vendeurs"
#: counter/models.py:111 launderette/models.py:15
msgid "counter"
msgstr "comptoir"
#: counter/models.py:185
#: counter/models.py:197
msgid "bank"
msgstr "banque"
#: counter/models.py:189
#: counter/models.py:199 counter/models.py:230
msgid "is validated"
msgstr "est validé"
#: counter/models.py:202
msgid "refilling"
msgstr "rechargement"
#: counter/models.py:209 eboutic/models.py:78
#: counter/models.py:225 eboutic/models.py:78
msgid "unit price"
msgstr "prix unitaire"
#: counter/models.py:210 eboutic/models.py:79
#: counter/models.py:226 eboutic/models.py:79
msgid "quantity"
msgstr "quantité"
#: counter/models.py:216
#: counter/models.py:233
msgid "selling"
msgstr "vente"
#: counter/models.py:241
#: counter/models.py:257
msgid "permanency"
msgstr "permanence"
#: counter/templates/counter/counter_click.jinja:20
#: counter/templates/counter/counter_click.jinja:24
msgid "Counter"
msgstr "Comptoir"
#: counter/templates/counter/counter_click.jinja:22
#: counter/templates/counter/counter_click.jinja:26
msgid "Club: "
msgstr "Club : "
#: counter/templates/counter/counter_click.jinja:25
#: counter/templates/counter/counter_click.jinja:29
msgid "Customer"
msgstr "Client"
#: counter/templates/counter/counter_click.jinja:30
#: counter/templates/counter/counter_click.jinja:34
msgid "Refilling"
msgstr "Rechargement"
#: counter/templates/counter/counter_click.jinja:35
#: counter/templates/counter/counter_click.jinja:48
#: counter/templates/counter/counter_click.jinja:39
#: counter/templates/counter/counter_click.jinja:52
#: launderette/templates/launderette/launderette_click.jinja:14
msgid "Go"
msgstr "Valider"
#: counter/templates/counter/counter_click.jinja:40
#: counter/templates/counter/counter_click.jinja:44
#: launderette/templates/launderette/launderette_detail.jinja:8
msgid "Selling"
msgstr "Vente"
#: counter/templates/counter/counter_click.jinja:42
msgid "Not enough money"
msgstr "Solde insuffisant"
#: counter/templates/counter/counter_click.jinja:50
#: counter/templates/counter/counter_click.jinja:54
#: eboutic/templates/eboutic/eboutic_main.jinja:23
#: eboutic/templates/eboutic/eboutic_makecommand.jinja:7
msgid "Basket: "
msgstr "Panier : "
#: counter/templates/counter/counter_click.jinja:58
#: counter/templates/counter/counter_click.jinja:62
#: counter/templates/counter/counter_main.jinja:24
#: eboutic/templates/eboutic/eboutic_main.jinja:30
msgid "Total: "
msgstr "Total : "
#: counter/templates/counter/counter_click.jinja:62
#: counter/templates/counter/counter_click.jinja:66
msgid "Finish"
msgstr "Terminer"
#: counter/templates/counter/counter_click.jinja:69
#: counter/templates/counter/counter_click.jinja:73
#: eboutic/templates/eboutic/eboutic_main.jinja:37
msgid "Products: "
msgstr "Produits : "
@ -1064,6 +1061,7 @@ msgid "There is no counters in this website."
msgstr "Il n'y a pas de comptoirs dans ce site web."
#: counter/templates/counter/counter_main.jinja:12
#: launderette/templates/launderette/launderette_click.jinja:8
#, python-format
msgid "%(counter_name)s counter"
msgstr "Comptoir %(counter_name)s"
@ -1148,10 +1146,6 @@ msgstr "Barman"
msgid "Buyings"
msgstr "Achats"
#: counter/templates/counter/user_account.jinja:38
msgid "Product"
msgstr "Produit"
#: counter/templates/counter/user_account.jinja:39
msgid "Quantity"
msgstr "Quantité"
@ -1168,23 +1162,23 @@ msgstr "Factures"
msgid "Items"
msgstr "Articles"
#: counter/views.py:45
#: counter/views.py:48
msgid "User not found"
msgstr "Utilisateur non trouvé"
#: counter/views.py:207
#: counter/views.py:211
msgid "END"
msgstr "FIN"
#: counter/views.py:209
#: counter/views.py:213
msgid "CAN"
msgstr "ANN"
#: counter/views.py:239
#: counter/views.py:243
msgid "You have not enough money to buy all the basket"
msgstr "Vous n'avez pas assez d'argent pour acheter le panier"
#: eboutic/models.py:47 sith/settings.py:240 sith/settings_sample.py:243
#: eboutic/models.py:47 sith/settings.py:247 sith/settings_sample.py:243
msgid "Credit card"
msgstr "Carte banquaire"
@ -1225,11 +1219,8 @@ msgid "Pay with credit card"
msgstr "Payer avec une carte banquaire"
#: eboutic/templates/eboutic/eboutic_makecommand.jinja:34
msgid ""
"AE account payment disabled because your basket contains refilling items."
msgstr ""
"Paiement par compte AE désactivé parce que votre panier contient des bons de "
"rechargement."
msgid "AE account payment disabled because your basket contains refilling items."
msgstr "Paiement par compte AE désactivé parce que votre panier contient des bons de rechargement."
#: eboutic/templates/eboutic/eboutic_makecommand.jinja:39
msgid "Pay with Sith account"
@ -1251,49 +1242,49 @@ msgstr "Retourner à l'eboutic"
msgid "You do not have enough money to buy the basket"
msgstr "Vous n'avez pas assez d'argent pour acheter le panier"
#: launderette/models.py:13
msgid "sellers"
msgstr "vendeurs"
#: launderette/models.py:37 launderette/models.py:60
#: launderette/models.py:43 launderette/models.py:66
msgid "launderette"
msgstr "laverie"
#: launderette/models.py:38 launderette/models.py:61 launderette/models.py:77
#: launderette/models.py:44 launderette/models.py:67 launderette/models.py:88
msgid "type"
msgstr "type"
#: launderette/models.py:38 launderette/models.py:61 launderette/models.py:77
#: launderette/models.py:44 launderette/models.py:67 launderette/models.py:88
#: launderette/templates/launderette/launderette_book.jinja:26
msgid "Washing"
msgstr "Lavage"
#: launderette/models.py:38 launderette/models.py:61 launderette/models.py:77
#: launderette/models.py:44 launderette/models.py:67 launderette/models.py:88
#: launderette/templates/launderette/launderette_book.jinja:30
msgid "Drying"
msgstr "Séchage"
#: launderette/models.py:39
#: launderette/models.py:45
msgid "is working"
msgstr "fonctionne"
#: launderette/models.py:42
#: launderette/models.py:48
msgid "Machine"
msgstr "Machine"
#: launderette/models.py:65
#: launderette/models.py:68
msgid "borrow date"
msgstr "date d'emprunt"
#: launderette/models.py:72
msgid "Token"
msgstr "Jeton"
#: launderette/models.py:78
#: launderette/models.py:89
msgid "machine"
msgstr "machine"
#: launderette/models.py:79
#: launderette/models.py:90
msgid "token"
msgstr "jeton"
#: launderette/models.py:83
#: launderette/models.py:94
msgid "Slot"
msgstr "Créneau"
@ -1309,11 +1300,19 @@ msgstr "Lavage et séchage"
msgid "Launderette admin"
msgstr "Gestion de la laverie"
#: launderette/templates/launderette/launderette_detail.jinja:8
#: launderette/templates/launderette/launderette_detail.jinja:9
msgid "Sell"
msgstr "Vendre"
#: launderette/templates/launderette/launderette_detail.jinja:10
msgid "Tokens"
msgstr "Jetons"
#: launderette/templates/launderette/launderette_detail.jinja:17
msgid "Machines"
msgstr "Machines"
#: launderette/templates/launderette/launderette_detail.jinja:9
#: launderette/templates/launderette/launderette_detail.jinja:18
msgid "New machine"
msgstr "Nouvelle machine"
@ -1338,75 +1337,83 @@ msgstr "Éditer la page de présentation"
msgid "Book launderette slot"
msgstr "Réserver un créneau de laverie"
#: sith/settings.py:237 sith/settings.py:244 sith/settings.py:256
#: launderette/views.py:156
msgid "User has booked no slot"
msgstr "L'utilisateur n'a pas réservé de créneau"
#: launderette/views.py:246
msgid "Token not found"
msgstr "Jeton non trouvé"
#: sith/settings.py:244 sith/settings.py:251 sith/settings.py:263
#: sith/settings_sample.py:240 sith/settings_sample.py:247
#: sith/settings_sample.py:259
msgid "Check"
msgstr "Chèque"
#: sith/settings.py:238 sith/settings.py:245 sith/settings.py:257
#: sith/settings.py:245 sith/settings.py:252 sith/settings.py:264
#: sith/settings_sample.py:241 sith/settings_sample.py:248
#: sith/settings_sample.py:260
msgid "Cash"
msgstr "Espèces"
#: sith/settings.py:239 sith/settings_sample.py:242
#: sith/settings.py:246 sith/settings_sample.py:242
msgid "Transfert"
msgstr "Virement"
#: sith/settings.py:246 sith/settings_sample.py:249
#: sith/settings.py:253 sith/settings_sample.py:249
msgid "Other"
msgstr "Autre"
#: sith/settings.py:270 sith/settings_sample.py:273
#: sith/settings.py:277 sith/settings_sample.py:273
msgid "One semester"
msgstr "Un semestre"
#: sith/settings.py:275 sith/settings_sample.py:278
#: sith/settings.py:282 sith/settings_sample.py:278
msgid "Two semesters"
msgstr "Deux semestres"
#: sith/settings.py:280 sith/settings_sample.py:283
#: sith/settings.py:287 sith/settings_sample.py:283
msgid "Common core cursus"
msgstr "Cursus tronc commun"
#: sith/settings.py:285 sith/settings_sample.py:288
#: sith/settings.py:292 sith/settings_sample.py:288
msgid "Branch cursus"
msgstr "Cursus branche"
#: sith/settings.py:293 sith/settings_sample.py:296
#: sith/settings.py:300 sith/settings_sample.py:296
msgid "President"
msgstr "Président"
#: sith/settings.py:294 sith/settings_sample.py:297
#: sith/settings.py:301 sith/settings_sample.py:297
msgid "Vice-President"
msgstr "Vice-Président"
#: sith/settings.py:295 sith/settings_sample.py:298
#: sith/settings.py:302 sith/settings_sample.py:298
msgid "Treasurer"
msgstr "Trésorier"
#: sith/settings.py:296 sith/settings_sample.py:299
#: sith/settings.py:303 sith/settings_sample.py:299
msgid "Communication supervisor"
msgstr "Responsable com"
#: sith/settings.py:297 sith/settings_sample.py:300
#: sith/settings.py:304 sith/settings_sample.py:300
msgid "Secretary"
msgstr "Secrétaire"
#: sith/settings.py:298 sith/settings_sample.py:301
#: sith/settings.py:305 sith/settings_sample.py:301
msgid "IT supervisor"
msgstr "Responsable info"
#: sith/settings.py:299 sith/settings_sample.py:302
#: sith/settings.py:306 sith/settings_sample.py:302
msgid "Board member"
msgstr "Membre du bureau"
#: sith/settings.py:300 sith/settings_sample.py:303
#: sith/settings.py:307 sith/settings_sample.py:303
msgid "Active member"
msgstr "Membre actif"
#: sith/settings.py:301 sith/settings_sample.py:304
#: sith/settings.py:308 sith/settings_sample.py:304
msgid "Curious"
msgstr "Curieux"
@ -1440,5 +1447,7 @@ msgstr "Un utilisateur avec cette adresse email existe déjà"
#: subscription/views.py:56
msgid "You must either choose an existing user or create a new one properly"
msgstr ""
"Vous devez soit choisir un utilisateur existant, ou en créer un proprement."
msgstr "Vous devez soit choisir un utilisateur existant, ou en créer un proprement."
#~ msgid "Product"
#~ msgstr "Produit"