diff --git a/apps/note/forms.py b/apps/note/forms.py index 15cccf2e..3222acec 100644 --- a/apps/note/forms.py +++ b/apps/note/forms.py @@ -3,6 +3,7 @@ from dal import autocomplete from django import forms +from django.utils.translation import gettext_lazy as _ from .models import Transaction, TransactionTemplate, TemplateTransaction @@ -33,6 +34,23 @@ class TransactionForm(forms.ModelForm): def save(self, commit=True): super().save(commit) + + def clean(self): + """ + If the user has no right to transfer funds, then it will be the source of the transfer by default. + Transactions between a note and the same note are not authorized. + """ + + cleaned_data = super().clean() + if not "source" in cleaned_data: # TODO Replace it with "if %user has no right to transfer funds" + cleaned_data["source"] = self.user.note + + if cleaned_data["source"].pk == cleaned_data["destination"].pk: + self.add_error("destination", _("Source and destination must be different.")) + + return cleaned_data + + class Meta: model = Transaction fields = ( diff --git a/apps/note/models/transactions.py b/apps/note/models/transactions.py index 49fc44b4..598c119b 100644 --- a/apps/note/models/transactions.py +++ b/apps/note/models/transactions.py @@ -84,8 +84,6 @@ class Transaction(PolymorphicModel): amount is store in centimes of currency, making it a positive integer value. (from someone to someone else) - - TODO: Ensure source != destination. """ source = models.ForeignKey( @@ -126,6 +124,11 @@ class Transaction(PolymorphicModel): """ When saving, also transfer money between two notes """ + + if self.source.pk == self.destination.pk: + # When source == destination, no money is transfered + return + created = self.pk is None to_transfer = self.amount * self.quantity if not created: diff --git a/apps/note/views.py b/apps/note/views.py index 75577a2e..5038df16 100644 --- a/apps/note/views.py +++ b/apps/note/views.py @@ -41,17 +41,12 @@ class TransactionCreate(LoginRequiredMixin, CreateView): if False: # TODO: fix it with "if %user has no right to transfer funds" del form.fields['source'] + form.user = self.request.user return form - def form_valid(self, form): - """ - If the user has no right to transfer funds, then it will be the source of the transfer by default. - """ - if False: # TODO: fix it with "if %user has no right to transfer funds" - form.instance.source = self.request.user.note - - return super().form_valid(form) + def get_success_url(self): + return reverse('note:transfer') class NoteAutocomplete(autocomplete.Select2QuerySetView): diff --git a/locale/de/LC_MESSAGES/django.po b/locale/de/LC_MESSAGES/django.po index 3aadf83e..9e7b56d5 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-02-21 13:50+0100\n" +"POT-Creation-Date: 2020-02-27 17:39+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -24,8 +24,8 @@ msgstr "" #: apps/activity/models.py:19 apps/activity/models.py:44 #: apps/member/models.py:60 apps/member/models.py:111 -#: apps/note/models/notes.py:176 apps/note/models/transactions.py:23 -#: apps/note/models/transactions.py:43 templates/member/profile_detail.html:11 +#: apps/note/models/notes.py:184 apps/note/models/transactions.py:24 +#: apps/note/models/transactions.py:44 templates/member/profile_detail.html:11 msgid "name" msgstr "" @@ -45,12 +45,12 @@ msgstr "" msgid "activity types" msgstr "" -#: apps/activity/models.py:48 +#: apps/activity/models.py:48 apps/note/models/transactions.py:69 msgid "description" msgstr "" -#: apps/activity/models.py:54 apps/note/models/notes.py:152 -#: apps/note/models/transactions.py:60 apps/note/models/transactions.py:104 +#: apps/activity/models.py:54 apps/note/models/notes.py:160 +#: apps/note/models/transactions.py:62 msgid "type" msgstr "" @@ -144,7 +144,7 @@ msgid "" "members can renew their membership." msgstr "" -#: apps/member/models.py:93 apps/note/models/notes.py:127 +#: apps/member/models.py:93 apps/note/models/notes.py:135 msgid "club" msgstr "" @@ -184,28 +184,32 @@ msgstr "" msgid "Update Profile" msgstr "" -#: apps/member/views.py:79 apps/note/models/notes.py:229 +#: apps/member/views.py:79 msgid "An alias with a similar name already exists." msgstr "" -#: apps/member/views.py:129 +#: apps/member/views.py:130 #, python-format msgid "Account #%(id)s: %(username)s" msgstr "" -#: apps/note/admin.py:118 apps/note/models/transactions.py:86 +#: apps/note/admin.py:120 apps/note/models/transactions.py:93 msgid "source" msgstr "" -#: apps/note/admin.py:126 apps/note/admin.py:154 -#: apps/note/models/transactions.py:51 apps/note/models/transactions.py:92 +#: apps/note/admin.py:128 apps/note/admin.py:156 +#: apps/note/models/transactions.py:53 apps/note/models/transactions.py:99 msgid "destination" msgstr "" -#: apps/note/apps.py:14 apps/note/models/notes.py:48 +#: apps/note/apps.py:14 apps/note/models/notes.py:54 msgid "note" msgstr "" +#: apps/note/forms.py:49 +msgid "Source and destination must be different." +msgstr "" + #: apps/note/models/notes.py:26 msgid "account balance" msgstr "" @@ -215,142 +219,158 @@ msgid "in centimes, money credited for this instance" msgstr "" #: apps/note/models/notes.py:31 +msgid "last negative date" +msgstr "" + +#: apps/note/models/notes.py:32 +msgid "last time the balance was negative" +msgstr "" + +#: apps/note/models/notes.py:37 msgid "active" msgstr "" -#: apps/note/models/notes.py:34 +#: apps/note/models/notes.py:40 msgid "" "Designates whether this note should be treated as active. Unselect this " "instead of deleting notes." msgstr "" -#: apps/note/models/notes.py:38 +#: apps/note/models/notes.py:44 msgid "display image" msgstr "" -#: apps/note/models/notes.py:43 apps/note/models/transactions.py:95 +#: apps/note/models/notes.py:49 apps/note/models/transactions.py:102 msgid "created at" msgstr "" -#: apps/note/models/notes.py:49 +#: apps/note/models/notes.py:55 msgid "notes" msgstr "" -#: apps/note/models/notes.py:57 +#: apps/note/models/notes.py:63 msgid "Note" msgstr "" -#: apps/note/models/notes.py:67 apps/note/models/notes.py:90 +#: apps/note/models/notes.py:73 apps/note/models/notes.py:97 msgid "This alias is already taken." msgstr "" -#: apps/note/models/notes.py:105 +#: apps/note/models/notes.py:113 msgid "user" msgstr "" -#: apps/note/models/notes.py:109 +#: apps/note/models/notes.py:117 msgid "one's note" msgstr "" -#: apps/note/models/notes.py:110 +#: apps/note/models/notes.py:118 msgid "users note" msgstr "" -#: apps/note/models/notes.py:116 +#: apps/note/models/notes.py:124 #, python-format msgid "%(user)s's note" msgstr "" -#: apps/note/models/notes.py:131 +#: apps/note/models/notes.py:139 msgid "club note" msgstr "" -#: apps/note/models/notes.py:132 +#: apps/note/models/notes.py:140 msgid "clubs notes" msgstr "" -#: apps/note/models/notes.py:138 +#: apps/note/models/notes.py:146 #, python-format msgid "Note of %(club)s club" msgstr "" -#: apps/note/models/notes.py:158 +#: apps/note/models/notes.py:166 msgid "special note" msgstr "" -#: apps/note/models/notes.py:159 +#: apps/note/models/notes.py:167 msgid "special notes" msgstr "" -#: apps/note/models/notes.py:182 +#: apps/note/models/notes.py:190 msgid "Invalid alias" msgstr "" -#: apps/note/models/notes.py:198 +#: apps/note/models/notes.py:206 msgid "alias" msgstr "" -#: apps/note/models/notes.py:199 templates/member/profile_detail.html:33 +#: apps/note/models/notes.py:207 templates/member/profile_detail.html:33 msgid "aliases" msgstr "" -#: apps/note/models/notes.py:225 -msgid "Alias too long." +#: apps/note/models/notes.py:233 +msgid "Alias is too long." msgstr "" -#: apps/note/models/notes.py:236 +#: apps/note/models/notes.py:238 +msgid "An alias with a similar name already exists:" +msgstr "" + +#: apps/note/models/notes.py:246 msgid "You can't delete your main alias." msgstr "" -#: apps/note/models/transactions.py:29 +#: apps/note/models/transactions.py:30 msgid "transaction category" msgstr "" -#: apps/note/models/transactions.py:30 +#: apps/note/models/transactions.py:31 msgid "transaction categories" msgstr "" -#: apps/note/models/transactions.py:54 apps/note/models/transactions.py:102 +#: apps/note/models/transactions.py:47 +msgid "A template with this name already exist" +msgstr "" + +#: apps/note/models/transactions.py:56 apps/note/models/transactions.py:109 msgid "amount" msgstr "" -#: apps/note/models/transactions.py:55 +#: apps/note/models/transactions.py:57 msgid "in centimes" msgstr "" -#: apps/note/models/transactions.py:65 +#: apps/note/models/transactions.py:74 msgid "transaction template" msgstr "" -#: apps/note/models/transactions.py:66 +#: apps/note/models/transactions.py:75 msgid "transaction templates" msgstr "" -#: apps/note/models/transactions.py:99 +#: apps/note/models/transactions.py:106 msgid "quantity" msgstr "" -#: apps/note/models/transactions.py:108 +#: apps/note/models/transactions.py:111 msgid "reason" msgstr "" -#: apps/note/models/transactions.py:112 +#: apps/note/models/transactions.py:115 msgid "valid" msgstr "" -#: apps/note/models/transactions.py:117 +#: apps/note/models/transactions.py:120 msgid "transaction" msgstr "" -#: apps/note/models/transactions.py:118 +#: apps/note/models/transactions.py:121 msgid "transactions" msgstr "" -#: apps/note/models/transactions.py:160 +#: apps/note/models/transactions.py:184 msgid "membership transaction" msgstr "" -#: apps/note/models/transactions.py:161 +#: apps/note/models/transactions.py:185 msgid "membership transactions" msgstr "" @@ -358,15 +378,19 @@ msgstr "" msgid "Transfer money from your account to one or others" msgstr "" -#: note_kfet/settings/base.py:148 +#: apps/note/views.py:138 +msgid "Consommations" +msgstr "" + +#: note_kfet/settings/base.py:155 msgid "German" msgstr "" -#: note_kfet/settings/base.py:149 +#: note_kfet/settings/base.py:156 msgid "English" msgstr "" -#: note_kfet/settings/base.py:150 +#: note_kfet/settings/base.py:157 msgid "French" msgstr "" diff --git a/locale/fr/LC_MESSAGES/django.po b/locale/fr/LC_MESSAGES/django.po index bdf4fc8f..4bd4f5f2 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-02-21 13:50+0100\n" +"POT-Creation-Date: 2020-02-27 17:39+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -19,8 +19,8 @@ msgstr "activité" #: apps/activity/models.py:19 apps/activity/models.py:44 #: apps/member/models.py:60 apps/member/models.py:111 -#: apps/note/models/notes.py:176 apps/note/models/transactions.py:23 -#: apps/note/models/transactions.py:43 templates/member/profile_detail.html:11 +#: apps/note/models/notes.py:184 apps/note/models/transactions.py:24 +#: apps/note/models/transactions.py:44 templates/member/profile_detail.html:11 msgid "name" msgstr "nom" @@ -40,12 +40,12 @@ msgstr "type d'activité" msgid "activity types" msgstr "types d'activité" -#: apps/activity/models.py:48 +#: apps/activity/models.py:48 apps/note/models/transactions.py:69 msgid "description" msgstr "description" -#: apps/activity/models.py:54 apps/note/models/notes.py:152 -#: apps/note/models/transactions.py:60 apps/note/models/transactions.py:104 +#: apps/activity/models.py:54 apps/note/models/notes.py:160 +#: apps/note/models/transactions.py:62 msgid "type" msgstr "type" @@ -143,7 +143,7 @@ msgstr "" "Combien de temps l'adhésion peut durer après le 1er Janvier de l'année " "suivante avant que les adhérents peuvent renouveler leur adhésion." -#: apps/member/models.py:93 apps/note/models/notes.py:127 +#: apps/member/models.py:93 apps/note/models/notes.py:135 msgid "club" msgstr "club" @@ -183,28 +183,32 @@ msgstr "adhésions" msgid "Update Profile" msgstr "Modifier le profil" -#: apps/member/views.py:79 apps/note/models/notes.py:229 +#: apps/member/views.py:79 msgid "An alias with a similar name already exists." msgstr "Un alias avec un nom similaire existe déjà." -#: apps/member/views.py:129 +#: apps/member/views.py:130 #, python-format msgid "Account #%(id)s: %(username)s" msgstr "Compte n°%(id)s : %(username)s" -#: apps/note/admin.py:118 apps/note/models/transactions.py:86 +#: apps/note/admin.py:120 apps/note/models/transactions.py:93 msgid "source" msgstr "source" -#: apps/note/admin.py:126 apps/note/admin.py:154 -#: apps/note/models/transactions.py:51 apps/note/models/transactions.py:92 +#: apps/note/admin.py:128 apps/note/admin.py:156 +#: apps/note/models/transactions.py:53 apps/note/models/transactions.py:99 msgid "destination" msgstr "destination" -#: apps/note/apps.py:14 apps/note/models/notes.py:48 +#: apps/note/apps.py:14 apps/note/models/notes.py:54 msgid "note" msgstr "note" +#: apps/note/forms.py:49 +msgid "Source and destination must be different." +msgstr "La source et la destination doivent être différentes." + #: apps/note/models/notes.py:26 msgid "account balance" msgstr "solde du compte" @@ -214,143 +218,160 @@ msgid "in centimes, money credited for this instance" msgstr "en centimes, argent crédité pour cette instance" #: apps/note/models/notes.py:31 +msgid "last negative date" +msgstr "dernier date de négatif" + +#: apps/note/models/notes.py:32 +msgid "last time the balance was negative" +msgstr "dernier instant où la note était en négatif" + +#: apps/note/models/notes.py:37 msgid "active" msgstr "actif" -#: apps/note/models/notes.py:34 +#: apps/note/models/notes.py:40 msgid "" "Designates whether this note should be treated as active. Unselect this " "instead of deleting notes." msgstr "" "Indique si la note est active. Désactiver cela plutôt que supprimer la note." -#: apps/note/models/notes.py:38 +#: apps/note/models/notes.py:44 msgid "display image" msgstr "image affichée" -#: apps/note/models/notes.py:43 apps/note/models/transactions.py:95 +#: apps/note/models/notes.py:49 apps/note/models/transactions.py:102 msgid "created at" msgstr "créée le" -#: apps/note/models/notes.py:49 +#: apps/note/models/notes.py:55 msgid "notes" msgstr "notes" -#: apps/note/models/notes.py:57 +#: apps/note/models/notes.py:63 msgid "Note" msgstr "Note" -#: apps/note/models/notes.py:67 apps/note/models/notes.py:90 +#: apps/note/models/notes.py:73 apps/note/models/notes.py:97 msgid "This alias is already taken." msgstr "Cet alias est déjà pris." -#: apps/note/models/notes.py:105 +#: apps/note/models/notes.py:113 msgid "user" msgstr "utilisateur" -#: apps/note/models/notes.py:109 +#: apps/note/models/notes.py:117 msgid "one's note" msgstr "note d'un utilisateur" -#: apps/note/models/notes.py:110 +#: apps/note/models/notes.py:118 msgid "users note" msgstr "notes des utilisateurs" -#: apps/note/models/notes.py:116 +#: apps/note/models/notes.py:124 #, python-format msgid "%(user)s's note" msgstr "Note de %(user)s" -#: apps/note/models/notes.py:131 +#: apps/note/models/notes.py:139 msgid "club note" msgstr "note d'un club" -#: apps/note/models/notes.py:132 +#: apps/note/models/notes.py:140 msgid "clubs notes" msgstr "notes des clubs" -#: apps/note/models/notes.py:138 +#: apps/note/models/notes.py:146 #, python-format msgid "Note of %(club)s club" msgstr "Note du club %(club)s" -#: apps/note/models/notes.py:158 +#: apps/note/models/notes.py:166 msgid "special note" msgstr "note spéciale" -#: apps/note/models/notes.py:159 +#: apps/note/models/notes.py:167 msgid "special notes" msgstr "notes spéciales" -#: apps/note/models/notes.py:182 +#: apps/note/models/notes.py:190 msgid "Invalid alias" msgstr "Alias invalide" -#: apps/note/models/notes.py:198 +#: apps/note/models/notes.py:206 msgid "alias" msgstr "alias" -#: apps/note/models/notes.py:199 templates/member/profile_detail.html:33 +#: apps/note/models/notes.py:207 templates/member/profile_detail.html:33 msgid "aliases" msgstr "alias" -#: apps/note/models/notes.py:225 -msgid "Alias too long." +#: apps/note/models/notes.py:233 +msgid "Alias is too long." msgstr "L'alias est trop long." -#: apps/note/models/notes.py:236 +#: apps/note/models/notes.py:238 +msgid "An alias with a similar name already exists:" +msgstr "Un alias avec un nom similaire existe déjà." + +#: apps/note/models/notes.py:246 msgid "You can't delete your main alias." msgstr "Vous ne pouvez pas supprimer votre alias principal." -#: apps/note/models/transactions.py:29 +#: apps/note/models/transactions.py:30 msgid "transaction category" msgstr "catégorie de transaction" -#: apps/note/models/transactions.py:30 +#: apps/note/models/transactions.py:31 msgid "transaction categories" msgstr "catégories de transaction" -#: apps/note/models/transactions.py:54 apps/note/models/transactions.py:102 +#: apps/note/models/transactions.py:47 +#, fuzzy +msgid "A template with this name already exist" +msgstr "Un modèle de transaction avec un nom similaire existe déjà." + +#: apps/note/models/transactions.py:56 apps/note/models/transactions.py:109 msgid "amount" msgstr "montant" -#: apps/note/models/transactions.py:55 +#: apps/note/models/transactions.py:57 msgid "in centimes" msgstr "en centimes" -#: apps/note/models/transactions.py:65 +#: apps/note/models/transactions.py:74 msgid "transaction template" msgstr "modèle de transaction" -#: apps/note/models/transactions.py:66 +#: apps/note/models/transactions.py:75 msgid "transaction templates" msgstr "modèles de transaction" -#: apps/note/models/transactions.py:99 +#: apps/note/models/transactions.py:106 msgid "quantity" msgstr "quantité" -#: apps/note/models/transactions.py:108 +#: apps/note/models/transactions.py:111 msgid "reason" msgstr "raison" -#: apps/note/models/transactions.py:112 +#: apps/note/models/transactions.py:115 msgid "valid" msgstr "valide" -#: apps/note/models/transactions.py:117 +#: apps/note/models/transactions.py:120 msgid "transaction" msgstr "transaction" -#: apps/note/models/transactions.py:118 +#: apps/note/models/transactions.py:121 msgid "transactions" msgstr "transactions" -#: apps/note/models/transactions.py:160 +#: apps/note/models/transactions.py:184 msgid "membership transaction" msgstr "transaction d'adhésion" -#: apps/note/models/transactions.py:161 +#: apps/note/models/transactions.py:185 msgid "membership transactions" msgstr "transactions d'adhésion" @@ -358,15 +379,19 @@ msgstr "transactions d'adhésion" msgid "Transfer money from your account to one or others" msgstr "Transfert d'argent de ton compte vers un ou plusieurs autres" -#: note_kfet/settings/base.py:148 +#: apps/note/views.py:138 +msgid "Consommations" +msgstr "transactions" + +#: note_kfet/settings/base.py:155 msgid "German" msgstr "" -#: note_kfet/settings/base.py:149 +#: note_kfet/settings/base.py:156 msgid "English" msgstr "" -#: note_kfet/settings/base.py:150 +#: note_kfet/settings/base.py:157 msgid "French" msgstr "" @@ -408,13 +433,13 @@ msgstr "" #: templates/member/profile_detail.html:14 msgid "username" -msgstr "nom d'utilisateur" +msgstr "" #: templates/member/profile_detail.html:17 #, fuzzy #| msgid "Change password" msgid "password" -msgstr "Changer le mot de passe" +msgstr "" #: templates/member/profile_detail.html:20 msgid "Change password" @@ -424,6 +449,10 @@ msgstr "Changer le mot de passe" msgid "Manage auth token" msgstr "Gérer les jetons d'authentification" +#: templates/member/profile_detail.html:51 +msgid "Transaction history" +msgstr "Historique des transactions" + #: templates/member/profile_detail.html:54 msgid "View my memberships" msgstr "Voir mes adhésions" diff --git a/templates/member/club_detail.html b/templates/member/club_detail.html index 1afc5c16..38f87812 100644 --- a/templates/member/club_detail.html +++ b/templates/member/club_detail.html @@ -48,7 +48,7 @@
diff --git a/templates/member/profile_detail.html b/templates/member/profile_detail.html index 1f60414b..48fb32ae 100644 --- a/templates/member/profile_detail.html +++ b/templates/member/profile_detail.html @@ -64,7 +64,7 @@