From 4bc4d266c21e86b81469e42c6704b07d3bbe8e77 Mon Sep 17 00:00:00 2001 From: imperosol Date: Wed, 9 Oct 2024 23:30:59 +0200 Subject: [PATCH 1/3] Remove the question mark from the counter state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit En raison de la manière dont le timeout marche et de l'activité des comptoirs, la notion de "comptoir inactif" n'est pas intuitive. Un comptoir est ouvert ou fermé. Point. --- core/templates/core/base.jinja | 8 +++----- counter/models.py | 15 --------------- counter/templates/counter/activity.jinja | 4 ---- 3 files changed, 3 insertions(+), 24 deletions(-) diff --git a/core/templates/core/base.jinja b/core/templates/core/base.jinja index 7492276b..44a8d7c1 100644 --- a/core/templates/core/base.jinja +++ b/core/templates/core/base.jinja @@ -70,16 +70,14 @@ {% cache 100 "counters_activity" %} {% for bar in Counter.objects.annotate_has_barman(user).filter(type="BAR") %}
  • - {# If the user is a barman, we redirect him directly to the barman page - else we redirect him to the activity page #} + {# If the user is a barman, we redirect him directly to the barman page + else we redirect him to the activity page #} {% if bar.has_annotated_barman %} {% else %} {% endif %} - {% if bar.is_inactive() %} - - {% elif bar.is_open %} + {% if bar.is_open %} {% else %} diff --git a/counter/models.py b/counter/models.py index f41f6c8c..535e4ed2 100644 --- a/counter/models.py +++ b/counter/models.py @@ -473,21 +473,6 @@ class Counter(models.Model): """Update the barman activity to prevent timeout.""" self.permanencies.filter(end=None).update(activity=timezone.now()) - @property - def is_open(self) -> bool: - return len(self.barmen_list) > 0 - - def is_inactive(self) -> bool: - """Returns True if the counter self is inactive from SITH_COUNTER_MINUTE_INACTIVE's value minutes, else False.""" - return self.is_open and ( - (timezone.now() - self.permanencies.order_by("-activity").first().activity) - > timedelta(minutes=settings.SITH_COUNTER_MINUTE_INACTIVE) - ) - - def barman_list(self) -> list[int]: - """Returns the barman id list.""" - return [b.id for b in self.barmen_list] - def can_refill(self) -> bool: """Show if the counter authorize the refilling with physic money.""" if self.type != "BAR": diff --git a/counter/templates/counter/activity.jinja b/counter/templates/counter/activity.jinja index 3fe1f2e2..29504797 100644 --- a/counter/templates/counter/activity.jinja +++ b/counter/templates/counter/activity.jinja @@ -30,10 +30,6 @@ {% trans %}counter is open, there's at least one barman connected{% endtrans %} -
    - - {% trans minutes=settings.SITH_COUNTER_MINUTE_INACTIVE %}counter is open but not active, the last sale was done at least {{ minutes }} minutes ago {% endtrans %} -
    {% trans %}counter is not open : no one is connected{% endtrans %} From c0a6f5eb30e557198b90c7fe35b9cb60f1a4d18f Mon Sep 17 00:00:00 2001 From: imperosol Date: Thu, 10 Oct 2024 00:06:22 +0200 Subject: [PATCH 2/3] Optimize barmen timeout and counter state fetch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Le timeout se fait en une seule requête et la récupération de l'état des comptoirs en une seule requête aussi. Grâce à ça, on peut en grande partie retirer le cache pour l'affichage de l'état des comptoirs, ce qui a des implications excellentes en termes d'UX (comme le fait que la redirection vers la page de comptoir ou d'activité aura plus une apparence de truc aléatoire) --- core/templates/core/base.jinja | 45 +++--- counter/api.py | 8 +- counter/models.py | 43 ++++-- counter/tests/test_counter.py | 40 ++++- counter/views.py | 1 + locale/fr/LC_MESSAGES/django.po | 263 +++++++++++++++----------------- 6 files changed, 224 insertions(+), 176 deletions(-) diff --git a/core/templates/core/base.jinja b/core/templates/core/base.jinja index 44a8d7c1..d3007f60 100644 --- a/core/templates/core/base.jinja +++ b/core/templates/core/base.jinja @@ -68,25 +68,34 @@
    diff --git a/counter/api.py b/counter/api.py index 88769b83..834852d4 100644 --- a/counter/api.py +++ b/counter/api.py @@ -23,15 +23,17 @@ from counter.schemas import CounterSchema class CounterController(ControllerBase): @route.get("", response=list[CounterSchema], permissions=[IsRoot]) def fetch_all(self): - return Counter.objects.all() + return Counter.objects.annotate_is_open() @route.get("{counter_id}/", response=CounterSchema, permissions=[CanView]) def fetch_one(self, counter_id: int): - return self.get_object_or_exception(Counter, pk=counter_id) + return self.get_object_or_exception( + Counter.objects.annotate_is_open(), pk=counter_id + ) @route.get("bar/", response=list[CounterSchema], permissions=[CanView]) def fetch_bars(self): - counters = list(Counter.objects.filter(type="BAR")) + counters = list(Counter.objects.annotate_is_open().filter(type="BAR")) for c in counters: self.check_object_permissions(c) return counters diff --git a/counter/models.py b/counter/models.py index 535e4ed2..2e58760a 100644 --- a/counter/models.py +++ b/counter/models.py @@ -358,7 +358,7 @@ class Product(models.Model): class CounterQuerySet(models.QuerySet): - def annotate_has_barman(self, user: User) -> CounterQuerySet: + def annotate_has_barman(self, user: User) -> Self: """Annotate the queryset with the `user_is_barman` field. For each counter, this field has value True if the user @@ -383,6 +383,29 @@ class CounterQuerySet(models.QuerySet): subquery = user.counters.filter(pk=OuterRef("pk")) return self.annotate(has_annotated_barman=Exists(subquery)) + def annotate_is_open(self) -> Self: + """Annotate tue queryset with the `is_open` field. + + For each counter, if `is_open=True`, then the counter is currently opened. + Else the counter is closed. + """ + return self.annotate( + is_open=Exists( + Permanency.objects.filter(counter_id=OuterRef("pk"), end=None) + ) + ) + + def handle_timeout(self) -> int: + """Disconnect the barmen who are inactive in the given counters. + + Returns: + The number of affected rows (ie, the number of timeouted permanences) + """ + timeout = timezone.now() - timedelta(minutes=settings.SITH_BARMAN_TIMEOUT) + return Permanency.objects.filter( + counter__in=self, end=None, activity__lt=timeout + ).update(end=F("activity")) + class Counter(models.Model): name = models.CharField(_("name"), max_length=30) @@ -450,20 +473,10 @@ class Counter(models.Model): @cached_property def barmen_list(self) -> list[User]: - return self.get_barmen_list() - - def get_barmen_list(self) -> list[User]: - """Returns the barman list as list of User. - - Also handle the timeout of the barmen - """ - perms = self.permanencies.filter(end=None) - - # disconnect barmen who are inactive - timeout = timezone.now() - timedelta(minutes=settings.SITH_BARMAN_TIMEOUT) - perms.filter(activity__lte=timeout).update(end=F("activity")) - - return [p.user for p in perms.select_related("user")] + """Returns the barman list as list of User.""" + return [ + p.user for p in self.permanencies.filter(end=None).select_related("user") + ] def get_random_barman(self) -> User: """Return a random user being currently a barman.""" diff --git a/counter/tests/test_counter.py b/counter/tests/test_counter.py index 4941702e..781c7e5a 100644 --- a/counter/tests/test_counter.py +++ b/counter/tests/test_counter.py @@ -15,20 +15,29 @@ import json import re import string +from datetime import timedelta import pytest +from django.conf import settings from django.core.cache import cache from django.test import Client, TestCase from django.urls import reverse from django.utils import timezone -from django.utils.timezone import timedelta +from django.utils.timezone import now +from freezegun import freeze_time from model_bakery import baker from club.models import Club, Membership from core.baker_recipes import subscriber_user from core.models import User -from counter.models import BillingInfo, Counter, Customer, Permanency, Product, Selling -from sith.settings import SITH_MAIN_CLUB +from counter.models import ( + BillingInfo, + Counter, + Customer, + Permanency, + Product, + Selling, +) class TestCounter(TestCase): @@ -219,7 +228,7 @@ class TestCounterStats(TestCase): s = Selling( label=barbar.name, product=barbar, - club=Club.objects.get(name=SITH_MAIN_CLUB["name"]), + club=Club.objects.get(name=settings.SITH_MAIN_CLUB["name"]), counter=cls.counter, unit_price=2, seller=cls.skia, @@ -497,6 +506,29 @@ class TestBarmanConnection(TestCase): assert not '
  • S' Kia
  • ' in str(response.content) +@pytest.mark.django_db +def test_barman_timeout(): + """Test that barmen timeout is well managed.""" + bar = baker.make(Counter, type="BAR") + user = baker.make(User) + bar.sellers.add(user) + baker.make(Permanency, counter=bar, user=user, start=now()) + + qs = Counter.objects.annotate_is_open().filter(pk=bar.pk) + + bar = qs[0] + assert bar.is_open + assert bar.barmen_list == [user] + qs.handle_timeout() # handling timeout before the actual timeout should be no-op + assert qs[0].is_open + with freeze_time() as frozen_time: + frozen_time.tick(timedelta(minutes=settings.SITH_BARMAN_TIMEOUT + 1)) + qs.handle_timeout() + bar = qs[0] + assert not bar.is_open + assert bar.barmen_list == [] + + class TestStudentCard(TestCase): """Tests for adding and deleting Stundent Cards Test that an user can be found with it's student card. diff --git a/counter/views.py b/counter/views.py index f45adf1f..50bf02b0 100644 --- a/counter/views.py +++ b/counter/views.py @@ -239,6 +239,7 @@ class CounterClick(CounterTabsMixin, CanViewMixin, DetailView): """ model = Counter + queryset = Counter.objects.annotate_is_open() template_name = "counter/counter_click.jinja" pk_url_kwarg = "counter_id" current_tab = "counter" diff --git a/locale/fr/LC_MESSAGES/django.po b/locale/fr/LC_MESSAGES/django.po index 6d2f3283..02b4bcbe 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: 2024-10-09 11:48+0200\n" +"POT-Creation-Date: 2024-10-10 19:37+0200\n" "PO-Revision-Date: 2016-07-18\n" "Last-Translator: Skia \n" "Language-Team: AE info \n" @@ -19,7 +19,7 @@ msgstr "" #: accounting/models.py:62 accounting/models.py:103 accounting/models.py:136 #: accounting/models.py:203 club/models.py:55 com/models.py:274 #: com/models.py:293 counter/models.py:220 counter/models.py:253 -#: counter/models.py:388 forum/models.py:59 launderette/models.py:29 +#: counter/models.py:411 forum/models.py:59 launderette/models.py:29 #: launderette/models.py:84 launderette/models.py:122 msgid "name" msgstr "nom" @@ -66,7 +66,7 @@ msgstr "numéro de compte" #: accounting/models.py:109 accounting/models.py:140 club/models.py:345 #: com/models.py:74 com/models.py:259 com/models.py:299 counter/models.py:276 -#: counter/models.py:390 trombi/models.py:210 +#: counter/models.py:413 trombi/models.py:210 msgid "club" msgstr "club" @@ -87,12 +87,12 @@ msgstr "Compte club" msgid "%(club_account)s on %(bank_account)s" msgstr "%(club_account)s sur %(bank_account)s" -#: accounting/models.py:201 club/models.py:351 counter/models.py:901 +#: accounting/models.py:201 club/models.py:351 counter/models.py:899 #: election/models.py:16 launderette/models.py:179 msgid "start date" msgstr "date de début" -#: accounting/models.py:202 club/models.py:352 counter/models.py:902 +#: accounting/models.py:202 club/models.py:352 counter/models.py:900 #: election/models.py:17 msgid "end date" msgstr "date de fin" @@ -106,7 +106,7 @@ msgid "club account" msgstr "compte club" #: accounting/models.py:212 accounting/models.py:272 counter/models.py:57 -#: counter/models.py:611 +#: counter/models.py:609 msgid "amount" msgstr "montant" @@ -128,18 +128,18 @@ msgstr "classeur" #: accounting/models.py:273 core/models.py:940 core/models.py:1460 #: core/models.py:1505 core/models.py:1534 core/models.py:1558 -#: counter/models.py:621 counter/models.py:725 counter/models.py:937 +#: counter/models.py:619 counter/models.py:723 counter/models.py:935 #: eboutic/models.py:57 eboutic/models.py:189 forum/models.py:311 #: forum/models.py:412 msgid "date" msgstr "date" -#: accounting/models.py:274 counter/models.py:222 counter/models.py:938 +#: accounting/models.py:274 counter/models.py:222 counter/models.py:936 #: pedagogy/models.py:207 msgid "comment" msgstr "commentaire" -#: accounting/models.py:276 counter/models.py:623 counter/models.py:727 +#: accounting/models.py:276 counter/models.py:621 counter/models.py:725 #: subscription/models.py:56 msgid "payment method" msgstr "méthode de paiement" @@ -166,7 +166,7 @@ msgstr "type comptable" #: accounting/models.py:311 accounting/models.py:450 accounting/models.py:483 #: accounting/models.py:515 core/models.py:1533 core/models.py:1559 -#: counter/models.py:691 +#: counter/models.py:689 msgid "label" msgstr "étiquette" @@ -650,7 +650,7 @@ msgid "Done" msgstr "Effectuées" #: accounting/templates/accounting/journal_details.jinja:41 -#: counter/templates/counter/cash_summary_list.jinja:37 counter/views.py:940 +#: counter/templates/counter/cash_summary_list.jinja:37 counter/views.py:941 #: pedagogy/templates/pedagogy/moderation.jinja:13 #: pedagogy/templates/pedagogy/uv_detail.jinja:142 #: trombi/templates/trombi/comment.jinja:4 @@ -971,11 +971,11 @@ msgstr "Date de fin" msgid "Counter" msgstr "Comptoir" -#: club/forms.py:167 counter/views.py:684 +#: club/forms.py:167 counter/views.py:685 msgid "Products" msgstr "Produits" -#: club/forms.py:172 counter/views.py:689 +#: club/forms.py:172 counter/views.py:690 msgid "Archived products" msgstr "Produits archivés" @@ -1045,7 +1045,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:337 counter/models.py:892 counter/models.py:928 +#: club/models.py:337 counter/models.py:890 counter/models.py:926 #: eboutic/models.py:53 eboutic/models.py:185 election/models.py:183 #: launderette/models.py:136 launderette/models.py:198 sas/models.py:274 #: trombi/models.py:206 @@ -1373,7 +1373,7 @@ msgstr "Anciens membres" msgid "History" msgstr "Historique" -#: club/views.py:116 core/templates/core/base.jinja:101 core/views/user.py:223 +#: club/views.py:116 core/templates/core/base.jinja:107 core/views/user.py:223 #: sas/templates/sas/picture.jinja:91 trombi/views.py:61 msgid "Tools" msgstr "Outils" @@ -1659,7 +1659,7 @@ msgid "Calls to moderate" msgstr "Appels à modérer" #: com/templates/com/news_admin_list.jinja:242 -#: core/templates/core/base.jinja:216 +#: core/templates/core/base.jinja:222 msgid "Events" msgstr "Événements" @@ -2416,52 +2416,52 @@ msgstr "Inscription" msgid "Search" msgstr "Recherche" -#: core/templates/core/base.jinja:102 +#: core/templates/core/base.jinja:108 msgid "Logout" msgstr "Déconnexion" -#: core/templates/core/base.jinja:150 +#: core/templates/core/base.jinja:156 msgid "You do not have any unread notification" msgstr "Vous n'avez aucune notification non lue" -#: core/templates/core/base.jinja:155 +#: core/templates/core/base.jinja:161 msgid "View more" msgstr "Voir plus" -#: core/templates/core/base.jinja:158 +#: core/templates/core/base.jinja:164 #: forum/templates/forum/last_unread.jinja:21 msgid "Mark all as read" msgstr "Marquer tout comme lu" -#: core/templates/core/base.jinja:206 +#: core/templates/core/base.jinja:212 msgid "Main" msgstr "Accueil" -#: core/templates/core/base.jinja:208 +#: core/templates/core/base.jinja:214 msgid "Associations & Clubs" msgstr "Associations & Clubs" -#: core/templates/core/base.jinja:210 +#: core/templates/core/base.jinja:216 msgid "AE" msgstr "L'AE" -#: core/templates/core/base.jinja:211 +#: core/templates/core/base.jinja:217 msgid "AE's clubs" msgstr "Les clubs de L'AE" -#: core/templates/core/base.jinja:212 +#: core/templates/core/base.jinja:218 msgid "Others UTBM's Associations" msgstr "Les autres associations de l'UTBM" -#: core/templates/core/base.jinja:218 core/templates/core/user_tools.jinja:172 +#: core/templates/core/base.jinja:224 core/templates/core/user_tools.jinja:172 msgid "Elections" msgstr "Élections" -#: core/templates/core/base.jinja:219 +#: core/templates/core/base.jinja:225 msgid "Big event" msgstr "Grandes Activités" -#: core/templates/core/base.jinja:222 +#: core/templates/core/base.jinja:228 #: forum/templates/forum/favorite_topics.jinja:18 #: forum/templates/forum/last_unread.jinja:18 #: forum/templates/forum/macros.jinja:90 forum/templates/forum/main.jinja:6 @@ -2470,11 +2470,11 @@ msgstr "Grandes Activités" msgid "Forum" msgstr "Forum" -#: core/templates/core/base.jinja:223 +#: core/templates/core/base.jinja:229 msgid "Gallery" msgstr "Photos" -#: core/templates/core/base.jinja:224 counter/models.py:398 +#: core/templates/core/base.jinja:230 counter/models.py:421 #: counter/templates/counter/counter_list.jinja:11 #: eboutic/templates/eboutic/eboutic_main.jinja:4 #: eboutic/templates/eboutic/eboutic_main.jinja:22 @@ -2484,75 +2484,75 @@ msgstr "Photos" msgid "Eboutic" msgstr "Eboutic" -#: core/templates/core/base.jinja:226 +#: core/templates/core/base.jinja:232 msgid "Services" msgstr "Services" -#: core/templates/core/base.jinja:228 +#: core/templates/core/base.jinja:234 msgid "Matmatronch" msgstr "Matmatronch" -#: core/templates/core/base.jinja:229 launderette/models.py:38 +#: core/templates/core/base.jinja:235 launderette/models.py:38 #: launderette/templates/launderette/launderette_book.jinja:5 #: launderette/templates/launderette/launderette_book_choose.jinja:4 #: launderette/templates/launderette/launderette_main.jinja:4 msgid "Launderette" msgstr "Laverie" -#: core/templates/core/base.jinja:230 core/templates/core/file.jinja:20 +#: core/templates/core/base.jinja:236 core/templates/core/file.jinja:20 #: core/views/files.py:116 msgid "Files" msgstr "Fichiers" -#: core/templates/core/base.jinja:231 core/templates/core/user_tools.jinja:163 +#: core/templates/core/base.jinja:237 core/templates/core/user_tools.jinja:163 msgid "Pedagogy" msgstr "Pédagogie" -#: core/templates/core/base.jinja:235 +#: core/templates/core/base.jinja:241 msgid "My Benefits" msgstr "Mes Avantages" -#: core/templates/core/base.jinja:237 +#: core/templates/core/base.jinja:243 msgid "Sponsors" msgstr "Partenaires" -#: core/templates/core/base.jinja:238 +#: core/templates/core/base.jinja:244 msgid "Subscriber benefits" msgstr "Les avantages cotisants" -#: core/templates/core/base.jinja:242 +#: core/templates/core/base.jinja:248 msgid "Help" msgstr "Aide" -#: core/templates/core/base.jinja:244 +#: core/templates/core/base.jinja:250 msgid "FAQ" msgstr "FAQ" -#: core/templates/core/base.jinja:245 core/templates/core/base.jinja:285 +#: core/templates/core/base.jinja:251 core/templates/core/base.jinja:291 msgid "Contacts" msgstr "Contacts" -#: core/templates/core/base.jinja:246 +#: core/templates/core/base.jinja:252 msgid "Wiki" msgstr "Wiki" -#: core/templates/core/base.jinja:286 +#: core/templates/core/base.jinja:292 msgid "Legal notices" msgstr "Mentions légales" -#: core/templates/core/base.jinja:287 +#: core/templates/core/base.jinja:293 msgid "Intellectual property" msgstr "Propriété intellectuelle" -#: core/templates/core/base.jinja:288 +#: core/templates/core/base.jinja:294 msgid "Help & Documentation" msgstr "Aide & Documentation" -#: core/templates/core/base.jinja:289 +#: core/templates/core/base.jinja:295 msgid "R&D" msgstr "R&D" -#: core/templates/core/base.jinja:292 +#: core/templates/core/base.jinja:298 msgid "Site created by the IT Department of the AE" msgstr "Site réalisé par le Pôle Informatique de l'AE" @@ -3039,7 +3039,7 @@ msgid "Eboutic invoices" msgstr "Facture eboutic" #: core/templates/core/user_account.jinja:54 -#: core/templates/core/user_tools.jinja:58 counter/views.py:709 +#: core/templates/core/user_tools.jinja:58 counter/views.py:710 msgid "Etickets" msgstr "Etickets" @@ -3375,7 +3375,7 @@ msgid "Subscription stats" msgstr "Statistiques de cotisation" #: core/templates/core/user_tools.jinja:48 counter/forms.py:164 -#: counter/views.py:679 +#: counter/views.py:680 msgid "Counters" msgstr "Comptoirs" @@ -3392,12 +3392,12 @@ msgid "Product types management" msgstr "Gestion des types de produit" #: core/templates/core/user_tools.jinja:56 -#: counter/templates/counter/cash_summary_list.jinja:23 counter/views.py:699 +#: counter/templates/counter/cash_summary_list.jinja:23 counter/views.py:700 msgid "Cash register summaries" msgstr "Relevés de caisse" #: core/templates/core/user_tools.jinja:57 -#: counter/templates/counter/invoices_call.jinja:4 counter/views.py:704 +#: counter/templates/counter/invoices_call.jinja:4 counter/views.py:705 msgid "Invoices call" msgstr "Appels à facture" @@ -3608,8 +3608,8 @@ msgstr "Photos" msgid "Galaxy" msgstr "Galaxie" -#: counter/apps.py:30 counter/models.py:414 counter/models.py:898 -#: counter/models.py:934 launderette/models.py:32 +#: counter/apps.py:30 counter/models.py:437 counter/models.py:896 +#: counter/models.py:932 launderette/models.py:32 msgid "counter" msgstr "comptoir" @@ -3649,7 +3649,7 @@ msgstr "client" msgid "customers" msgstr "clients" -#: counter/models.py:74 counter/views.py:261 +#: counter/models.py:74 counter/views.py:262 msgid "Not enough money" msgstr "Solde insuffisant" @@ -3725,77 +3725,77 @@ msgstr "groupe d'achat" msgid "archived" msgstr "archivé" -#: counter/models.py:294 counter/models.py:1034 +#: counter/models.py:294 counter/models.py:1032 msgid "product" msgstr "produit" -#: counter/models.py:393 +#: counter/models.py:416 msgid "products" msgstr "produits" -#: counter/models.py:396 +#: counter/models.py:419 msgid "counter type" msgstr "type de comptoir" -#: counter/models.py:398 +#: counter/models.py:421 msgid "Bar" msgstr "Bar" -#: counter/models.py:398 +#: counter/models.py:421 msgid "Office" msgstr "Bureau" -#: counter/models.py:401 +#: counter/models.py:424 msgid "sellers" msgstr "vendeurs" -#: counter/models.py:409 launderette/models.py:192 +#: counter/models.py:432 launderette/models.py:192 msgid "token" msgstr "jeton" -#: counter/models.py:629 +#: counter/models.py:627 msgid "bank" msgstr "banque" -#: counter/models.py:631 counter/models.py:732 +#: counter/models.py:629 counter/models.py:730 msgid "is validated" msgstr "est validé" -#: counter/models.py:636 +#: counter/models.py:634 msgid "refilling" msgstr "rechargement" -#: counter/models.py:709 eboutic/models.py:245 +#: counter/models.py:707 eboutic/models.py:245 msgid "unit price" msgstr "prix unitaire" -#: counter/models.py:710 counter/models.py:1014 eboutic/models.py:246 +#: counter/models.py:708 counter/models.py:1012 eboutic/models.py:246 msgid "quantity" msgstr "quantité" -#: counter/models.py:729 +#: counter/models.py:727 msgid "Sith account" msgstr "Compte utilisateur" -#: counter/models.py:729 sith/settings.py:403 sith/settings.py:408 +#: counter/models.py:727 sith/settings.py:403 sith/settings.py:408 #: sith/settings.py:428 msgid "Credit card" msgstr "Carte bancaire" -#: counter/models.py:737 +#: counter/models.py:735 msgid "selling" msgstr "vente" -#: counter/models.py:841 +#: counter/models.py:839 msgid "Unknown event" msgstr "Événement inconnu" -#: counter/models.py:842 +#: counter/models.py:840 #, python-format msgid "Eticket bought for the event %(event)s" msgstr "Eticket acheté pour l'événement %(event)s" -#: counter/models.py:844 counter/models.py:867 +#: counter/models.py:842 counter/models.py:865 #, python-format msgid "" "You bought an eticket for the event %(event)s.\n" @@ -3807,63 +3807,63 @@ msgstr "" "Vous pouvez également retrouver tous vos e-tickets sur votre page de compte " "%(url)s." -#: counter/models.py:903 +#: counter/models.py:901 msgid "last activity date" msgstr "dernière activité" -#: counter/models.py:906 +#: counter/models.py:904 msgid "permanency" msgstr "permanence" -#: counter/models.py:939 +#: counter/models.py:937 msgid "emptied" msgstr "coffre vidée" -#: counter/models.py:942 +#: counter/models.py:940 msgid "cash register summary" msgstr "relevé de caisse" -#: counter/models.py:1010 +#: counter/models.py:1008 msgid "cash summary" msgstr "relevé" -#: counter/models.py:1013 +#: counter/models.py:1011 msgid "value" msgstr "valeur" -#: counter/models.py:1016 +#: counter/models.py:1014 msgid "check" msgstr "chèque" -#: counter/models.py:1018 +#: counter/models.py:1016 msgid "True if this is a bank check, else False" msgstr "Vrai si c'est un chèque, sinon Faux." -#: counter/models.py:1022 +#: counter/models.py:1020 msgid "cash register summary item" msgstr "élément de relevé de caisse" -#: counter/models.py:1038 +#: counter/models.py:1036 msgid "banner" msgstr "bannière" -#: counter/models.py:1040 +#: counter/models.py:1038 msgid "event date" msgstr "date de l'événement" -#: counter/models.py:1042 +#: counter/models.py:1040 msgid "event title" msgstr "titre de l'événement" -#: counter/models.py:1044 +#: counter/models.py:1042 msgid "secret" msgstr "secret" -#: counter/models.py:1083 +#: counter/models.py:1081 msgid "uid" msgstr "uid" -#: counter/models.py:1088 +#: counter/models.py:1086 msgid "student cards" msgstr "cartes étudiante" @@ -3890,15 +3890,6 @@ msgid "counter is open, there's at least one barman connected" msgstr "Le comptoir est ouvert, et il y a au moins un barman connecté" #: counter/templates/counter/activity.jinja:35 -#, python-format -msgid "" -"counter is open but not active, the last sale was done at least %(minutes)s " -"minutes ago " -msgstr "" -"Le comptoir est ouvert, mais inactif. La dernière vente a eu lieu il y a " -"%(minutes)s minutes." - -#: counter/templates/counter/activity.jinja:39 msgid "counter is not open : no one is connected" msgstr "Le comptoir est fermé" @@ -3919,7 +3910,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:941 +#: counter/templates/counter/cash_summary_list.jinja:36 counter/views.py:942 msgid "Emptied" msgstr "Coffre vidé" @@ -4165,81 +4156,81 @@ 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:252 +#: counter/views.py:253 msgid "Too young for that product" msgstr "Trop jeune pour ce produit" -#: counter/views.py:255 +#: counter/views.py:256 msgid "Not allowed for that product" msgstr "Non autorisé pour ce produit" -#: counter/views.py:258 +#: counter/views.py:259 msgid "No date of birth provided" msgstr "Pas de date de naissance renseignée" -#: counter/views.py:547 +#: counter/views.py:548 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:674 +#: counter/views.py:675 msgid "Counter administration" msgstr "Administration des comptoirs" -#: counter/views.py:694 +#: counter/views.py:695 msgid "Product types" msgstr "Types de produit" -#: counter/views.py:898 +#: counter/views.py:899 msgid "10 cents" msgstr "10 centimes" -#: counter/views.py:899 +#: counter/views.py:900 msgid "20 cents" msgstr "20 centimes" -#: counter/views.py:900 +#: counter/views.py:901 msgid "50 cents" msgstr "50 centimes" -#: counter/views.py:901 +#: counter/views.py:902 msgid "1 euro" msgstr "1 €" -#: counter/views.py:902 +#: counter/views.py:903 msgid "2 euros" msgstr "2 €" -#: counter/views.py:903 +#: counter/views.py:904 msgid "5 euros" msgstr "5 €" -#: counter/views.py:904 +#: counter/views.py:905 msgid "10 euros" msgstr "10 €" -#: counter/views.py:905 +#: counter/views.py:906 msgid "20 euros" msgstr "20 €" -#: counter/views.py:906 +#: counter/views.py:907 msgid "50 euros" msgstr "50 €" -#: counter/views.py:908 +#: counter/views.py:909 msgid "100 euros" msgstr "100 €" -#: counter/views.py:911 counter/views.py:917 counter/views.py:923 -#: counter/views.py:929 counter/views.py:935 +#: counter/views.py:912 counter/views.py:918 counter/views.py:924 +#: counter/views.py:930 counter/views.py:936 msgid "Check amount" msgstr "Montant du chèque" -#: counter/views.py:914 counter/views.py:920 counter/views.py:926 -#: counter/views.py:932 counter/views.py:938 +#: counter/views.py:915 counter/views.py:921 counter/views.py:927 +#: counter/views.py:933 counter/views.py:939 msgid "Check quantity" msgstr "Nombre de chèque" -#: counter/views.py:1507 +#: counter/views.py:1459 msgid "people(s)" msgstr "personne(s)" @@ -4812,12 +4803,12 @@ msgid "Washing and drying" msgstr "Lavage et séchage" #: launderette/templates/launderette/launderette_book.jinja:27 -#: sith/settings.py:642 +#: sith/settings.py:639 msgid "Washing" msgstr "Lavage" #: launderette/templates/launderette/launderette_book.jinja:31 -#: sith/settings.py:642 +#: sith/settings.py:639 msgid "Drying" msgstr "Séchage" @@ -5609,72 +5600,72 @@ msgstr "Membre actif⸱ve" msgid "Curious" msgstr "Curieux⸱euse" -#: sith/settings.py:646 +#: sith/settings.py:643 msgid "A new poster needs to be moderated" msgstr "Une nouvelle affiche a besoin d'être modérée" -#: sith/settings.py:647 +#: sith/settings.py:644 msgid "A new mailing list needs to be moderated" msgstr "Une nouvelle mailing list a besoin d'être modérée" -#: sith/settings.py:650 +#: sith/settings.py:647 msgid "A new pedagogy comment has been signaled for moderation" msgstr "" "Un nouveau commentaire de la pédagogie a été signalé pour la modération" -#: sith/settings.py:652 +#: sith/settings.py:649 #, python-format msgid "There are %s fresh news to be moderated" msgstr "Il y a %s nouvelles toutes fraîches à modérer" -#: sith/settings.py:653 +#: sith/settings.py:650 msgid "New files to be moderated" msgstr "Nouveaux fichiers à modérer" -#: sith/settings.py:654 +#: sith/settings.py:651 #, python-format msgid "There are %s pictures to be moderated in the SAS" msgstr "Il y a %s photos à modérer dans le SAS" -#: sith/settings.py:655 +#: sith/settings.py:652 msgid "You've been identified on some pictures" msgstr "Vous avez été identifié sur des photos" -#: sith/settings.py:656 +#: sith/settings.py:653 #, python-format msgid "You just refilled of %s €" msgstr "Vous avez rechargé votre compte de %s€" -#: sith/settings.py:657 +#: sith/settings.py:654 #, python-format msgid "You just bought %s" msgstr "Vous avez acheté %s" -#: sith/settings.py:658 +#: sith/settings.py:655 msgid "You have a notification" msgstr "Vous avez une notification" -#: sith/settings.py:670 +#: sith/settings.py:667 msgid "Success!" msgstr "Succès !" -#: sith/settings.py:671 +#: sith/settings.py:668 msgid "Fail!" msgstr "Échec !" -#: sith/settings.py:672 +#: sith/settings.py:669 msgid "You successfully posted an article in the Weekmail" msgstr "Article posté avec succès dans le Weekmail" -#: sith/settings.py:673 +#: sith/settings.py:670 msgid "You successfully edited an article in the Weekmail" msgstr "Article édité avec succès dans le Weekmail" -#: sith/settings.py:674 +#: sith/settings.py:671 msgid "You successfully sent the Weekmail" msgstr "Weekmail envoyé avec succès" -#: sith/settings.py:682 +#: sith/settings.py:679 msgid "AE tee-shirt" msgstr "Tee-shirt AE" From ca25a12be0354012bacc58974dc4741863d02ec6 Mon Sep 17 00:00:00 2001 From: imperosol Date: Thu, 10 Oct 2024 00:10:12 +0200 Subject: [PATCH 3/3] Increase the barmen timeout limit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit La limite actuelle est trop faible. En soirée, on s'en fout. Mais en journée, c'est terriblement chiant. Certains barmens passent leur temps à rafraichir la la page, certains mettent un rechargement auto à intervalles réguliers (ce qui tue le concept du timeout), et d'autres encore ont juste arrêté d'y prêter attention (mais le comptoir apparait alors comme fermé, et des étudiants qui auraient pu venir au Foyer ne viennent finalement pas) --- core/templates/core/base.jinja | 5 ++--- sith/settings.py | 5 +---- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/core/templates/core/base.jinja b/core/templates/core/base.jinja index d3007f60..cfa94908 100644 --- a/core/templates/core/base.jinja +++ b/core/templates/core/base.jinja @@ -73,9 +73,8 @@ Thus the barmen timeout is handled in the only place that is loaded on every page : the header bar. However, let's be clear : this has nothing to do here. - It's' merely a contrived workaround in order not to setup - a proper periodic task manager that has lived way too much. - As Hubert Bonisseur De La Batte said : "s'agirait de grandir"#} + It's' merely a contrived workaround that should + replaced by a proper task manager as soon as possible. #} {% set _ = Counter.objects.filter(type="BAR").handle_timeout() %} {% endcache %} {% for bar in Counter.objects.annotate_has_barman(user).annotate_is_open().filter(type="BAR") %} diff --git a/sith/settings.py b/sith/settings.py index 8a534cd2..cd70f49b 100644 --- a/sith/settings.py +++ b/sith/settings.py @@ -612,14 +612,11 @@ SITH_CLUB_ROLES = { SITH_MAXIMUM_FREE_ROLE = 1 # Minutes to timeout the logged barmen -SITH_BARMAN_TIMEOUT = 20 +SITH_BARMAN_TIMEOUT = 30 # Minutes to delete the last operations SITH_LAST_OPERATIONS_LIMIT = 10 -# Minutes for a counter to be inactive -SITH_COUNTER_MINUTE_INACTIVE = 10 - # ET variables SITH_EBOUTIC_CB_ENABLED = True SITH_EBOUTIC_ET_URL = (