From 9d584ae87a16729979d2fe0b4f5ba06cb40e327c Mon Sep 17 00:00:00 2001
From: Yohann D'ANELLO <yohann.danello@gmail.com>
Date: Mon, 6 Apr 2020 07:06:52 +0200
Subject: [PATCH] Add shortcuts for transfers and credits in the activity entry
 page

---
 apps/activity/views.py                 |   4 +
 apps/note/views.py                     |   9 +-
 locale/de/LC_MESSAGES/django.po        | 144 +++++++++++-----------
 locale/fr/LC_MESSAGES/django.po        | 159 ++++++++++++++-----------
 static/js/base.js                      |  17 ++-
 static/js/transfer.js                  |  14 ++-
 templates/activity/activity_entry.html |  30 ++++-
 templates/note/transaction_form.html   |   7 +-
 8 files changed, 232 insertions(+), 152 deletions(-)

diff --git a/apps/activity/views.py b/apps/activity/views.py
index 29fbc860..714d0dbe 100644
--- a/apps/activity/views.py
+++ b/apps/activity/views.py
@@ -155,4 +155,8 @@ class ActivityEntryView(LoginRequiredMixin, TemplateView):
         ctx["noteuser_ctype"] = ContentType.objects.get_for_model(NoteUser).pk
         ctx["notespecial_ctype"] = ContentType.objects.get_for_model(NoteSpecial).pk
 
+        ctx["activities_open"] = Activity.objects.filter(open=True).filter(
+            PermissionBackend.filter_queryset(self.request.user, Activity, "view")).filter(
+            PermissionBackend.filter_queryset(self.request.user, Activity, "change")).all()
+
         return ctx
diff --git a/apps/note/views.py b/apps/note/views.py
index 4f6575e3..4f2321fb 100644
--- a/apps/note/views.py
+++ b/apps/note/views.py
@@ -1,6 +1,7 @@
 # Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
 # SPDX-License-Identifier: GPL-3.0-or-later
 
+from django.conf import settings
 from django.contrib.auth.mixins import LoginRequiredMixin
 from django.contrib.contenttypes.models import ContentType
 from django.utils.translation import gettext_lazy as _
@@ -29,7 +30,7 @@ class TransactionCreateView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTabl
     table_class = HistoryTable
 
     def get_queryset(self, **kwargs):
-        return super().get_queryset(**kwargs).order_by("-id").all()[:50]
+        return super().get_queryset(**kwargs).order_by("-id").all()[:20]
 
     def get_context_data(self, **kwargs):
         """
@@ -44,6 +45,12 @@ class TransactionCreateView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTabl
             .filter(PermissionBackend.filter_queryset(self.request.user, NoteSpecial, "view"))\
             .order_by("special_type").all()
 
+        if "activity" in settings.INSTALLED_APPS:
+            from activity.models import Activity
+            context["activities_open"] = Activity.objects.filter(open=True).filter(
+                PermissionBackend.filter_queryset(self.request.user, Activity, "view")).filter(
+                PermissionBackend.filter_queryset(self.request.user, Activity, "change")).all()
+
         return context
 
 
diff --git a/locale/de/LC_MESSAGES/django.po b/locale/de/LC_MESSAGES/django.po
index 41ed293d..5fe4ad5a 100644
--- a/locale/de/LC_MESSAGES/django.po
+++ b/locale/de/LC_MESSAGES/django.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2020-04-05 15:39+0200\n"
+"POT-Creation-Date: 2020-04-06 06:43+0200\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -171,13 +171,14 @@ msgstr ""
 msgid "Type"
 msgstr ""
 
-#: apps/activity/tables.py:77 apps/registration/forms.py:49
-#: apps/treasury/forms.py:121
+#: apps/activity/tables.py:77 apps/member/forms.py:75
+#: apps/registration/forms.py:49 apps/treasury/forms.py:121
 msgid "Last name"
 msgstr ""
 
-#: apps/activity/tables.py:79 apps/registration/forms.py:54
-#: apps/treasury/forms.py:123 templates/note/transaction_form.html:92
+#: apps/activity/tables.py:79 apps/member/forms.py:80
+#: apps/registration/forms.py:54 apps/treasury/forms.py:123
+#: templates/note/transaction_form.html:97
 msgid "First name"
 msgstr ""
 
@@ -193,7 +194,7 @@ msgstr ""
 msgid "Activities"
 msgstr ""
 
-#: apps/activity/views.py:153
+#: apps/activity/views.py:154
 msgid "Entry for activity \"{}\""
 msgstr ""
 
@@ -254,6 +255,35 @@ msgstr ""
 msgid "member"
 msgstr ""
 
+#: apps/member/forms.py:54 apps/registration/forms.py:29
+msgid "Inscription paid by Société Générale"
+msgstr ""
+
+#: apps/member/forms.py:56 apps/registration/forms.py:31
+msgid "Check this case is the Société Générale paid the inscription."
+msgstr ""
+
+#: apps/member/forms.py:61 apps/registration/forms.py:36
+msgid "Credit type"
+msgstr ""
+
+#: apps/member/forms.py:62 apps/registration/forms.py:37
+msgid "No credit"
+msgstr ""
+
+#: apps/member/forms.py:64
+msgid "You can credit the note of the user."
+msgstr ""
+
+#: apps/member/forms.py:68 apps/registration/forms.py:42
+msgid "Credit amount"
+msgstr ""
+
+#: apps/member/forms.py:85 apps/registration/forms.py:59
+#: apps/treasury/forms.py:125 templates/note/transaction_form.html:103
+msgid "Bank"
+msgstr ""
+
 #: apps/member/models.py:32
 #: templates/registration/future_profile_detail.html:47
 msgid "phone number"
@@ -382,11 +412,11 @@ msgstr ""
 msgid "fee"
 msgstr ""
 
-#: apps/member/models.py:261 apps/member/views.py:385
+#: apps/member/models.py:261 apps/member/views.py:447
 msgid "User is not a member of the parent club"
 msgstr ""
 
-#: apps/member/models.py:271 apps/member/views.py:394
+#: apps/member/models.py:271 apps/member/views.py:456
 msgid "User is already a member of the club"
 msgstr ""
 
@@ -407,39 +437,41 @@ msgstr ""
 msgid "Renew"
 msgstr ""
 
-#: apps/member/views.py:59 apps/registration/forms.py:20
+#: apps/member/views.py:56 apps/registration/forms.py:20
 msgid "This address must be valid."
 msgstr ""
 
-#: apps/member/views.py:62 templates/member/profile_info.html:45
+#: apps/member/views.py:59 templates/member/profile_info.html:45
 #: templates/registration/future_profile_detail.html:55
 msgid "Update Profile"
 msgstr ""
 
-#: apps/member/views.py:72
+#: apps/member/views.py:69
 msgid "An alias with a similar name already exists."
 msgstr ""
 
-#: apps/member/views.py:167
+#: apps/member/views.py:164
 msgid "Search user"
 msgstr ""
 
-#: apps/member/views.py:381
+#: apps/member/views.py:442
 msgid ""
 "This user don't have enough money to join this club, and can't have a "
 "negative balance."
 msgstr ""
 
-#: apps/member/views.py:398 apps/member/views.py:430
+#: apps/member/views.py:460
 msgid "The membership must start after {:%m-%d-%Y}."
 msgstr ""
 
-#: apps/member/views.py:403 apps/member/views.py:435
+#: apps/member/views.py:465
 msgid "The membership must begin before {:%m-%d-%Y}."
 msgstr ""
 
-#: apps/member/views.py:457
-msgid "This membership is already renewed"
+#: apps/member/views.py:472 apps/member/views.py:474 apps/member/views.py:476
+#: apps/registration/views.py:237 apps/registration/views.py:239
+#: apps/registration/views.py:241
+msgid "This field is required."
 msgstr ""
 
 #: apps/note/admin.py:120 apps/note/models/transactions.py:99
@@ -617,9 +649,10 @@ msgstr ""
 msgid "transactions"
 msgstr ""
 
-#: apps/note/models/transactions.py:207 templates/base.html:84
+#: apps/note/models/transactions.py:207
+#: templates/activity/activity_entry.html:13 templates/base.html:84
 #: templates/note/transaction_form.html:19
-#: templates/note/transaction_form.html:140
+#: templates/note/transaction_form.html:145
 msgid "Transfer"
 msgstr ""
 
@@ -635,7 +668,9 @@ msgstr ""
 msgid "bank"
 msgstr ""
 
-#: apps/note/models/transactions.py:253 templates/note/transaction_form.html:24
+#: apps/note/models/transactions.py:253
+#: templates/activity/activity_entry.html:17
+#: templates/note/transaction_form.html:24
 msgid "Credit"
 msgstr ""
 
@@ -672,11 +707,11 @@ msgstr ""
 msgid "Edit"
 msgstr ""
 
-#: apps/note/views.py:39
+#: apps/note/views.py:40
 msgid "Transfer money"
 msgstr ""
 
-#: apps/note/views.py:100 templates/base.html:79
+#: apps/note/views.py:107 templates/base.html:79
 msgid "Consumptions"
 msgstr ""
 
@@ -702,31 +737,6 @@ msgstr ""
 msgid "registration"
 msgstr ""
 
-#: apps/registration/forms.py:29
-msgid "Inscription paid by Société Générale"
-msgstr ""
-
-#: apps/registration/forms.py:31
-msgid "Check this case is the Société Générale paid the inscription."
-msgstr ""
-
-#: apps/registration/forms.py:36
-msgid "Credit type"
-msgstr ""
-
-#: apps/registration/forms.py:37
-msgid "No credit"
-msgstr ""
-
-#: apps/registration/forms.py:42
-msgid "Credit amount"
-msgstr ""
-
-#: apps/registration/forms.py:59 apps/treasury/forms.py:125
-#: templates/note/transaction_form.html:98
-msgid "Bank"
-msgstr ""
-
 #: apps/registration/forms.py:64
 msgid "Join BDE Club"
 msgstr ""
@@ -760,11 +770,6 @@ msgid ""
 "The entered amount is not enough for the memberships, should be at least {}"
 msgstr ""
 
-#: apps/registration/views.py:237 apps/registration/views.py:239
-#: apps/registration/views.py:241
-msgid "This field is required."
-msgstr ""
-
 #: apps/treasury/apps.py:12 templates/base.html:111
 msgid "Treasury"
 msgstr ""
@@ -791,7 +796,7 @@ msgid "You can't change the type of the remittance."
 msgstr ""
 
 #: apps/treasury/forms.py:127 apps/treasury/tables.py:47
-#: templates/note/transaction_form.html:128
+#: templates/note/transaction_form.html:133
 #: templates/treasury/remittance_form.html:18
 msgid "Amount"
 msgstr ""
@@ -812,7 +817,7 @@ msgstr ""
 msgid "Description"
 msgstr ""
 
-#: apps/treasury/models.py:46 templates/note/transaction_form.html:86
+#: apps/treasury/models.py:46 templates/note/transaction_form.html:91
 msgid "Name"
 msgstr ""
 
@@ -938,15 +943,20 @@ msgstr ""
 msgid "Guests list"
 msgstr ""
 
-#: templates/activity/activity_entry.html:10
+#: templates/activity/activity_entry.html:22
+#: templates/note/transaction_form.html:33
+msgid "Entries"
+msgstr ""
+
+#: templates/activity/activity_entry.html:30
 msgid "Return to activity page"
 msgstr ""
 
-#: templates/activity/activity_entry.html:18
+#: templates/activity/activity_entry.html:38
 msgid "entries"
 msgstr ""
 
-#: templates/activity/activity_entry.html:18
+#: templates/activity/activity_entry.html:38
 msgid "entry"
 msgstr ""
 
@@ -1145,7 +1155,7 @@ msgstr ""
 msgid "Save Changes"
 msgstr ""
 
-#: templates/note/conso_form.html:28 templates/note/transaction_form.html:50
+#: templates/note/conso_form.html:28 templates/note/transaction_form.html:55
 msgid "Select emitters"
 msgstr ""
 
@@ -1169,7 +1179,7 @@ msgstr ""
 msgid "Double consumptions"
 msgstr ""
 
-#: templates/note/conso_form.html:141 templates/note/transaction_form.html:147
+#: templates/note/conso_form.html:141 templates/note/transaction_form.html:152
 msgid "Recent transactions history"
 msgstr ""
 
@@ -1177,29 +1187,29 @@ msgstr ""
 msgid "Gift"
 msgstr ""
 
-#: templates/note/transaction_form.html:68
+#: templates/note/transaction_form.html:73
 msgid "External payment"
 msgstr ""
 
-#: templates/note/transaction_form.html:76
+#: templates/note/transaction_form.html:81
 msgid "Transfer type"
 msgstr ""
 
-#: templates/note/transaction_form.html:111
-#: templates/note/transaction_form.html:164
-#: templates/note/transaction_form.html:171
+#: templates/note/transaction_form.html:116
+#: templates/note/transaction_form.html:169
+#: templates/note/transaction_form.html:176
 msgid "Select receivers"
 msgstr ""
 
-#: templates/note/transaction_form.html:133
+#: templates/note/transaction_form.html:138
 msgid "Reason"
 msgstr ""
 
-#: templates/note/transaction_form.html:178
+#: templates/note/transaction_form.html:183
 msgid "Credit note"
 msgstr ""
 
-#: templates/note/transaction_form.html:185
+#: templates/note/transaction_form.html:190
 msgid "Debit note"
 msgstr ""
 
diff --git a/locale/fr/LC_MESSAGES/django.po b/locale/fr/LC_MESSAGES/django.po
index dca8fd69..c666c12a 100644
--- a/locale/fr/LC_MESSAGES/django.po
+++ b/locale/fr/LC_MESSAGES/django.po
@@ -3,7 +3,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2020-04-05 15:31+0200\n"
+"POT-Creation-Date: 2020-04-06 06:43+0200\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -167,13 +167,14 @@ msgstr "supprimer"
 msgid "Type"
 msgstr "Type"
 
-#: apps/activity/tables.py:77 apps/registration/forms.py:49
-#: apps/treasury/forms.py:121
+#: apps/activity/tables.py:77 apps/member/forms.py:75
+#: apps/registration/forms.py:49 apps/treasury/forms.py:121
 msgid "Last name"
 msgstr "Nom de famille"
 
-#: apps/activity/tables.py:79 apps/registration/forms.py:54
-#: apps/treasury/forms.py:123 templates/note/transaction_form.html:92
+#: apps/activity/tables.py:79 apps/member/forms.py:80
+#: apps/registration/forms.py:54 apps/treasury/forms.py:123
+#: templates/note/transaction_form.html:97
 msgid "First name"
 msgstr "Prénom"
 
@@ -189,7 +190,7 @@ msgstr "Solde du compte"
 msgid "Activities"
 msgstr "Activités"
 
-#: apps/activity/views.py:153
+#: apps/activity/views.py:154
 msgid "Entry for activity \"{}\""
 msgstr "Entrées pour l'activité « {} »"
 
@@ -250,6 +251,35 @@ msgstr "Les logs ne peuvent pas être détruits."
 msgid "member"
 msgstr "adhérent"
 
+#: apps/member/forms.py:54 apps/registration/forms.py:29
+msgid "Inscription paid by Société Générale"
+msgstr "Inscription payée par la Société générale"
+
+#: apps/member/forms.py:56 apps/registration/forms.py:31
+msgid "Check this case is the Société Générale paid the inscription."
+msgstr "Cochez cette case si la Société Générale a payé l'inscription."
+
+#: apps/member/forms.py:61 apps/registration/forms.py:36
+msgid "Credit type"
+msgstr "Type de rechargement"
+
+#: apps/member/forms.py:62 apps/registration/forms.py:37
+msgid "No credit"
+msgstr "Pas de rechargement"
+
+#: apps/member/forms.py:64
+msgid "You can credit the note of the user."
+msgstr "Vous pouvez créditer la note de l'utisateur avant l'adhésion."
+
+#: apps/member/forms.py:68 apps/registration/forms.py:42
+msgid "Credit amount"
+msgstr "Montant à créditer"
+
+#: apps/member/forms.py:85 apps/registration/forms.py:59
+#: apps/treasury/forms.py:125 templates/note/transaction_form.html:103
+msgid "Bank"
+msgstr "Banque"
+
 #: apps/member/models.py:32
 #: templates/registration/future_profile_detail.html:47
 msgid "phone number"
@@ -382,11 +412,11 @@ msgstr "l'adhésion finit le"
 msgid "fee"
 msgstr "cotisation"
 
-#: apps/member/models.py:261 apps/member/views.py:385
+#: apps/member/models.py:261 apps/member/views.py:447
 msgid "User is not a member of the parent club"
 msgstr "L'utilisateur n'est pas membre du club parent"
 
-#: apps/member/models.py:271 apps/member/views.py:394
+#: apps/member/models.py:271 apps/member/views.py:456
 msgid "User is already a member of the club"
 msgstr "L'utilisateur est déjà membre du club"
 
@@ -407,42 +437,44 @@ msgstr "adhésions"
 msgid "Renew"
 msgstr "Renouveler"
 
-#: apps/member/views.py:59 apps/registration/forms.py:20
+#: apps/member/views.py:56 apps/registration/forms.py:20
 msgid "This address must be valid."
 msgstr "Cette adresse doit être valide."
 
-#: apps/member/views.py:62 templates/member/profile_info.html:45
+#: apps/member/views.py:59 templates/member/profile_info.html:45
 #: templates/registration/future_profile_detail.html:55
 msgid "Update Profile"
 msgstr "Modifier le profil"
 
-#: apps/member/views.py:72
+#: apps/member/views.py:69
 msgid "An alias with a similar name already exists."
 msgstr "Un alias avec un nom similaire existe déjà."
 
-#: apps/member/views.py:167
+#: apps/member/views.py:164
 msgid "Search user"
 msgstr "Chercher un utilisateur"
 
-#: apps/member/views.py:381
+#: apps/member/views.py:442
 msgid ""
 "This user don't have enough money to join this club, and can't have a "
 "negative balance."
 msgstr ""
-"Cet utilisateur n'a pas assez d'argent pour rejoindre ce club et ne "
-"peut pas avoir un solde négatif."
+"Cet utilisateur n'a pas assez d'argent pour rejoindre ce club et ne peut pas "
+"avoir un solde négatif."
 
-#: apps/member/views.py:398 apps/member/views.py:430
+#: apps/member/views.py:460
 msgid "The membership must start after {:%m-%d-%Y}."
 msgstr "L'adhésion doit commencer après le {:%d/%m/%Y}."
 
-#: apps/member/views.py:403 apps/member/views.py:435
+#: apps/member/views.py:465
 msgid "The membership must begin before {:%m-%d-%Y}."
 msgstr "L'adhésion doit commencer avant le {:%d/%m/%Y}."
 
-#: apps/member/views.py:457
-msgid "This membership is already renewed"
-msgstr "Cette adhésion est déjà renouvelée"
+#: apps/member/views.py:472 apps/member/views.py:474 apps/member/views.py:476
+#: apps/registration/views.py:237 apps/registration/views.py:239
+#: apps/registration/views.py:241
+msgid "This field is required."
+msgstr "Ce champ est requis."
 
 #: apps/note/admin.py:120 apps/note/models/transactions.py:99
 msgid "source"
@@ -620,9 +652,10 @@ msgstr "transaction"
 msgid "transactions"
 msgstr "transactions"
 
-#: apps/note/models/transactions.py:207 templates/base.html:84
+#: apps/note/models/transactions.py:207
+#: templates/activity/activity_entry.html:13 templates/base.html:84
 #: templates/note/transaction_form.html:19
-#: templates/note/transaction_form.html:140
+#: templates/note/transaction_form.html:145
 msgid "Transfer"
 msgstr "Virement"
 
@@ -638,7 +671,9 @@ msgstr "prénom"
 msgid "bank"
 msgstr "banque"
 
-#: apps/note/models/transactions.py:253 templates/note/transaction_form.html:24
+#: apps/note/models/transactions.py:253
+#: templates/activity/activity_entry.html:17
+#: templates/note/transaction_form.html:24
 msgid "Credit"
 msgstr "Crédit"
 
@@ -675,11 +710,11 @@ msgstr "Supprimer"
 msgid "Edit"
 msgstr "Éditer"
 
-#: apps/note/views.py:39
+#: apps/note/views.py:40
 msgid "Transfer money"
 msgstr "Transférer de l'argent"
 
-#: apps/note/views.py:100 templates/base.html:79
+#: apps/note/views.py:107 templates/base.html:79
 msgid "Consumptions"
 msgstr "Consommations"
 
@@ -705,31 +740,6 @@ msgstr ""
 msgid "registration"
 msgstr "inscription"
 
-#: apps/registration/forms.py:29
-msgid "Inscription paid by Société Générale"
-msgstr "Inscription payée par la Société générale"
-
-#: apps/registration/forms.py:31
-msgid "Check this case is the Société Générale paid the inscription."
-msgstr "Cochez cette case si la Société Générale a payé l'inscription."
-
-#: apps/registration/forms.py:36
-msgid "Credit type"
-msgstr "Type de rechargement"
-
-#: apps/registration/forms.py:37
-msgid "No credit"
-msgstr "Pas de rechargement"
-
-#: apps/registration/forms.py:42
-msgid "Credit amount"
-msgstr "Montant à créditer"
-
-#: apps/registration/forms.py:59 apps/treasury/forms.py:125
-#: templates/note/transaction_form.html:98
-msgid "Bank"
-msgstr "Banque"
-
 #: apps/registration/forms.py:64
 msgid "Join BDE Club"
 msgstr "Adhérer au club BDE"
@@ -761,12 +771,9 @@ msgstr "Vous devez adhérer au club BDE avant d'adhérer au club Kfet."
 #: apps/registration/views.py:230
 msgid ""
 "The entered amount is not enough for the memberships, should be at least {}"
-msgstr "Le montant crédité est trop faible pour adhérer, il doit être au minimum de {}"
-
-#: apps/registration/views.py:237 apps/registration/views.py:239
-#: apps/registration/views.py:241
-msgid "This field is required."
-msgstr "Ce champ est requis."
+msgstr ""
+"Le montant crédité est trop faible pour adhérer, il doit être au minimum de "
+"{}"
 
 #: apps/treasury/apps.py:12 templates/base.html:111
 msgid "Treasury"
@@ -794,7 +801,7 @@ msgid "You can't change the type of the remittance."
 msgstr "Vous ne pouvez pas changer le type de la remise."
 
 #: apps/treasury/forms.py:127 apps/treasury/tables.py:47
-#: templates/note/transaction_form.html:128
+#: templates/note/transaction_form.html:133
 #: templates/treasury/remittance_form.html:18
 msgid "Amount"
 msgstr "Montant"
@@ -815,7 +822,7 @@ msgstr "Objet"
 msgid "Description"
 msgstr "Description"
 
-#: apps/treasury/models.py:46 templates/note/transaction_form.html:86
+#: apps/treasury/models.py:46 templates/note/transaction_form.html:91
 msgid "Name"
 msgstr "Nom"
 
@@ -941,15 +948,20 @@ msgstr "Inviter"
 msgid "Guests list"
 msgstr "Liste des invités"
 
-#: templates/activity/activity_entry.html:10
+#: templates/activity/activity_entry.html:22
+#: templates/note/transaction_form.html:33
+msgid "Entries"
+msgstr "Entrées"
+
+#: templates/activity/activity_entry.html:30
 msgid "Return to activity page"
 msgstr "Retour à la page de l'activité"
 
-#: templates/activity/activity_entry.html:18
+#: templates/activity/activity_entry.html:38
 msgid "entries"
 msgstr "entrées"
 
-#: templates/activity/activity_entry.html:18
+#: templates/activity/activity_entry.html:38
 msgid "entry"
 msgstr "entrée"
 
@@ -975,7 +987,7 @@ msgstr "La note du BDE de l'ENS Paris-Saclay."
 
 #: templates/base.html:89
 msgid "Users"
-msgstr ""
+msgstr "Utilisateurs"
 
 #: templates/base.html:94
 msgid "Clubs"
@@ -1150,7 +1162,7 @@ msgstr "Voir mes adhésions"
 msgid "Save Changes"
 msgstr "Sauvegarder les changements"
 
-#: templates/note/conso_form.html:28 templates/note/transaction_form.html:50
+#: templates/note/conso_form.html:28 templates/note/transaction_form.html:55
 msgid "Select emitters"
 msgstr "Sélection des émetteurs"
 
@@ -1174,7 +1186,7 @@ msgstr "Consommations simples"
 msgid "Double consumptions"
 msgstr "Consommations doubles"
 
-#: templates/note/conso_form.html:141 templates/note/transaction_form.html:147
+#: templates/note/conso_form.html:141 templates/note/transaction_form.html:152
 msgid "Recent transactions history"
 msgstr "Historique des transactions récentes"
 
@@ -1182,29 +1194,29 @@ msgstr "Historique des transactions récentes"
 msgid "Gift"
 msgstr "Don"
 
-#: templates/note/transaction_form.html:68
+#: templates/note/transaction_form.html:73
 msgid "External payment"
 msgstr "Paiement externe"
 
-#: templates/note/transaction_form.html:76
+#: templates/note/transaction_form.html:81
 msgid "Transfer type"
 msgstr "Type de transfert"
 
-#: templates/note/transaction_form.html:111
-#: templates/note/transaction_form.html:164
-#: templates/note/transaction_form.html:171
+#: templates/note/transaction_form.html:116
+#: templates/note/transaction_form.html:169
+#: templates/note/transaction_form.html:176
 msgid "Select receivers"
 msgstr "Sélection des destinataires"
 
-#: templates/note/transaction_form.html:133
+#: templates/note/transaction_form.html:138
 msgid "Reason"
 msgstr "Raison"
 
-#: templates/note/transaction_form.html:178
+#: templates/note/transaction_form.html:183
 msgid "Credit note"
 msgstr "Note à recharger"
 
-#: templates/note/transaction_form.html:185
+#: templates/note/transaction_form.html:190
 msgid "Debit note"
 msgstr "Note à débiter"
 
@@ -1424,3 +1436,6 @@ msgstr "Il n'y a pas de transaction associée à une remise ouverte."
 #: templates/treasury/remittance_list.html:54
 msgid "Closed remittances"
 msgstr "Remises fermées"
+
+#~ msgid "This membership is already renewed"
+#~ msgstr "Cette adhésion est déjà renouvelée"
diff --git a/static/js/base.js b/static/js/base.js
index 7febd3d6..bb73b328 100644
--- a/static/js/base.js
+++ b/static/js/base.js
@@ -19,23 +19,32 @@ function pretty_money(value) {
  * Add a message on the top of the page.
  * @param msg The message to display
  * @param alert_type The type of the alert. Choices: info, success, warning, danger
+ * @param timeout The delay (in millis) after that the message is auto-closed. If negative, then it is ignored.
  */
-function addMsg(msg, alert_type) {
+function addMsg(msg, alert_type, timeout=-1) {
     let msgDiv = $("#messages");
     let html = msgDiv.html();
+    let id = Math.floor(10000 * Math.random() + 1);
     html += "<div class=\"alert alert-" + alert_type + " alert-dismissible\">" +
-        "<button class=\"close\" data-dismiss=\"alert\" href=\"#\"><span aria-hidden=\"true\">×</span></button>"
+        "<button id=\"close-message-" + id + "\" class=\"close\" data-dismiss=\"alert\" href=\"#\"><span aria-hidden=\"true\">×</span></button>"
         + msg + "</div>\n";
     msgDiv.html(html);
+
+    if (timeout > 0) {
+        setTimeout(function () {
+            $("#close-message-" + id).click();
+        }, timeout);
+    }
 }
 
 /**
  * add Muliple error message from err_obj
  * @param errs_obj [{error_code:erro_message}]
+ * @param timeout The delay (in millis) after that the message is auto-closed. If negative, then it is ignored.
  */
-function errMsg(errs_obj){
+function errMsg(errs_obj, timeout=-1) {
     for (const err_msg of Object.values(errs_obj)) {
-              addMsg(err_msg,'danger');
+              addMsg(err_msg,'danger', timeout);
           }
 }
 
diff --git a/static/js/transfer.js b/static/js/transfer.js
index cf62e453..9aff4649 100644
--- a/static/js/transfer.js
+++ b/static/js/transfer.js
@@ -28,6 +28,7 @@ function reset() {
 }
 
 $(document).ready(function() {
+    console.log(42);
     autoCompleteNote("source_note", "source_alias_matched", "source_note_list", sources, sources_notes_display,
         "source_alias", "source_note", "user_note", "profile_pic");
     autoCompleteNote("dest_note", "dest_alias_matched", "dest_note_list", dests, dests_notes_display,
@@ -61,16 +62,25 @@ $(document).ready(function() {
 
 
     // Ensure we begin in gift mode. Removing these lines may cause problems when reloading.
-    $("#type_gift").prop('checked', 'true');
+    let type_gift = $("#type_gift"); // Default mode
+    type_gift.removeAttr('checked');
     $("#type_transfer").removeAttr('checked');
     $("#type_credit").removeAttr('checked');
     $("#type_debit").removeAttr('checked');
+    $("label[for='type_gift']").attr('class', 'btn btn-sm btn-outline-primary');
     $("label[for='type_transfer']").attr('class', 'btn btn-sm btn-outline-primary');
     $("label[for='type_credit']").attr('class', 'btn btn-sm btn-outline-primary');
     $("label[for='type_debit']").attr('class', 'btn btn-sm btn-outline-primary');
+
+    console.log("#type_" + location.hash.substr(1));
+    if (location.hash)
+        $("#type_" + location.hash.substr(1)).click();
+    else
+        type_gift.click();
+    location.hash = "";
 });
 
-$("#transfer").click(function() {
+$("#btn_transfer").click(function() {
     if ($("#type_gift").is(':checked')) {
         dests_notes_display.forEach(function (dest) {
             $.post("/api/note/transaction/transaction/",
diff --git a/templates/activity/activity_entry.html b/templates/activity/activity_entry.html
index c06a5188..a712228d 100644
--- a/templates/activity/activity_entry.html
+++ b/templates/activity/activity_entry.html
@@ -6,6 +6,26 @@
 {% load perms %}
 
 {% block content %}
+    <div class="row">
+        <div class="col-xl-12">
+            <div class="btn-group btn-group-toggle" style="width: 100%; padding: 0 0 2em 0" data-toggle="buttons">
+                <a href="{% url "note:transfer" %}#transfer" class="btn btn-sm btn-outline-primary">
+                    {% trans "Transfer" %}
+                </a>
+                {% if "note.notespecial"|not_empty_model_list %}
+                    <a href="{% url "note:transfer" %}#credit" class="btn btn-sm btn-outline-primary">
+                        {% trans "Credit" %}
+                    </a>
+                {% endif %}
+                {% for a in activities_open %}
+                    <a href="{% url "activity:activity_entry" pk=a.pk %}" class="btn btn-sm btn-outline-primary{% if a.pk == activity.pk %} active{% endif %}">
+                        {% trans "Entries" %} {{ a.name }}
+                    </a>
+                {% endfor %}
+            </div>
+        </div>
+    </div>
+
     <a href="{% url "activity:activity_detail" pk=activity.pk %}">
         <button class="btn btn-light">{% trans "Return to activity page" %}</button>
     </a>
@@ -56,10 +76,10 @@
                         note: id,
                         guest: null
                     }).done(function () {
-                        addMsg("Entrée effectuée !", "success");
+                        addMsg("Entrée effectuée !", "success", 4000);
                         reloadTable(true);
                     }).fail(function(xhr) {
-                        errMsg(xhr.responseJSON);
+                        errMsg(xhr.responseJSON, 4000);
                     });
                 }
                 else {
@@ -84,10 +104,10 @@
                             note: target.attr("data-inviter"),
                             guest: id
                         }).done(function () {
-                            addMsg("Entrée effectuée !", "success");
+                            addMsg("Entrée effectuée !", "success", 4000);
                             reloadTable(true);
                         }).fail(function (xhr) {
-                            errMsg(xhr.responseJSON);
+                            errMsg(xhr.responseJSON, 4000);
                         });
                     };
 
@@ -111,7 +131,7 @@
                                 makeTransaction();
                                 reset();
                             }).fail(function (xhr) {
-                                errMsg(xhr.responseJSON);
+                                errMsg(xhr.responseJSON, 4000);
                             });
                         };
                     };
diff --git a/templates/note/transaction_form.html b/templates/note/transaction_form.html
index 65aaa635..0b53df61 100644
--- a/templates/note/transaction_form.html
+++ b/templates/note/transaction_form.html
@@ -28,6 +28,11 @@ SPDX-License-Identifier: GPL-2.0-or-later
                         {% trans "Debit" %}
                     </label>
                 {% endif %}
+                {% for activity in activities_open %}
+                    <a href="{% url "activity:activity_entry" pk=activity.pk %}" class="btn btn-sm btn-outline-primary">
+                        {% trans "Entries" %} {{ activity.name }}
+                    </a>
+                {% endfor %}
             </div>
         </div>
     </div>
@@ -137,7 +142,7 @@ SPDX-License-Identifier: GPL-2.0-or-later
 
     <div class="form-row">
         <div class="col-md-12">
-            <button id="transfer" class="form-control btn btn-primary">{% trans 'Transfer' %}</button>
+            <button id="btn_transfer" class="form-control btn btn-primary">{% trans 'Transfer' %}</button>
         </div>
     </div>
 
-- 
GitLab