diff --git a/apps/note/forms.py b/apps/note/forms.py index bc479e20..fe81783e 100644 --- a/apps/note/forms.py +++ b/apps/note/forms.py @@ -3,10 +3,11 @@ from django import forms from django.contrib.contenttypes.models import ContentType +from django.forms import CheckboxSelectMultiple from django.utils.translation import gettext_lazy as _ -from note_kfet.inputs import Autocomplete, AmountInput +from note_kfet.inputs import Autocomplete, AmountInput, DateTimePickerInput -from .models import TransactionTemplate, NoteClub +from .models import TransactionTemplate, NoteClub, Alias class ImageForm(forms.Form): @@ -38,3 +39,80 @@ class TransactionTemplateForm(forms.ModelForm): ), 'amount': AmountInput(), } + + +class SearchTransactionForm(forms.Form): + source = forms.ModelChoiceField( + queryset=Alias.objects.all(), + label=_("Source"), + required=False, + widget=Autocomplete( + Alias, + resetable=True, + attrs={ + 'api_url': '/api/note/alias/', + 'placeholder': 'Note ...', + }, + ), + ) + + destination = forms.ModelChoiceField( + queryset=Alias.objects.all(), + label=_("Destination"), + required=False, + widget=Autocomplete( + Alias, + resetable=True, + attrs={ + 'api_url': '/api/note/alias/', + 'placeholder': 'Note ...', + }, + ), + ) + + type = forms.ModelMultipleChoiceField( + queryset=ContentType.objects.filter(app_label="note", model__endswith="transaction"), + initial=ContentType.objects.filter(app_label="note", model__endswith="transaction"), + label=_("Type"), + required=False, + widget=CheckboxSelectMultiple(), + ) + + reason = forms.CharField( + label=_("Reason"), + required=False, + ) + + valid = forms.BooleanField( + label=_("Valid"), + initial=False, + required=False, + ) + + amount_gte = forms.Field( + label=_("Total amount greater than"), + initial=0, + required=False, + widget=AmountInput(), + ) + + amount_lte = forms.Field( + initial=2 ** 31 - 1, + label=_("Total amount less than"), + required=False, + widget=AmountInput(), + ) + + created_after = forms.Field( + label=_("Created after"), + initial="2000-01-01 00:00", + required=False, + widget=DateTimePickerInput(), + ) + + created_before = forms.Field( + label=_("Created before"), + initial="2042-12-31 21:42", + required=False, + widget=DateTimePickerInput(), + ) diff --git a/apps/note/models/transactions.py b/apps/note/models/transactions.py index 6eab05ee..69306b71 100644 --- a/apps/note/models/transactions.py +++ b/apps/note/models/transactions.py @@ -243,6 +243,7 @@ class RecurrentTransaction(Transaction): TransactionTemplate, on_delete=models.PROTECT, ) + category = models.ForeignKey( TemplateCategory, on_delete=models.PROTECT, @@ -252,6 +253,10 @@ class RecurrentTransaction(Transaction): def type(self): return _('Template') + class Meta: + verbose_name = _("recurrent transaction") + verbose_name_plural = _("recurrent transactions") + class SpecialTransaction(Transaction): """ @@ -290,6 +295,10 @@ class SpecialTransaction(Transaction): raise(ValidationError(_("A special transaction is only possible between a" " Note associated to a payment method and a User or a Club"))) + class Meta: + verbose_name = _("Special transaction") + verbose_name_plural = _("Special transactions") + class MembershipTransaction(Transaction): """ diff --git a/apps/note/urls.py b/apps/note/urls.py index 9d6af317..c5662f2c 100644 --- a/apps/note/urls.py +++ b/apps/note/urls.py @@ -12,4 +12,5 @@ urlpatterns = [ path('buttons/update//', views.TransactionTemplateUpdateView.as_view(), name='template_update'), path('buttons/', views.TransactionTemplateListView.as_view(), name='template_list'), path('consos/', views.ConsoView.as_view(), name='consos'), + path('transactions//', views.TransactionSearchView.as_view(), name='transactions'), ] diff --git a/apps/note/views.py b/apps/note/views.py index ad2b2a99..3524a080 100644 --- a/apps/note/views.py +++ b/apps/note/views.py @@ -5,9 +5,9 @@ import json from django.conf import settings from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.contenttypes.models import ContentType -from django.db.models import Q +from django.db.models import Q, F from django.utils.translation import gettext_lazy as _ -from django.views.generic import CreateView, UpdateView +from django.views.generic import CreateView, UpdateView, DetailView from django_tables2 import SingleTableView from django.urls import reverse_lazy @@ -16,8 +16,8 @@ from note_kfet.inputs import AmountInput from permission.backends import PermissionBackend from permission.views import ProtectQuerysetMixin -from .forms import TransactionTemplateForm -from .models import TemplateCategory, Transaction, TransactionTemplate, RecurrentTransaction, NoteSpecial +from .forms import TransactionTemplateForm, SearchTransactionForm +from .models import TemplateCategory, Transaction, TransactionTemplate, RecurrentTransaction, NoteSpecial, Note from .models.transactions import SpecialTransaction from .tables import HistoryTable, ButtonTable @@ -171,3 +171,51 @@ class ConsoView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableView): context['no_cache'] = True return context + + +class TransactionSearchView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView): + model = Note + context_object_name = "note" + template_name = "note/search_transactions.html" + extra_context = {"title": _("Search transactions")} + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + + form = SearchTransactionForm(data=self.request.GET if self.request.GET else None) + context["form"] = form + + form.full_clean() + if form.is_valid(): + data = form.cleaned_data + else: + data = {} + + transactions = Transaction.objects.annotate(total_amount=F("quantity") * F("amount")).filter( + PermissionBackend.filter_queryset(self.request.user, Transaction, "view"))\ + .filter(Q(source=self.object) | Q(destination=self.object)).order_by('-created_at') + + if "source" in data and data["source"]: + transactions = transactions.filter(source_id=data["source"].note_id) + if "destination" in data and data["destination"]: + transactions = transactions.filter(destination_id=data["destination"].note_id) + if "type" in data and data["type"]: + transactions = transactions.filter(polymorphic_ctype__in=data["type"]) + if "reason" in data and data["reason"]: + transactions = transactions.filter(reason__iregex=data["reason"]) + if "valid" in data and data["valid"]: + transactions = transactions.filter(valid=data["valid"]) + if "amount_gte" in data and data["amount_gte"]: + transactions = transactions.filter(total_amount__gte=data["amount_gte"]) + if "amount_lte" in data and data["amount_lte"]: + transactions = transactions.filter(total_amount__lte=data["amount_lte"]) + if "created_after" in data and data["created_after"]: + transactions = transactions.filter(created_at__gte=data["created_after"]) + if "created_before" in data and data["created_before"]: + transactions = transactions.filter(created_at__lte=data["created_before"]) + + table = HistoryTable(transactions) + table.paginate(per_page=20) + context["table"] = table + + return context diff --git a/apps/wei/views.py b/apps/wei/views.py index 8a95c72a..ed76cc0f 100644 --- a/apps/wei/views.py +++ b/apps/wei/views.py @@ -130,7 +130,7 @@ class WEIDetailView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView): context["my_registration"] = my_registration buses = Bus.objects.filter(PermissionBackend.filter_queryset(self.request.user, Bus, "view")) \ - .filter(wei=self.object).annotate(count=Count("memberships")) + .filter(wei=self.object).annotate(count=Count("memberships")).order_by("name") bus_table = BusTable(data=buses, prefix="bus-") context['buses'] = bus_table @@ -589,9 +589,6 @@ class WEIUpdateRegistrationView(ProtectQuerysetMixin, LoginRequiredMixin, Update form_class = WEIRegistrationForm extra_context = {"title": _("Update WEI Registration")} - def get_queryset(self, **kwargs): - return WEIRegistration.objects - def dispatch(self, request, *args, **kwargs): wei = self.get_object().wei today = date.today() diff --git a/locale/de/LC_MESSAGES/django.po b/locale/de/LC_MESSAGES/django.po index b094a5ac..3f207ceb 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-08-03 12:35+0200\n" +"POT-Creation-Date: 2020-08-03 18:38+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -46,7 +46,7 @@ msgstr "" #: apps/activity/models.py:24 apps/activity/models.py:49 #: apps/member/models.py:158 apps/note/models/notes.py:212 #: apps/note/models/transactions.py:25 apps/note/models/transactions.py:45 -#: apps/note/models/transactions.py:263 apps/permission/models.py:339 +#: apps/note/models/transactions.py:268 apps/permission/models.py:339 #: apps/wei/models.py:65 apps/wei/models.py:117 #: templates/member/club_info.html:13 templates/member/profile_info.html:14 #: templates/registration/future_profile_detail.html:16 @@ -182,16 +182,16 @@ msgstr "" msgid "remove" msgstr "" -#: apps/activity/tables.py:75 apps/treasury/models.py:141 +#: apps/activity/tables.py:75 apps/note/forms.py:76 apps/treasury/models.py:141 msgid "Type" msgstr "" -#: apps/activity/tables.py:77 apps/member/forms.py:102 +#: apps/activity/tables.py:77 apps/member/forms.py:103 #: apps/registration/forms.py:70 apps/treasury/forms.py:120 msgid "Last name" msgstr "" -#: apps/activity/tables.py:79 apps/member/forms.py:107 +#: apps/activity/tables.py:79 apps/member/forms.py:108 #: apps/registration/forms.py:75 apps/treasury/forms.py:122 #: templates/note/transaction_form.html:129 msgid "First name" @@ -225,7 +225,7 @@ msgstr "" msgid "Invite guest to the activity \"{}\"" msgstr "" -#: apps/activity/views.py:171 +#: apps/activity/views.py:181 msgid "Entry for activity \"{}\"" msgstr "" @@ -313,45 +313,45 @@ msgstr "" msgid "member" msgstr "" -#: apps/member/forms.py:58 apps/member/views.py:82 +#: apps/member/forms.py:59 apps/member/views.py:82 #: apps/registration/forms.py:28 msgid "An alias with a similar name already exists." msgstr "" -#: apps/member/forms.py:81 apps/registration/forms.py:50 +#: apps/member/forms.py:82 apps/registration/forms.py:50 msgid "Inscription paid by Société Générale" msgstr "" -#: apps/member/forms.py:83 apps/registration/forms.py:52 +#: apps/member/forms.py:84 apps/registration/forms.py:52 msgid "Check this case is the Société Générale paid the inscription." msgstr "" -#: apps/member/forms.py:88 apps/registration/forms.py:57 +#: apps/member/forms.py:89 apps/registration/forms.py:57 msgid "Credit type" msgstr "" -#: apps/member/forms.py:89 apps/registration/forms.py:58 +#: apps/member/forms.py:90 apps/registration/forms.py:58 msgid "No credit" msgstr "" -#: apps/member/forms.py:91 +#: apps/member/forms.py:92 msgid "You can credit the note of the user." msgstr "" -#: apps/member/forms.py:95 apps/registration/forms.py:63 +#: apps/member/forms.py:96 apps/registration/forms.py:63 msgid "Credit amount" msgstr "" -#: apps/member/forms.py:112 apps/registration/forms.py:80 +#: apps/member/forms.py:113 apps/registration/forms.py:80 #: apps/treasury/forms.py:124 templates/note/transaction_form.html:135 msgid "Bank" msgstr "" -#: apps/member/forms.py:139 +#: apps/member/forms.py:140 msgid "User" msgstr "" -#: apps/member/forms.py:153 +#: apps/member/forms.py:154 msgid "Roles" msgstr "" @@ -540,7 +540,7 @@ msgstr "" msgid "membership ends on" msgstr "" -#: apps/member/models.py:310 apps/member/views.py:535 apps/wei/views.py:795 +#: apps/member/models.py:310 apps/member/views.py:535 apps/wei/views.py:793 msgid "User is not a member of the parent club" msgstr "" @@ -620,7 +620,7 @@ msgstr "" msgid "Add new member to the club" msgstr "" -#: apps/member/views.py:530 apps/wei/views.py:786 +#: apps/member/views.py:530 apps/wei/views.py:784 msgid "" "This user don't have enough money to join this club, and can't have a " "negative balance." @@ -662,14 +662,46 @@ msgstr "" msgid "amount" msgstr "" -#: apps/note/forms.py:14 +#: apps/note/forms.py:15 msgid "select an image" msgstr "" -#: apps/note/forms.py:15 +#: apps/note/forms.py:16 msgid "Maximal size: 2MB" msgstr "" +#: apps/note/forms.py:47 +msgid "Source" +msgstr "" + +#: apps/note/forms.py:61 +msgid "Destination" +msgstr "" + +#: apps/note/forms.py:82 templates/note/transaction_form.html:104 +msgid "Reason" +msgstr "" + +#: apps/note/forms.py:87 apps/treasury/tables.py:117 +msgid "Valid" +msgstr "" + +#: apps/note/forms.py:93 +msgid "Total amount greater than" +msgstr "" + +#: apps/note/forms.py:101 +msgid "Total amount less than" +msgstr "" + +#: apps/note/forms.py:107 +msgid "Created after" +msgstr "" + +#: apps/note/forms.py:114 +msgid "Created before" +msgstr "" + #: apps/note/models/notes.py:29 msgid "account balance" msgstr "" @@ -842,39 +874,55 @@ msgstr "" msgid "Transfer" msgstr "" -#: apps/note/models/transactions.py:253 +#: apps/note/models/transactions.py:254 msgid "Template" msgstr "" -#: apps/note/models/transactions.py:268 -msgid "first_name" +#: apps/note/models/transactions.py:257 +msgid "recurrent transaction" +msgstr "" + +#: apps/note/models/transactions.py:258 +msgid "recurrent transactions" msgstr "" #: apps/note/models/transactions.py:273 +msgid "first_name" +msgstr "" + +#: apps/note/models/transactions.py:278 msgid "bank" msgstr "" -#: apps/note/models/transactions.py:279 +#: apps/note/models/transactions.py:284 #: templates/activity/activity_entry.html:17 #: templates/note/transaction_form.html:20 msgid "Credit" msgstr "" -#: apps/note/models/transactions.py:279 templates/note/transaction_form.html:24 +#: apps/note/models/transactions.py:284 templates/note/transaction_form.html:24 msgid "Debit" msgstr "" -#: apps/note/models/transactions.py:290 +#: apps/note/models/transactions.py:295 msgid "" "A special transaction is only possible between a Note associated to a " "payment method and a User or a Club" msgstr "" -#: apps/note/models/transactions.py:307 apps/note/models/transactions.py:312 +#: apps/note/models/transactions.py:299 +msgid "Special transaction" +msgstr "" + +#: apps/note/models/transactions.py:300 +msgid "Special transactions" +msgstr "" + +#: apps/note/models/transactions.py:316 apps/note/models/transactions.py:321 msgid "membership transaction" msgstr "" -#: apps/note/models/transactions.py:308 apps/treasury/models.py:228 +#: apps/note/models/transactions.py:317 apps/treasury/models.py:228 msgid "membership transactions" msgstr "" @@ -903,26 +951,30 @@ msgstr "" msgid "Edit" msgstr "" -#: apps/note/views.py:33 +#: apps/note/views.py:35 msgid "Transfer money" msgstr "" -#: apps/note/views.py:69 +#: apps/note/views.py:75 msgid "Create new button" msgstr "" -#: apps/note/views.py:78 +#: apps/note/views.py:84 msgid "Search button" msgstr "" -#: apps/note/views.py:101 +#: apps/note/views.py:107 msgid "Update button" msgstr "" -#: apps/note/views.py:138 templates/base.html:94 +#: apps/note/views.py:144 templates/base.html:94 msgid "Consumptions" msgstr "" +#: apps/note/views.py:180 +msgid "Search transactions" +msgstr "" + #: apps/permission/models.py:99 #, python-brace-format msgid "Can {type} {model}.{field} in {query}" @@ -1288,10 +1340,6 @@ msgstr "" msgid "Remove" msgstr "" -#: apps/treasury/tables.py:117 -msgid "Valid" -msgstr "" - #: apps/treasury/tables.py:124 msgid "Yes" msgstr "" @@ -1342,37 +1390,37 @@ msgstr "" msgid "WEI" msgstr "" -#: apps/wei/forms/registration.py:47 apps/wei/models.py:112 +#: apps/wei/forms/registration.py:48 apps/wei/models.py:112 #: apps/wei/models.py:297 msgid "bus" msgstr "" -#: apps/wei/forms/registration.py:48 +#: apps/wei/forms/registration.py:49 msgid "" "This choice is not definitive. The WEI organizers are free to attribute for " "you a bus and a team, in particular if you are a free eletron." msgstr "" -#: apps/wei/forms/registration.py:54 +#: apps/wei/forms/registration.py:56 msgid "Team" msgstr "" -#: apps/wei/forms/registration.py:56 +#: apps/wei/forms/registration.py:58 msgid "" "Leave this field empty if you won't be in a team (staff, bus chief, free " "electron)" msgstr "" -#: apps/wei/forms/registration.py:61 apps/wei/forms/registration.py:67 +#: apps/wei/forms/registration.py:64 apps/wei/forms/registration.py:74 #: apps/wei/models.py:147 msgid "WEI Roles" msgstr "" -#: apps/wei/forms/registration.py:62 +#: apps/wei/forms/registration.py:65 msgid "Select the roles that you are interested in." msgstr "" -#: apps/wei/forms/registration.py:72 +#: apps/wei/forms/registration.py:81 msgid "This team doesn't belong to the given bus." msgstr "" @@ -1618,7 +1666,7 @@ msgstr "" msgid "Register 1A" msgstr "" -#: apps/wei/views.py:489 apps/wei/views.py:559 +#: apps/wei/views.py:489 apps/wei/views.py:560 msgid "This user is already registered to this WEI." msgstr "" @@ -1636,31 +1684,31 @@ msgstr "" msgid "Register 2A+" msgstr "" -#: apps/wei/views.py:541 apps/wei/views.py:629 +#: apps/wei/views.py:542 apps/wei/views.py:627 msgid "You already opened an account in the Société générale." msgstr "" -#: apps/wei/views.py:589 +#: apps/wei/views.py:590 msgid "Update WEI Registration" msgstr "" -#: apps/wei/views.py:679 +#: apps/wei/views.py:677 msgid "Delete WEI registration" msgstr "" -#: apps/wei/views.py:690 +#: apps/wei/views.py:688 msgid "You don't have the right to delete this WEI registration." msgstr "" -#: apps/wei/views.py:709 +#: apps/wei/views.py:707 msgid "Validate WEI registration" msgstr "" -#: apps/wei/views.py:790 +#: apps/wei/views.py:788 msgid "This user didn't give her/his caution check." msgstr "" -#: apps/wei/views.py:827 apps/wei/views.py:880 apps/wei/views.py:890 +#: apps/wei/views.py:825 apps/wei/views.py:878 apps/wei/views.py:888 #: templates/wei/survey.html:12 templates/wei/survey_closed.html:12 #: templates/wei/survey_end.html:12 msgid "Survey WEI" @@ -1822,6 +1870,10 @@ msgstr "" msgid "Add alias" msgstr "" +#: templates/member/autocomplete_model.html:11 +msgid "Reset" +msgstr "" + #: templates/member/club_info.html:17 msgid "Club Parent" msgstr "" @@ -1990,10 +2042,6 @@ msgstr "" msgid "Action" msgstr "" -#: templates/note/transaction_form.html:104 -msgid "Reason" -msgstr "" - #: templates/note/transaction_form.html:113 msgid "Transfer type" msgstr "" diff --git a/locale/fr/LC_MESSAGES/django.po b/locale/fr/LC_MESSAGES/django.po index 511b3efb..8fedb67a 100644 --- a/locale/fr/LC_MESSAGES/django.po +++ b/locale/fr/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-08-03 12:35+0200\n" +"POT-Creation-Date: 2020-08-03 18:38+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -47,7 +47,7 @@ msgstr "Vous ne pouvez pas inviter plus de 3 personnes à cette activité." #: apps/activity/models.py:24 apps/activity/models.py:49 #: apps/member/models.py:158 apps/note/models/notes.py:212 #: apps/note/models/transactions.py:25 apps/note/models/transactions.py:45 -#: apps/note/models/transactions.py:263 apps/permission/models.py:339 +#: apps/note/models/transactions.py:268 apps/permission/models.py:339 #: apps/wei/models.py:65 apps/wei/models.py:117 #: templates/member/club_info.html:13 templates/member/profile_info.html:14 #: templates/registration/future_profile_detail.html:16 @@ -183,16 +183,16 @@ msgstr "Entré le " msgid "remove" msgstr "supprimer" -#: apps/activity/tables.py:75 apps/treasury/models.py:141 +#: apps/activity/tables.py:75 apps/note/forms.py:76 apps/treasury/models.py:141 msgid "Type" msgstr "Type" -#: apps/activity/tables.py:77 apps/member/forms.py:102 +#: apps/activity/tables.py:77 apps/member/forms.py:103 #: apps/registration/forms.py:70 apps/treasury/forms.py:120 msgid "Last name" msgstr "Nom de famille" -#: apps/activity/tables.py:79 apps/member/forms.py:107 +#: apps/activity/tables.py:79 apps/member/forms.py:108 #: apps/registration/forms.py:75 apps/treasury/forms.py:122 #: templates/note/transaction_form.html:129 msgid "First name" @@ -226,7 +226,7 @@ msgstr "Modifier l'activité" msgid "Invite guest to the activity \"{}\"" msgstr "Invitation pour l'activité « {} »" -#: apps/activity/views.py:171 +#: apps/activity/views.py:181 msgid "Entry for activity \"{}\"" msgstr "Entrées pour l'activité « {} »" @@ -314,45 +314,45 @@ msgstr "cotisation" msgid "member" msgstr "adhérent" -#: apps/member/forms.py:58 apps/member/views.py:82 +#: apps/member/forms.py:59 apps/member/views.py:82 #: apps/registration/forms.py:28 msgid "An alias with a similar name already exists." msgstr "Un alias avec un nom similaire existe déjà." -#: apps/member/forms.py:81 apps/registration/forms.py:50 +#: apps/member/forms.py:82 apps/registration/forms.py:50 msgid "Inscription paid by Société Générale" msgstr "Inscription payée par la Société générale" -#: apps/member/forms.py:83 apps/registration/forms.py:52 +#: apps/member/forms.py:84 apps/registration/forms.py:52 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:88 apps/registration/forms.py:57 +#: apps/member/forms.py:89 apps/registration/forms.py:57 msgid "Credit type" msgstr "Type de rechargement" -#: apps/member/forms.py:89 apps/registration/forms.py:58 +#: apps/member/forms.py:90 apps/registration/forms.py:58 msgid "No credit" msgstr "Pas de rechargement" -#: apps/member/forms.py:91 +#: apps/member/forms.py:92 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:95 apps/registration/forms.py:63 +#: apps/member/forms.py:96 apps/registration/forms.py:63 msgid "Credit amount" msgstr "Montant à créditer" -#: apps/member/forms.py:112 apps/registration/forms.py:80 +#: apps/member/forms.py:113 apps/registration/forms.py:80 #: apps/treasury/forms.py:124 templates/note/transaction_form.html:135 msgid "Bank" msgstr "Banque" -#: apps/member/forms.py:139 +#: apps/member/forms.py:140 msgid "User" msgstr "Utilisateur" -#: apps/member/forms.py:153 +#: apps/member/forms.py:154 msgid "Roles" msgstr "Rôles" @@ -545,7 +545,7 @@ msgstr "l'adhésion commence le" msgid "membership ends on" msgstr "l'adhésion finit le" -#: apps/member/models.py:310 apps/member/views.py:535 apps/wei/views.py:795 +#: apps/member/models.py:310 apps/member/views.py:535 apps/wei/views.py:793 msgid "User is not a member of the parent club" msgstr "L'utilisateur n'est pas membre du club parent" @@ -625,7 +625,7 @@ msgstr "Modifier le club" msgid "Add new member to the club" msgstr "Ajouter un nouveau membre au club" -#: apps/member/views.py:530 apps/wei/views.py:786 +#: apps/member/views.py:530 apps/wei/views.py:784 msgid "" "This user don't have enough money to join this club, and can't have a " "negative balance." @@ -669,14 +669,46 @@ msgstr "destination" msgid "amount" msgstr "montant" -#: apps/note/forms.py:14 +#: apps/note/forms.py:15 msgid "select an image" msgstr "Choisissez une image" -#: apps/note/forms.py:15 +#: apps/note/forms.py:16 msgid "Maximal size: 2MB" msgstr "Taille maximale : 2 Mo" +#: apps/note/forms.py:47 +msgid "Source" +msgstr "Source" + +#: apps/note/forms.py:61 +msgid "Destination" +msgstr "Destination" + +#: apps/note/forms.py:82 templates/note/transaction_form.html:104 +msgid "Reason" +msgstr "Raison" + +#: apps/note/forms.py:87 apps/treasury/tables.py:117 +msgid "Valid" +msgstr "Valide" + +#: apps/note/forms.py:93 +msgid "Total amount greater than" +msgstr "Montant total supérieur à" + +#: apps/note/forms.py:101 +msgid "Total amount less than" +msgstr "Montant total inférieur à" + +#: apps/note/forms.py:107 +msgid "Created after" +msgstr "Créé après" + +#: apps/note/forms.py:114 +msgid "Created before" +msgstr "Créé avant" + #: apps/note/models/notes.py:29 msgid "account balance" msgstr "solde du compte" @@ -805,11 +837,11 @@ msgstr "mis en avant" #: apps/note/models/transactions.py:87 msgid "transaction template" -msgstr "modèle de transaction" +msgstr "Modèle de transaction" #: apps/note/models/transactions.py:88 msgid "transaction templates" -msgstr "modèles de transaction" +msgstr "Modèles de transaction" #: apps/note/models/transactions.py:112 apps/note/models/transactions.py:125 #: apps/note/tables.py:35 apps/note/tables.py:44 @@ -830,12 +862,12 @@ msgstr "Motif d'invalidité" #: apps/note/models/transactions.py:159 msgid "transaction" -msgstr "transaction" +msgstr "Transaction" #: apps/note/models/transactions.py:160 #: templates/treasury/sogecredit_detail.html:22 msgid "transactions" -msgstr "transactions" +msgstr "Transactions" #: apps/note/models/transactions.py:175 msgid "" @@ -852,29 +884,37 @@ msgstr "" msgid "Transfer" msgstr "Virement" -#: apps/note/models/transactions.py:253 +#: apps/note/models/transactions.py:254 msgid "Template" msgstr "Bouton" -#: apps/note/models/transactions.py:268 +#: apps/note/models/transactions.py:257 +msgid "recurrent transaction" +msgstr "Transaction issue de bouton" + +#: apps/note/models/transactions.py:258 +msgid "recurrent transactions" +msgstr "Transactions issues de boutons" + +#: apps/note/models/transactions.py:273 msgid "first_name" msgstr "prénom" -#: apps/note/models/transactions.py:273 +#: apps/note/models/transactions.py:278 msgid "bank" msgstr "banque" -#: apps/note/models/transactions.py:279 +#: apps/note/models/transactions.py:284 #: templates/activity/activity_entry.html:17 #: templates/note/transaction_form.html:20 msgid "Credit" msgstr "Crédit" -#: apps/note/models/transactions.py:279 templates/note/transaction_form.html:24 +#: apps/note/models/transactions.py:284 templates/note/transaction_form.html:24 msgid "Debit" msgstr "Débit" -#: apps/note/models/transactions.py:290 +#: apps/note/models/transactions.py:295 msgid "" "A special transaction is only possible between a Note associated to a " "payment method and a User or a Club" @@ -882,11 +922,19 @@ msgstr "" "Une transaction spéciale n'est possible que entre une note associée à un " "mode de paiement et un utilisateur ou un club." -#: apps/note/models/transactions.py:307 apps/note/models/transactions.py:312 +#: apps/note/models/transactions.py:299 +msgid "Special transaction" +msgstr "Transaction de crédit/retrait" + +#: apps/note/models/transactions.py:300 +msgid "Special transactions" +msgstr "Transactions de crédit/retrait" + +#: apps/note/models/transactions.py:316 apps/note/models/transactions.py:321 msgid "membership transaction" msgstr "Transaction d'adhésion" -#: apps/note/models/transactions.py:308 apps/treasury/models.py:228 +#: apps/note/models/transactions.py:317 apps/treasury/models.py:228 msgid "membership transactions" msgstr "Transactions d'adhésion" @@ -915,26 +963,30 @@ msgstr "Supprimer" msgid "Edit" msgstr "Éditer" -#: apps/note/views.py:33 +#: apps/note/views.py:35 msgid "Transfer money" msgstr "Transférer de l'argent" -#: apps/note/views.py:69 +#: apps/note/views.py:75 msgid "Create new button" msgstr "Créer un nouveau bouton" -#: apps/note/views.py:78 +#: apps/note/views.py:84 msgid "Search button" msgstr "Chercher un bouton" -#: apps/note/views.py:101 +#: apps/note/views.py:107 msgid "Update button" msgstr "Modifier le bouton" -#: apps/note/views.py:138 templates/base.html:94 +#: apps/note/views.py:144 templates/base.html:94 msgid "Consumptions" msgstr "Consommations" +#: apps/note/views.py:180 +msgid "Search transactions" +msgstr "Rechercher des transactions" + #: apps/permission/models.py:99 #, python-brace-format msgid "Can {type} {model}.{field} in {query}" @@ -1317,10 +1369,6 @@ msgstr "Ajouter" msgid "Remove" msgstr "supprimer" -#: apps/treasury/tables.py:117 -msgid "Valid" -msgstr "Valide" - #: apps/treasury/tables.py:124 msgid "Yes" msgstr "Oui" @@ -1371,12 +1419,12 @@ msgstr "Gérer les crédits de la Société générale" msgid "WEI" msgstr "WEI" -#: apps/wei/forms/registration.py:47 apps/wei/models.py:112 +#: apps/wei/forms/registration.py:48 apps/wei/models.py:112 #: apps/wei/models.py:297 msgid "bus" msgstr "Bus" -#: apps/wei/forms/registration.py:48 +#: apps/wei/forms/registration.py:49 msgid "" "This choice is not definitive. The WEI organizers are free to attribute for " "you a bus and a team, in particular if you are a free eletron." @@ -1385,11 +1433,11 @@ msgstr "" "attribuer un bus et une équipe, en particulier si vous êtes un électron " "libre." -#: apps/wei/forms/registration.py:54 +#: apps/wei/forms/registration.py:56 msgid "Team" msgstr "Équipe" -#: apps/wei/forms/registration.py:56 +#: apps/wei/forms/registration.py:58 msgid "" "Leave this field empty if you won't be in a team (staff, bus chief, free " "electron)" @@ -1397,16 +1445,16 @@ msgstr "" "Laissez ce champ vide si vous ne serez pas dans une équipe (staff, chef de " "bus ou électron libre)" -#: apps/wei/forms/registration.py:61 apps/wei/forms/registration.py:67 +#: apps/wei/forms/registration.py:64 apps/wei/forms/registration.py:74 #: apps/wei/models.py:147 msgid "WEI Roles" msgstr "Rôles au WEI" -#: apps/wei/forms/registration.py:62 +#: apps/wei/forms/registration.py:65 msgid "Select the roles that you are interested in." msgstr "Sélectionnez les rôles qui vous intéressent." -#: apps/wei/forms/registration.py:72 +#: apps/wei/forms/registration.py:81 msgid "This team doesn't belong to the given bus." msgstr "Cette équipe n'appartient pas à ce bus." @@ -1662,7 +1710,7 @@ msgstr "Inscrire un 1A au WEI" msgid "Register 1A" msgstr "Inscrire un 1A" -#: apps/wei/views.py:489 apps/wei/views.py:559 +#: apps/wei/views.py:489 apps/wei/views.py:560 msgid "This user is already registered to this WEI." msgstr "Cette personne est déjà inscrite au WEI." @@ -1682,31 +1730,31 @@ msgstr "Inscrire un 2A+ au WEI" msgid "Register 2A+" msgstr "Inscrire un 2A+" -#: apps/wei/views.py:541 apps/wei/views.py:629 +#: apps/wei/views.py:542 apps/wei/views.py:627 msgid "You already opened an account in the Société générale." msgstr "Vous avez déjà ouvert un compte auprès de la société générale." -#: apps/wei/views.py:589 +#: apps/wei/views.py:590 msgid "Update WEI Registration" msgstr "Modifier l'inscription WEI" -#: apps/wei/views.py:679 +#: apps/wei/views.py:677 msgid "Delete WEI registration" msgstr "Supprimer l'inscription WEI" -#: apps/wei/views.py:690 +#: apps/wei/views.py:688 msgid "You don't have the right to delete this WEI registration." msgstr "Vous n'avez pas la permission de supprimer cette inscription au WEI." -#: apps/wei/views.py:709 +#: apps/wei/views.py:707 msgid "Validate WEI registration" msgstr "Valider l'inscription WEI" -#: apps/wei/views.py:790 +#: apps/wei/views.py:788 msgid "This user didn't give her/his caution check." msgstr "Cet utilisateur n'a pas donné son chèque de caution." -#: apps/wei/views.py:827 apps/wei/views.py:880 apps/wei/views.py:890 +#: apps/wei/views.py:825 apps/wei/views.py:878 apps/wei/views.py:888 #: templates/wei/survey.html:12 templates/wei/survey_closed.html:12 #: templates/wei/survey_end.html:12 msgid "Survey WEI" @@ -1882,6 +1930,10 @@ msgstr "" msgid "Add alias" msgstr "Ajouter un alias" +#: templates/member/autocomplete_model.html:11 +msgid "Reset" +msgstr "" + #: templates/member/club_info.html:17 msgid "Club Parent" msgstr "Club parent" @@ -2050,10 +2102,6 @@ msgstr "Sélection des destinataires" msgid "Action" msgstr "Action" -#: templates/note/transaction_form.html:104 -msgid "Reason" -msgstr "Raison" - #: templates/note/transaction_form.html:113 msgid "Transfer type" msgstr "Type de transfert" diff --git a/note_kfet/inputs.py b/note_kfet/inputs.py index 1a17d5ac..8e3d9e29 100644 --- a/note_kfet/inputs.py +++ b/note_kfet/inputs.py @@ -23,10 +23,11 @@ class AmountInput(NumberInput): class Autocomplete(TextInput): template_name = "member/autocomplete_model.html" - def __init__(self, model, attrs=None): + def __init__(self, model, resetable=False, attrs=None): super().__init__(attrs) self.model = model + self.resetable = resetable self.model_pk = None class Media: @@ -34,6 +35,11 @@ class Autocomplete(TextInput): js = ('js/autocomplete_model.js', ) + def get_context(self, name, value, attrs): + context = super().get_context(name, value, attrs) + context['widget']['resetable'] = self.resetable + return context + def format_value(self, value): if value: self.attrs["model_pk"] = int(value) diff --git a/static/js/autocomplete_model.js b/static/js/autocomplete_model.js index 6e135ad1..9d9ba2d3 100644 --- a/static/js/autocomplete_model.js +++ b/static/js/autocomplete_model.js @@ -10,6 +10,7 @@ $(document).ready(function () { if (!name_field) name_field = "name"; let input = target.val(); + $("#" + prefix + "_reset").removeClass("d-none"); $.getJSON(api_url + (api_url.includes("?") ? "&" : "?") + "format=json&search=^" + input + api_url_suffix, function(objects) { let html = ""; @@ -39,4 +40,12 @@ $(document).ready(function () { } }); }); + + $(".autocomplete-reset").click(function() { + let name = $(this).attr("id").replace("_reset", ""); + $("#" + name + "_pk").val(""); + $("#" + name).val(""); + $("#" + name + "_list").html(""); + $(this).addClass("d-none"); + }); }); \ No newline at end of file diff --git a/templates/member/autocomplete_model.html b/templates/member/autocomplete_model.html index 2236c6ef..0aeca361 100644 --- a/templates/member/autocomplete_model.html +++ b/templates/member/autocomplete_model.html @@ -1,3 +1,5 @@ +{% load i18n %} + + {% if widget.resetable %} + {% trans "Reset" %} + {% endif %}
diff --git a/templates/member/club_tables.html b/templates/member/club_tables.html index 139d3abc..063c00c5 100644 --- a/templates/member/club_tables.html +++ b/templates/member/club_tables.html @@ -1,5 +1,7 @@ {% load render_table from django_tables2 %} {% load i18n %} +{% load perms %} + {% if managers.data %}
@@ -29,7 +31,7 @@ {% if history_list.data %}
diff --git a/templates/member/profile_info.html b/templates/member/profile_info.html index 7be10ba1..35d3e4ea 100644 --- a/templates/member/profile_info.html +++ b/templates/member/profile_info.html @@ -2,22 +2,22 @@
-

{% trans "Account #" %} {{ object.pk }}

+

{% trans "Account #" %} {{ user.pk }}

{% trans 'name'|capfirst %}, {% trans 'first name' %}
-
{{ object.last_name }} {{ object.first_name }}
+
{{ user.last_name }} {{ user.first_name }}
{% trans 'username'|capfirst %}
-
{{ object.username }}
+
{{ user.username }}
- {% if object.pk == user.pk %} + {% if user.pk == user.pk %}
{% trans 'password'|capfirst %}
@@ -27,25 +27,25 @@ {% endif %}
{% trans 'section'|capfirst %}
-
{{ object.profile.section }}
+
{{ user.profile.section }}
{% trans 'address'|capfirst %}
-
{{ object.profile.address }}
+
{{ user.profile.address }}
{% trans 'balance'|capfirst %}
-
{{ object.note.balance | pretty_money }}
+
{{ user.note.balance | pretty_money }}
-
{% trans 'aliases'|capfirst %}
-
{{ object.note.alias_set.all|join:", " }}
+
{% trans 'aliases'|capfirst %}
+
{{ user.note.alias_set.all|join:", " }}
- {% if object.pk == user.pk %} + {% if user.pk == user.pk %} {% trans 'Manage auth token' %} {% endif %}