diff --git a/core/management/commands/populate.py b/core/management/commands/populate.py index 241832a3..c34ed2ce 100644 --- a/core/management/commands/populate.py +++ b/core/management/commands/populate.py @@ -39,7 +39,7 @@ from accounting.models import GeneralJournal, BankAccount, ClubAccount, Operatio from core.utils import resize_image from club.models import Club, Membership from subscription.models import Subscription -from counter.models import Customer, ProductType, Product, Counter +from counter.models import Customer, ProductType, Product, Counter, Selling from com.models import Sith, Weekmail from election.models import Election, Role, Candidature, ElectionList from forum.models import Forum, ForumTopic @@ -340,6 +340,8 @@ Welcome to the wiki page! c.save() r = ProductType(name="Rechargements") r.save() + verre = ProductType(name="Verre") + verre.save() cotis = Product(name="Cotis 1 semestre", code="1SCOTIZ", product_type=c, purchase_price="15", selling_price="15", special_selling_price="15", club=main_club) cotis.save() @@ -355,6 +357,14 @@ Welcome to the wiki page! cble = Product(name="Chimay Bleue", code="CBLE", product_type=p, purchase_price="1.50", selling_price="1.7", special_selling_price="1.6", club=main_club) cble.save() + cons = Product(name="Consigne Eco-cup", code="CONS", product_type=verre, purchase_price="1", selling_price="1", + special_selling_price="1", club=main_club) + cons.id = 1152 + cons.save() + dcons = Product(name="Déconsigne Eco-cup", code="DECO", product_type=verre, purchase_price="-1", selling_price="-1", + special_selling_price="-1", club=main_club) + dcons.id = 1151 + dcons.save() Product(name="Corsendonk", code="CORS", product_type=p, purchase_price="1.50", selling_price="1.7", special_selling_price="1.6", club=main_club).save() Product(name="Carolus", code="CARO", product_type=p, purchase_price="1.50", selling_price="1.7", @@ -362,6 +372,8 @@ Welcome to the wiki page! mde = Counter.objects.filter(name="MDE").first() mde.products.add(barb) mde.products.add(cble) + mde.products.add(cons) + mde.products.add(dcons) mde.sellers.add(skia) mde.save() @@ -473,6 +485,9 @@ Welcome to the wiki page! start=s.subscription_start) s.save() + Selling(label=dcons.name, product=dcons, counter=mde, unit_price=dcons.selling_price, club=main_club, + quantity=settings.SITH_ECOCUP_LIMIT + 3, seller=skia, customer=krophil.customer).save() + # Add barman to counter c = Counter.objects.get(id=2) c.sellers.add(User.objects.get(pk=krophil.pk)) diff --git a/core/templates/core/user_account.jinja b/core/templates/core/user_account.jinja index fd0ba54a..6349fe15 100644 --- a/core/templates/core/user_account.jinja +++ b/core/templates/core/user_account.jinja @@ -37,14 +37,18 @@

{% trans %}User account{% endtrans %}

{% trans %}Amount: {% endtrans %}{{ customer.amount }} €

-{% if customer.refillings.exists() %} - {% if customer.buyings.exists() %} +{% set bought = customer.buyings.exists() %} +{% set refilled = customer.refillings.exists() %} +{% if bought or refilled %} + {% if bought %}
{% trans %}Account buyings{% endtrans %}
{{ monthly(buyings_month) }} {% endif %} + {% if refilled %}
{% trans %}Refillings{% endtrans %}
{{ monthly(refilling_month) }} {% endif %} +{% endif %} {% if customer.user.invoices.exists() %}
{% trans %}Eboutic invoices{% endtrans %}
{{ monthly(invoices_month) }} diff --git a/counter/migrations/0013_customer_recorded_products.py b/counter/migrations/0013_customer_recorded_products.py new file mode 100644 index 00000000..026b7b33 --- /dev/null +++ b/counter/migrations/0013_customer_recorded_products.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.utils.translation import ugettext_lazy as _ +from django.db import migrations, models +from django.conf import settings + +from core.models import User +from counter.models import Customer, Product, Selling, Counter + + +def balance_ecocups(apps, schema_editor): + for customer in Customer.objects.all(): + customer.recorded_products = 0 + for selling in customer.buyings.filter(product__id__in=[settings.SITH_ECOCUP_CONS, settings.SITH_ECOCUP_DECO]).all(): + if selling.product.is_record_product: + customer.recorded_products += selling.quantity + elif selling.product.is_unrecord_product: + customer.recorded_products -= selling.quantity + if customer.recorded_products < -settings.SITH_ECOCUP_LIMIT: + qt = -(customer.recorded_products + settings.SITH_ECOCUP_LIMIT) + cons = Product.objects.get(id=settings.SITH_ECOCUP_CONS) + Selling(label=_("Ecocup regularization"), product=cons, unit_price=cons.selling_price, + club=cons.club, counter=Counter.objects.filter(name='Foyer').first(), + quantity=qt, seller=User.objects.get(id=0), customer=customer).save(allow_negative=True) + customer.recorded_products += qt + customer.save() + + +class Migration(migrations.Migration): + + dependencies = [ + ('counter', '0012_auto_20170515_2202'), + ] + + operations = [ + migrations.AddField( + model_name='customer', + name='recorded_products', + field=models.IntegerField(verbose_name='recorded items', default=0), + ), + migrations.RunPython(balance_ecocups), + ] diff --git a/counter/models.py b/counter/models.py index d85813ba..074f761e 100644 --- a/counter/models.py +++ b/counter/models.py @@ -51,6 +51,7 @@ class Customer(models.Model): user = models.OneToOneField(User, primary_key=True) account_id = models.CharField(_('account id'), max_length=10, unique=True) amount = CurrencyField(_('amount')) + recorded_products = models.IntegerField(_('recorded product'), default=0) class Meta: verbose_name = _('customer') @@ -60,6 +61,13 @@ class Customer(models.Model): def __str__(self): return "%s - %s" % (self.user.username, self.account_id) + @property + def can_record(self): + return self.recorded_products > -settings.SITH_ECOCUP_LIMIT + + def can_record_more(self, number): + return self.recorded_products - number >= -settings.SITH_ECOCUP_LIMIT + @property def can_buy(self): return (self.user.subscriptions.last() and @@ -72,8 +80,13 @@ class Customer(models.Model): letter = random.choice(string.ascii_lowercase) return number + letter - def save(self, *args, **kwargs): - if self.amount < 0: + def save(self, allow_negative=False, is_selling=False, *args, **kwargs): + """ + is_selling : tell if the current action is a selling + allow_negative : ignored if not a selling. Allow a selling to put the account in negative + Those two parameters avoid blocking the save method of a customer if his account is negative + """ + if self.amount < 0 and (is_selling and not allow_negative): raise ValidationError(_("Not enough money")) super(Customer, self).save(*args, **kwargs) @@ -143,6 +156,14 @@ class Product(models.Model): class Meta: verbose_name = _('product') + @property + def is_record_product(self): + return settings.SITH_ECOCUP_CONS == self.id + + @property + def is_unrecord_product(self): + return settings.SITH_ECOCUP_DECO == self.id + def is_owned_by(self, user): """ Method to see if that object can be edited by the given user @@ -376,13 +397,16 @@ class Selling(models.Model): html_message=message_html ) - def save(self, *args, **kwargs): + def save(self, allow_negative=False, *args, **kwargs): + """ + allow_negative : Allow this selling to use more money than available for this user + """ if not self.date: self.date = timezone.now() self.full_clean() if not self.is_validated: self.customer.amount -= self.quantity * self.unit_price - self.customer.save() + self.customer.save(allow_negative=allow_negative, is_selling=True) self.is_validated = True u = User.objects.filter(id=self.customer.user.id).first() if u.was_subscribed: diff --git a/counter/views.py b/counter/views.py index 863a703d..9d4963f8 100644 --- a/counter/views.py +++ b/counter/views.py @@ -330,6 +330,28 @@ class CounterClick(CounterTabsMixin, CanViewMixin, DetailView): except: return 0 + def compute_record_product(self, request, product=None): + recorded = 0 + basket = request.session['basket'] + + if product: + if product.is_record_product: + recorded -= 1 + elif product.is_unrecord_product: + recorded += 1 + + for p in basket: + bproduct = self.get_product(str(p)) + if bproduct.is_record_product: + recorded -= basket[p]['qty'] + elif bproduct.is_unrecord_product: + recorded += basket[p]['qty'] + return recorded + + def is_record_product_ok(self, request, product): + return self.customer.can_record_more( + self.compute_record_product(request, product)) + def add_product(self, request, q=1, p=None): """ Add a product to the basket @@ -359,6 +381,9 @@ class CounterClick(CounterTabsMixin, CanViewMixin, DetailView): if self.customer.amount < (total + round(q * float(price), 2)): # Check for enough money request.session['not_enough'] = True return False + if product.is_unrecord_product and not self.is_record_product_ok(request, product): + request.session['not_allowed'] = True + return False if product.limit_age >= 18 and not self.customer.user.date_of_birth: request.session['no_age'] = True return False @@ -421,6 +446,9 @@ class CounterClick(CounterTabsMixin, CanViewMixin, DetailView): """ Finish the click session, and validate the basket """ with transaction.atomic(): request.session['last_basket'] = [] + if self.sum_basket(request) > self.customer.amount: + raise DataError(_("You have not enough money to buy all the basket")) + for pid, infos in request.session['basket'].items(): # This duplicates code for DB optimization (prevent to load many times the same object) p = Product.objects.filter(pk=pid).first() @@ -428,8 +456,6 @@ class CounterClick(CounterTabsMixin, CanViewMixin, DetailView): uprice = p.special_selling_price else: uprice = p.selling_price - 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'] + infos['bonus_qty'], p.name)) s = Selling(label=p.name, product=p, club=p.club, counter=self.object, unit_price=uprice, quantity=infos['qty'], seller=self.operator, customer=self.customer) @@ -438,6 +464,8 @@ class CounterClick(CounterTabsMixin, CanViewMixin, DetailView): s = Selling(label=p.name + " (Plateau)", product=p, club=p.club, counter=self.object, unit_price=0, quantity=infos['bonus_qty'], seller=self.operator, customer=self.customer) s.save() + self.customer.recorded_products -= self.compute_record_product(request) + self.customer.save() request.session['last_customer'] = self.customer.user.get_display_name() request.session['last_total'] = "%0.2f" % self.sum_basket(request) request.session['new_customer_amount'] = str(self.customer.amount) diff --git a/locale/fr/LC_MESSAGES/django.po b/locale/fr/LC_MESSAGES/django.po index 28dbaa7b..60bf7060 100644 --- a/locale/fr/LC_MESSAGES/django.po +++ b/locale/fr/LC_MESSAGES/django.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-08-01 13:50+0200\n" +"POT-Creation-Date: 2017-08-15 02:08+0200\n" "PO-Revision-Date: 2016-07-18\n" "Last-Translator: Skia \n" "Language-Team: AE info \n" @@ -18,8 +18,8 @@ msgstr "" #: accounting/models.py:61 accounting/models.py:110 accounting/models.py:138 #: accounting/models.py:197 club/models.py:44 -#: core/templates/core/base.jinja:234 counter/models.py:100 -#: counter/models.py:126 counter/models.py:162 forum/models.py:49 +#: core/templates/core/base.jinja:233 counter/models.py:108 +#: counter/models.py:134 counter/models.py:178 forum/models.py:49 #: launderette/models.py:38 launderette/models.py:84 launderette/models.py:110 #: stock/models.py:38 stock/models.py:54 stock/models.py:77 stock/models.py:97 msgid "name" @@ -66,8 +66,8 @@ msgid "account number" msgstr "numero de compte" #: accounting/models.py:113 accounting/models.py:139 club/models.py:187 -#: com/models.py:65 com/models.py:156 counter/models.py:135 -#: counter/models.py:163 trombi/models.py:149 +#: com/models.py:65 com/models.py:156 counter/models.py:143 +#: counter/models.py:179 trombi/models.py:149 msgid "club" msgstr "club" @@ -88,12 +88,12 @@ msgstr "Compte club" msgid "%(club_account)s on %(bank_account)s" msgstr "%(club_account)s sur %(bank_account)s" -#: accounting/models.py:195 club/models.py:188 counter/models.py:439 +#: accounting/models.py:195 club/models.py:188 counter/models.py:455 #: election/models.py:16 launderette/models.py:148 msgid "start date" msgstr "date de début" -#: accounting/models.py:196 club/models.py:189 counter/models.py:440 +#: accounting/models.py:196 club/models.py:189 counter/models.py:456 #: election/models.py:17 msgid "end date" msgstr "date de fin" @@ -107,7 +107,7 @@ msgid "club account" msgstr "compte club" #: accounting/models.py:200 accounting/models.py:257 counter/models.py:53 -#: counter/models.py:276 +#: counter/models.py:292 msgid "amount" msgstr "montant" @@ -128,17 +128,17 @@ msgid "journal" msgstr "classeur" #: accounting/models.py:258 core/models.py:628 core/models.py:1003 -#: core/models.py:1044 counter/models.py:279 counter/models.py:328 -#: counter/models.py:457 eboutic/models.py:39 eboutic/models.py:73 +#: core/models.py:1044 counter/models.py:295 counter/models.py:344 +#: counter/models.py:473 eboutic/models.py:39 eboutic/models.py:73 #: forum/models.py:239 forum/models.py:314 stock/models.py:76 msgid "date" msgstr "date" -#: accounting/models.py:259 counter/models.py:458 stock/models.py:79 +#: accounting/models.py:259 counter/models.py:474 stock/models.py:79 msgid "comment" msgstr "commentaire" -#: accounting/models.py:260 counter/models.py:280 counter/models.py:329 +#: accounting/models.py:260 counter/models.py:296 counter/models.py:345 #: subscription/models.py:55 msgid "payment method" msgstr "méthode de paiement" @@ -164,7 +164,7 @@ msgid "accounting type" msgstr "type comptable" #: accounting/models.py:269 accounting/models.py:371 accounting/models.py:398 -#: accounting/models.py:422 counter/models.py:320 +#: accounting/models.py:422 counter/models.py:336 msgid "label" msgstr "étiquette" @@ -253,7 +253,7 @@ msgstr "" "Vous devez fournir soit un type comptable simplifié ou un type comptable " "standard" -#: accounting/models.py:366 counter/models.py:130 +#: accounting/models.py:366 counter/models.py:138 msgid "code" msgstr "code" @@ -347,12 +347,11 @@ msgstr "Compte en banque : " #: election/templates/election/election_detail.jinja:280 #: election/templates/election/election_detail.jinja:330 #: election/templates/election/election_detail.jinja:378 -#: forum/templates/forum/macros.jinja:21 -#: forum/templates/forum/macros.jinja:123 +#: forum/templates/forum/macros.jinja:21 forum/templates/forum/macros.jinja:123 #: launderette/templates/launderette/launderette_admin.jinja:16 #: launderette/views.py:182 sas/templates/sas/album.jinja:26 #: sas/templates/sas/moderation.jinja:18 sas/templates/sas/picture.jinja:74 -#: sas/templates/sas/picture.jinja:124 +#: sas/templates/sas/picture.jinja.py:124 #: stock/templates/stock/stock_shopping_list.jinja:43 #: stock/templates/stock/stock_shopping_list.jinja:69 #: trombi/templates/trombi/detail.jinja:35 @@ -505,8 +504,8 @@ msgstr "Non" #: accounting/templates/accounting/club_account_details.jinja:56 #: com/templates/com/news_admin_list.jinja:38 -#: com/templates/com/news_admin_list.jinja:71 -#: core/templates/core/file.jinja:36 core/templates/core/page.jinja:28 +#: com/templates/com/news_admin_list.jinja:71 core/templates/core/file.jinja:36 +#: core/templates/core/page.jinja:28 msgid "View" msgstr "Voir" @@ -604,7 +603,7 @@ msgid "Done" msgstr "Effectuées" #: accounting/templates/accounting/journal_details.jinja:39 -#: counter/templates/counter/cash_summary_list.jinja:37 counter/views.py:827 +#: counter/templates/counter/cash_summary_list.jinja:37 counter/views.py:855 #: trombi/templates/trombi/comment.jinja:4 #: trombi/templates/trombi/comment.jinja:8 #: trombi/templates/trombi/user_tools.jinja:50 @@ -855,7 +854,7 @@ msgstr "Vous ne pouvez pas faire de boucles dans les clubs" msgid "A club with that unix_name already exists" msgstr "Un club avec ce nom UNIX existe déjà." -#: club/models.py:186 counter/models.py:437 counter/models.py:455 +#: club/models.py:186 counter/models.py:453 counter/models.py:471 #: eboutic/models.py:38 eboutic/models.py:72 election/models.py:140 #: launderette/models.py:114 launderette/models.py:152 sas/models.py:158 #: trombi/models.py:148 @@ -867,8 +866,8 @@ msgstr "nom d'utilisateur" msgid "role" msgstr "rôle" -#: club/models.py:192 core/models.py:64 counter/models.py:101 -#: counter/models.py:127 election/models.py:13 election/models.py:93 +#: club/models.py:192 core/models.py:64 counter/models.py:109 +#: counter/models.py:135 election/models.py:13 election/models.py:93 #: election/models.py:141 forum/models.py:50 forum/models.py:186 msgid "description" msgstr "description" @@ -885,8 +884,7 @@ msgstr "L'utilisateur est déjà membre de ce club" msgid "past member" msgstr "Anciens membres" -#: club/templates/club/club_list.jinja:4 -#: club/templates/club/club_list.jinja:24 +#: club/templates/club/club_list.jinja:4 club/templates/club/club_list.jinja:24 msgid "Club list" msgstr "Liste des clubs" @@ -951,14 +949,13 @@ msgstr "Du" msgid "To" msgstr "Au" -#: club/templates/club/club_sellings.jinja:5 club/views.py:78 -#: club/views.py:251 counter/templates/counter/counter_main.jinja:19 +#: club/templates/club/club_sellings.jinja:5 club/views.py:78 club/views.py:251 +#: counter/templates/counter/counter_main.jinja:19 #: counter/templates/counter/last_ops.jinja:35 msgid "Sellings" msgstr "Ventes" -#: club/templates/club/club_sellings.jinja:9 -#: club/templates/club/stats.jinja:19 +#: club/templates/club/club_sellings.jinja:9 club/templates/club/stats.jinja:19 #: counter/templates/counter/cash_summary_list.jinja:15 msgid "Show" msgstr "Montrer" @@ -1076,7 +1073,7 @@ msgstr "Membres" msgid "Old members" msgstr "Anciens membres" -#: club/views.py:68 core/templates/core/base.jinja:65 core/views/user.py:180 +#: club/views.py:68 core/templates/core/base.jinja:64 core/views/user.py:180 #: sas/templates/sas/picture.jinja:95 trombi/views.py:55 msgid "Tools" msgstr "Outils" @@ -1096,17 +1093,17 @@ msgstr "Choisir un utilisateur" msgid "You do not have the permission to do that" msgstr "Vous n'avez pas la permission de faire cela" -#: club/views.py:197 counter/views.py:1069 +#: club/views.py:197 counter/views.py:1097 msgid "Begin date" msgstr "Date de début" -#: club/views.py:198 com/views.py:130 counter/views.py:1070 +#: club/views.py:198 com/views.py:130 counter/views.py:1098 #: election/views.py:135 subscription/views.py:47 msgid "End date" msgstr "Date de fin" #: club/views.py:213 core/templates/core/user_stats.jinja:27 -#: counter/views.py:1160 +#: counter/views.py:1188 msgid "Product" msgstr "Produit" @@ -1219,9 +1216,8 @@ msgid "News admin" msgstr "Administration des nouvelles" #: com/templates/com/news_admin_list.jinja:9 -#: com/templates/com/news_detail.jinja:5 -#: com/templates/com/news_detail.jinja:11 com/templates/com/news_list.jinja:4 -#: com/templates/com/news_list.jinja:28 +#: com/templates/com/news_detail.jinja:5 com/templates/com/news_detail.jinja:11 +#: com/templates/com/news_list.jinja:4 com/templates/com/news_list.jinja:28 msgid "News" msgstr "Nouvelles" @@ -1239,7 +1235,7 @@ msgstr "Type" #: com/templates/com/news_admin_list.jinja:15 #: com/templates/com/news_admin_list.jinja:50 #: com/templates/com/weekmail.jinja:19 com/templates/com/weekmail.jinja:48 -#: core/templates/core/base.jinja:244 forum/templates/forum/forum.jinja:29 +#: core/templates/core/base.jinja:243 forum/templates/forum/forum.jinja:29 #: forum/templates/forum/forum.jinja:48 forum/templates/forum/main.jinja:25 #: forum/views.py:159 msgid "Title" @@ -1611,7 +1607,7 @@ msgstr "-" msgid "XS" msgstr "XS" -#: core/models.py:171 core/templates/core/base.jinja:257 +#: core/models.py:171 core/templates/core/base.jinja:256 msgid "S" msgstr "S" @@ -1892,136 +1888,131 @@ msgstr "404. Non trouvé" msgid "Welcome!" msgstr "Bienvenue!" -#: core/templates/core/base.jinja:20 -msgid "Logo" -msgstr "Logo" - -#: core/templates/core/base.jinja:34 core/templates/core/login.jinja:4 +#: core/templates/core/base.jinja:33 core/templates/core/login.jinja:4 #: core/templates/core/password_reset_complete.jinja:5 msgid "Login" msgstr "Connexion" -#: core/templates/core/base.jinja:35 core/templates/core/register.jinja:18 +#: core/templates/core/base.jinja:34 core/templates/core/register.jinja:18 msgid "Register" msgstr "S'enregister" -#: core/templates/core/base.jinja:62 +#: core/templates/core/base.jinja:61 msgid "View more" msgstr "Voir plus" -#: core/templates/core/base.jinja:63 -#: forum/templates/forum/last_unread.jinja:16 +#: core/templates/core/base.jinja:62 forum/templates/forum/last_unread.jinja:16 msgid "Mark all as read" msgstr "Marquer tout commme lu" -#: core/templates/core/base.jinja:66 +#: core/templates/core/base.jinja:65 msgid "Logout" msgstr "Déconnexion" -#: core/templates/core/base.jinja:68 core/templates/core/base.jinja.py:69 +#: core/templates/core/base.jinja:67 core/templates/core/base.jinja.py:68 msgid "Search" msgstr "Recherche" -#: core/templates/core/base.jinja:91 +#: core/templates/core/base.jinja:90 msgid "Main" msgstr "Accueil" -#: core/templates/core/base.jinja:92 +#: core/templates/core/base.jinja:91 msgid "Matmatronch" msgstr "Matmatronch" -#: core/templates/core/base.jinja:93 +#: core/templates/core/base.jinja:92 msgid "Wiki" msgstr "Wiki" -#: core/templates/core/base.jinja:94 sas/templates/sas/album.jinja:4 +#: core/templates/core/base.jinja:93 sas/templates/sas/album.jinja:4 #: sas/templates/sas/main.jinja:4 sas/templates/sas/main.jinja.py:32 #: sas/templates/sas/picture.jinja:34 msgid "SAS" msgstr "SAS" -#: core/templates/core/base.jinja:95 forum/templates/forum/forum.jinja:10 +#: core/templates/core/base.jinja:94 forum/templates/forum/forum.jinja:10 #: forum/templates/forum/last_unread.jinja:13 -#: forum/templates/forum/main.jinja:6 forum/templates/forum/main.jinja:11 +#: forum/templates/forum/main.jinja:6 forum/templates/forum/main.jinja.py:11 #: forum/templates/forum/main.jinja:14 forum/templates/forum/reply.jinja:15 #: forum/templates/forum/topic.jinja:30 msgid "Forum" msgstr "Forum" -#: core/templates/core/base.jinja:96 +#: core/templates/core/base.jinja:95 msgid "Services" msgstr "Services" -#: core/templates/core/base.jinja:97 core/templates/core/file.jinja:20 +#: core/templates/core/base.jinja:96 core/templates/core/file.jinja:20 #: core/views/files.py:75 msgid "Files" msgstr "Fichiers" -#: core/templates/core/base.jinja:98 +#: core/templates/core/base.jinja:97 msgid "Sponsors" msgstr "Partenaires" -#: core/templates/core/base.jinja:99 +#: core/templates/core/base.jinja:98 msgid "Help" msgstr "Aide" -#: core/templates/core/base.jinja:138 +#: core/templates/core/base.jinja:137 msgid "Contacts" msgstr "Contacts" -#: core/templates/core/base.jinja:139 +#: core/templates/core/base.jinja:138 msgid "Legal notices" msgstr "Mentions légales" -#: core/templates/core/base.jinja:140 +#: core/templates/core/base.jinja:139 msgid "Intellectual property" msgstr "Propriété intellectuelle" -#: core/templates/core/base.jinja:141 +#: core/templates/core/base.jinja:140 msgid "Help & Documentation" msgstr "Aide & Documentation" -#: core/templates/core/base.jinja:142 +#: core/templates/core/base.jinja:141 msgid "R&D" msgstr "R&D" -#: core/templates/core/base.jinja:144 +#: core/templates/core/base.jinja:143 msgid "Site made by good people" msgstr "Site réalisé par des gens bons" -#: core/templates/core/base.jinja:241 +#: core/templates/core/base.jinja:240 msgid "https://path/to/image.gif" msgstr "https://chemin/vers/image.gif" -#: core/templates/core/base.jinja:243 +#: core/templates/core/base.jinja:242 msgid "alternative text" msgstr "texte alternatif" -#: core/templates/core/base.jinja:253 +#: core/templates/core/base.jinja:252 msgid "Image" msgstr "Image" -#: core/templates/core/base.jinja:254 +#: core/templates/core/base.jinja:253 msgid "Link" msgstr "Lien" -#: core/templates/core/base.jinja:255 +#: core/templates/core/base.jinja:254 msgid "sup" msgstr "exp" -#: core/templates/core/base.jinja:256 +#: core/templates/core/base.jinja:255 msgid "sub" msgstr "ind" -#: core/templates/core/base.jinja:258 +#: core/templates/core/base.jinja:257 msgid "U" msgstr "S" -#: core/templates/core/base.jinja:259 +#: core/templates/core/base.jinja:258 msgid "I" msgstr "I" -#: core/templates/core/base.jinja:260 +#: core/templates/core/base.jinja:259 msgid "B" msgstr "G" @@ -2192,13 +2183,11 @@ msgstr "login" msgid "Lost password?" msgstr "Mot de passe perdu ?" -#: core/templates/core/macros.jinja:31 -#: core/templates/core/user_detail.jinja:27 +#: core/templates/core/macros.jinja:31 core/templates/core/user_detail.jinja:27 msgid "Born: " msgstr "Né le : " -#: core/templates/core/macros.jinja:35 -#: core/templates/core/user_detail.jinja:48 +#: core/templates/core/macros.jinja:35 core/templates/core/user_detail.jinja:48 msgid "Promo: " msgstr "Promo : " @@ -2471,29 +2460,29 @@ msgstr "Compte de %(user_name)s" msgid "User account" msgstr "Compte utilisateur" -#: core/templates/core/user_account.jinja:42 +#: core/templates/core/user_account.jinja:44 #: core/templates/core/user_account_detail.jinja:13 msgid "Account buyings" msgstr "Achat sur compte utilisateur" -#: core/templates/core/user_account.jinja:45 +#: core/templates/core/user_account.jinja:48 #: core/templates/core/user_account_detail.jinja:46 #: counter/templates/counter/cash_summary_list.jinja:17 #: counter/templates/counter/last_ops.jinja:10 msgid "Refillings" msgstr "Rechargements" -#: core/templates/core/user_account.jinja:49 +#: core/templates/core/user_account.jinja:53 #: core/templates/core/user_account_detail.jinja:74 msgid "Eboutic invoices" msgstr "Facture eboutic" -#: core/templates/core/user_account.jinja:53 -#: core/templates/core/user_tools.jinja:36 counter/views.py:573 +#: core/templates/core/user_account.jinja:57 +#: core/templates/core/user_tools.jinja:36 counter/views.py:601 msgid "Etickets" msgstr "Etickets" -#: core/templates/core/user_account.jinja:64 +#: core/templates/core/user_account.jinja:68 #: core/templates/core/user_account_detail.jinja:102 msgid "User has no account" msgstr "L'utilisateur n'a pas de compte" @@ -2683,8 +2672,8 @@ msgstr "Cotisations" msgid "Subscription stats" msgstr "Statistiques de cotisation" -#: core/templates/core/user_tools.jinja:27 counter/views.py:543 -#: counter/views.py:709 +#: core/templates/core/user_tools.jinja:27 counter/views.py:571 +#: counter/views.py:737 msgid "Counters" msgstr "Comptoirs" @@ -2705,12 +2694,12 @@ msgid "Product types management" msgstr "Gestion des types de produit" #: core/templates/core/user_tools.jinja:34 -#: counter/templates/counter/cash_summary_list.jinja:23 counter/views.py:563 +#: counter/templates/counter/cash_summary_list.jinja:23 counter/views.py:591 msgid "Cash register summaries" msgstr "Relevés de caisse" #: core/templates/core/user_tools.jinja:35 -#: counter/templates/counter/invoices_call.jinja:4 counter/views.py:568 +#: counter/templates/counter/invoices_call.jinja:4 counter/views.py:596 msgid "Invoices call" msgstr "Appels à facture" @@ -2873,88 +2862,96 @@ msgstr "Fillot" msgid "Pictures" msgstr "Photos" -#: core/views/user.py:373 +#: core/views/user.py:388 msgid "User already has a profile picture" msgstr "L'utilisateur a déjà une photo de profil" +#: counter/migrations/0013_customer_recorded_products.py:23 +msgid "Ecocup regularization" +msgstr "Régularization des ecocups" + #: counter/models.py:52 msgid "account id" msgstr "numéro de compte" -#: counter/models.py:56 +#: counter/models.py:54 +msgid "recorded product" +msgstr "produits consignés" + +#: counter/models.py:57 msgid "customer" msgstr "client" -#: counter/models.py:57 +#: counter/models.py:58 msgid "customers" msgstr "clients" -#: counter/models.py:77 counter/templates/counter/counter_click.jinja:48 +#: counter/models.py:85 counter/templates/counter/counter_click.jinja:48 #: counter/templates/counter/counter_click.jinja:82 msgid "Not enough money" msgstr "Solde insuffisant" -#: counter/models.py:105 counter/models.py:128 +#: counter/models.py:113 counter/models.py:136 msgid "product type" msgstr "type du produit" -#: counter/models.py:131 +#: counter/models.py:139 msgid "purchase price" msgstr "prix d'achat" -#: counter/models.py:132 +#: counter/models.py:140 msgid "selling price" msgstr "prix de vente" -#: counter/models.py:133 +#: counter/models.py:141 msgid "special selling price" msgstr "prix de vente spécial" -#: counter/models.py:134 +#: counter/models.py:142 msgid "icon" msgstr "icône" -#: counter/models.py:136 +#: counter/models.py:144 msgid "limit age" msgstr "âge limite" -#: counter/models.py:137 +#: counter/models.py:145 msgid "tray price" msgstr "prix plateau" -#: counter/models.py:138 +#: counter/models.py:146 msgid "parent product" msgstr "produit parent" -#: counter/models.py:140 +#: counter/models.py:148 msgid "buying groups" msgstr "groupe d'achat" -#: counter/models.py:141 election/models.py:36 +#: counter/models.py:149 election/models.py:36 msgid "archived" msgstr "archivé" -#: counter/models.py:144 counter/models.py:540 +#: counter/models.py:152 counter/models.py:556 msgid "product" msgstr "produit" -#: counter/models.py:164 +#: counter/models.py:180 msgid "products" msgstr "produits" -#: counter/models.py:165 +#: counter/models.py:181 msgid "counter type" msgstr "type de comptoir" -#: counter/models.py:167 +#: counter/models.py:183 msgid "Bar" msgstr "Bar" -#: counter/models.py:167 +#: counter/models.py:183 msgid "Office" msgstr "Bureau" -#: counter/models.py:167 counter/templates/counter/counter_list.jinja:11 +#: counter/models.py:183 counter/templates/counter/counter_list.jinja:11 #: eboutic/templates/eboutic/eboutic_main.jinja:4 #: eboutic/templates/eboutic/eboutic_main.jinja:24 #: eboutic/templates/eboutic/eboutic_makecommand.jinja:8 @@ -2963,62 +2960,62 @@ msgstr "Bureau" msgid "Eboutic" msgstr "Eboutic" -#: counter/models.py:168 +#: counter/models.py:184 msgid "sellers" msgstr "vendeurs" -#: counter/models.py:171 launderette/models.py:151 +#: counter/models.py:187 launderette/models.py:151 msgid "token" msgstr "jeton" -#: counter/models.py:174 counter/models.py:438 counter/models.py:456 +#: counter/models.py:190 counter/models.py:454 counter/models.py:472 #: launderette/models.py:39 stock/models.py:39 msgid "counter" msgstr "comptoir" -#: counter/models.py:282 +#: counter/models.py:298 msgid "bank" msgstr "banque" -#: counter/models.py:284 counter/models.py:331 +#: counter/models.py:300 counter/models.py:347 msgid "is validated" msgstr "est validé" -#: counter/models.py:287 +#: counter/models.py:303 msgid "refilling" msgstr "rechargement" -#: counter/models.py:324 eboutic/models.py:129 +#: counter/models.py:340 eboutic/models.py:129 msgid "unit price" msgstr "prix unitaire" -#: counter/models.py:325 counter/models.py:529 eboutic/models.py:130 +#: counter/models.py:341 counter/models.py:545 eboutic/models.py:130 msgid "quantity" msgstr "quantité" -#: counter/models.py:330 +#: counter/models.py:346 msgid "Sith account" msgstr "Compte utilisateur" -#: counter/models.py:330 sith/settings.py:357 sith/settings.py:362 +#: counter/models.py:346 sith/settings.py:357 sith/settings.py:362 #: sith/settings.py:384 msgid "Credit card" msgstr "Carte bancaire" -#: counter/models.py:334 +#: counter/models.py:350 msgid "selling" msgstr "vente" -#: counter/models.py:353 +#: counter/models.py:369 msgid "Unknown event" msgstr "Événement inconnu" -#: counter/models.py:354 +#: counter/models.py:370 #, python-format msgid "Eticket bought for the event %(event)s" msgstr "Eticket acheté pour l'événement %(event)s" -#: counter/models.py:356 counter/models.py:368 +#: counter/models.py:372 counter/models.py:384 #, python-format msgid "" "You bought an eticket for the event %(event)s.\n" @@ -3027,51 +3024,51 @@ msgstr "" "Vous avez acheté un Eticket pour l'événement %(event)s.\n" "Vous pouvez le télécharger sur cette page: %(url)s" -#: counter/models.py:441 +#: counter/models.py:457 msgid "last activity date" msgstr "dernière activité" -#: counter/models.py:444 +#: counter/models.py:460 msgid "permanency" msgstr "permanence" -#: counter/models.py:459 +#: counter/models.py:475 msgid "emptied" msgstr "coffre vidée" -#: counter/models.py:462 +#: counter/models.py:478 msgid "cash register summary" msgstr "relevé de caisse" -#: counter/models.py:527 +#: counter/models.py:543 msgid "cash summary" msgstr "relevé" -#: counter/models.py:528 +#: counter/models.py:544 msgid "value" msgstr "valeur" -#: counter/models.py:530 +#: counter/models.py:546 msgid "check" msgstr "chèque" -#: counter/models.py:533 +#: counter/models.py:549 msgid "cash register summary item" msgstr "élément de relevé de caisse" -#: counter/models.py:541 +#: counter/models.py:557 msgid "banner" msgstr "bannière" -#: counter/models.py:542 +#: counter/models.py:558 msgid "event date" msgstr "date de l'événement" -#: counter/models.py:543 +#: counter/models.py:559 msgid "event title" msgstr "titre de l'événement" -#: counter/models.py:544 +#: counter/models.py:560 msgid "secret" msgstr "secret" @@ -3123,7 +3120,7 @@ msgstr "Liste des relevés de caisse" msgid "Theoric sums" msgstr "Sommes théoriques" -#: counter/templates/counter/cash_summary_list.jinja:36 counter/views.py:828 +#: counter/templates/counter/cash_summary_list.jinja:36 counter/views.py:856 msgid "Emptied" msgstr "Coffre vidé" @@ -3359,97 +3356,97 @@ msgstr "L'utilisateur n'est pas barman." msgid "Bad location, someone is already logged in somewhere else" msgstr "Mauvais comptoir, quelqu'un est déjà connecté ailleurs" -#: counter/views.py:400 +#: counter/views.py:425 msgid "END" msgstr "FIN" -#: counter/views.py:402 +#: counter/views.py:427 msgid "CAN" msgstr "ANN" -#: counter/views.py:432 +#: counter/views.py:450 msgid "You have not enough money to buy all the basket" msgstr "Vous n'avez pas assez d'argent pour acheter le panier" -#: counter/views.py:533 +#: counter/views.py:561 msgid "Counter administration" msgstr "Administration des comptoirs" -#: counter/views.py:538 +#: counter/views.py:566 msgid "Stocks" msgstr "Stocks" -#: counter/views.py:548 +#: counter/views.py:576 msgid "Products" msgstr "Produits" -#: counter/views.py:553 +#: counter/views.py:581 msgid "Archived products" msgstr "Produits archivés" -#: counter/views.py:558 +#: counter/views.py:586 msgid "Product types" msgstr "Types de produit" -#: counter/views.py:706 +#: counter/views.py:734 msgid "Parent product" msgstr "Produit parent" -#: counter/views.py:707 +#: counter/views.py:735 msgid "Buying groups" msgstr "Groupes d'achat" -#: counter/views.py:807 +#: counter/views.py:835 msgid "10 cents" msgstr "10 centimes" -#: counter/views.py:808 +#: counter/views.py:836 msgid "20 cents" msgstr "20 centimes" -#: counter/views.py:809 +#: counter/views.py:837 msgid "50 cents" msgstr "50 centimes" -#: counter/views.py:810 +#: counter/views.py:838 msgid "1 euro" msgstr "1 €" -#: counter/views.py:811 +#: counter/views.py:839 msgid "2 euros" msgstr "2 €" -#: counter/views.py:812 +#: counter/views.py:840 msgid "5 euros" msgstr "5 €" -#: counter/views.py:813 +#: counter/views.py:841 msgid "10 euros" msgstr "10 €" -#: counter/views.py:814 +#: counter/views.py:842 msgid "20 euros" msgstr "20 €" -#: counter/views.py:815 +#: counter/views.py:843 msgid "50 euros" msgstr "50 €" -#: counter/views.py:816 +#: counter/views.py:844 msgid "100 euros" msgstr "100 €" -#: counter/views.py:817 counter/views.py:819 counter/views.py:821 -#: counter/views.py:823 counter/views.py:825 +#: counter/views.py:845 counter/views.py:847 counter/views.py:849 +#: counter/views.py:851 counter/views.py:853 msgid "Check amount" msgstr "Montant du chèque" -#: counter/views.py:818 counter/views.py:820 counter/views.py:822 -#: counter/views.py:824 counter/views.py:826 +#: counter/views.py:846 counter/views.py:848 counter/views.py:850 +#: counter/views.py:852 counter/views.py:854 msgid "Check quantity" msgstr "Nombre de chèque" -#: counter/views.py:1234 +#: counter/views.py:1262 msgid "people(s)" msgstr "personne(s)" @@ -3804,6 +3801,10 @@ msgstr "Appliquer les droits et le club propriétaire récursivement" msgid "%(author)s said" msgstr "Citation de %(author)s" +#: fuck.py:32 +msgid "Record regularization" +msgstr "Régularization des consignes" + #: launderette/models.py:42 #: launderette/templates/launderette/launderette_book.jinja:5 #: launderette/templates/launderette/launderette_book_choose.jinja:4 @@ -3860,12 +3861,12 @@ msgid "Washing and drying" msgstr "Lavage et séchage" #: launderette/templates/launderette/launderette_book.jinja:27 -#: sith/settings.py:526 +#: sith/settings.py:532 msgid "Washing" msgstr "Lavage" #: launderette/templates/launderette/launderette_book.jinja:31 -#: sith/settings.py:526 +#: sith/settings.py:532 msgid "Drying" msgstr "Séchage" @@ -4091,133 +4092,133 @@ msgstr "Sevenans" msgid "Montbéliard" msgstr "Montbéliard" -#: sith/settings.py:419 +#: sith/settings.py:425 msgid "One semester" msgstr "Un semestre, 15 €" -#: sith/settings.py:424 +#: sith/settings.py:430 msgid "Two semesters" msgstr "Deux semestres, 28 €" -#: sith/settings.py:429 +#: sith/settings.py:435 msgid "Common core cursus" msgstr "Cursus tronc commun, 45 €" -#: sith/settings.py:434 +#: sith/settings.py:440 msgid "Branch cursus" msgstr "Cursus branche, 45 €" -#: sith/settings.py:439 +#: sith/settings.py:445 msgid "Alternating cursus" msgstr "Cursus alternant, 30 €" -#: sith/settings.py:444 +#: sith/settings.py:450 msgid "Honorary member" msgstr "Membre honoraire, 0 €" -#: sith/settings.py:449 +#: sith/settings.py:455 msgid "Assidu member" msgstr "Membre d'Assidu, 0 €" -#: sith/settings.py:454 +#: sith/settings.py:460 msgid "Amicale/DOCEO member" msgstr "Membre de l'Amicale/DOCEO, 0 €" -#: sith/settings.py:459 +#: sith/settings.py:465 msgid "UT network member" msgstr "Cotisant du réseau UT, 0 €" -#: sith/settings.py:464 +#: sith/settings.py:470 msgid "CROUS member" msgstr "Membres du CROUS, 0 €" -#: sith/settings.py:469 +#: sith/settings.py:475 msgid "Sbarro/ESTA member" msgstr "Membre de Sbarro ou de l'ESTA, 15 €" -#: sith/settings.py:491 +#: sith/settings.py:497 msgid "President" msgstr "Président" -#: sith/settings.py:492 +#: sith/settings.py:498 msgid "Vice-President" msgstr "Vice-Président" -#: sith/settings.py:493 +#: sith/settings.py:499 msgid "Treasurer" msgstr "Trésorier" -#: sith/settings.py:494 +#: sith/settings.py:500 msgid "Communication supervisor" msgstr "Responsable communication" -#: sith/settings.py:495 +#: sith/settings.py:501 msgid "Secretary" msgstr "Secrétaire" -#: sith/settings.py:496 +#: sith/settings.py:502 msgid "IT supervisor" msgstr "Responsable info" -#: sith/settings.py:497 +#: sith/settings.py:503 msgid "Board member" msgstr "Membre du bureau" -#: sith/settings.py:498 +#: sith/settings.py:504 msgid "Active member" msgstr "Membre actif" -#: sith/settings.py:499 +#: sith/settings.py:505 msgid "Curious" msgstr "Curieux" -#: sith/settings.py:533 +#: sith/settings.py:539 msgid "A fresh new to be moderated" msgstr "Une nouvelle toute neuve à modérer" -#: sith/settings.py:534 +#: sith/settings.py:540 msgid "New files to be moderated" msgstr "Nouveaux fichiers à modérer" -#: sith/settings.py:535 +#: sith/settings.py:541 msgid "New pictures/album to be moderated in the SAS" msgstr "Nouvelles photos/albums à modérer dans le SAS" -#: sith/settings.py:536 +#: sith/settings.py:542 msgid "You've been identified on some pictures" msgstr "Vous avez été identifié sur des photos" -#: sith/settings.py:537 +#: sith/settings.py:543 #, python-format msgid "You just refilled of %s €" msgstr "Vous avez rechargé votre compte de %s €" -#: sith/settings.py:538 +#: sith/settings.py:544 #, python-format msgid "You just bought %s" msgstr "Vous avez acheté %s" -#: sith/settings.py:539 +#: sith/settings.py:545 msgid "You have a notification" msgstr "Vous avez une notification" -#: sith/settings.py:543 +#: sith/settings.py:549 msgid "Success!" msgstr "Succès !" -#: sith/settings.py:544 +#: sith/settings.py:550 msgid "Fail!" msgstr "Échec !" -#: sith/settings.py:545 +#: sith/settings.py:551 msgid "You successfully posted an article in the Weekmail" msgstr "Article posté avec succès dans le Weekmail" -#: sith/settings.py:546 +#: sith/settings.py:552 msgid "You successfully edited an article in the Weekmail" msgstr "Article édité avec succès dans le Weekmail" -#: sith/settings.py:547 +#: sith/settings.py:553 msgid "You successfully sent the Weekmail" msgstr "Weekmail envoyé avec succès" @@ -4786,3 +4787,5 @@ msgstr "Vous ne pouvez plus écrire de commentaires, la date est passée." msgid "Maximum characters: %(max_length)s" msgstr "Nombre de caractères max: %(max_length)s" +#~ msgid "Logo" +#~ msgstr "Logo" diff --git a/sith/settings.py b/sith/settings.py index 9d1d16a3..d12d3a0b 100644 --- a/sith/settings.py +++ b/sith/settings.py @@ -397,6 +397,13 @@ SITH_COUNTER_BANK = [ ('LA-POSTE', 'La Poste'), ] +SITH_ECOCUP_CONS = 1152 + +SITH_ECOCUP_DECO = 1151 + +# The limit is the maximum difference between cons and deco possible for a customer +SITH_ECOCUP_LIMIT = 3 + # Defines pagination for cash summary SITH_COUNTER_CASH_SUMMARY_LENGTH = 50