From d1aa1edd09fa34290c9faaf0ddf2e9f1477bde53 Mon Sep 17 00:00:00 2001 From: Ehouarn Date: Sat, 2 Aug 2025 23:32:13 +0200 Subject: [PATCH] Deposit check logic changed --- apps/permission/fixtures/initial.json | 40 +++++++++++++++++-- apps/wei/api/views.py | 2 +- apps/wei/forms/registration.py | 6 +-- ..._weiregistration_deposit_check_and_more.py | 22 ++++++++++ apps/wei/models.py | 4 +- apps/wei/tables.py | 35 ++++++++++++++-- .../wei/templates/wei/weimembership_form.html | 6 +-- apps/wei/tests/test_wei_algorithm_2025.py | 7 ++-- apps/wei/tests/test_wei_registration.py | 8 ++-- apps/wei/views.py | 39 +++++++++++------- 10 files changed, 132 insertions(+), 37 deletions(-) create mode 100644 apps/wei/migrations/0018_remove_weiregistration_deposit_check_and_more.py diff --git a/apps/permission/fixtures/initial.json b/apps/permission/fixtures/initial.json index 8c69e367..703e8d7b 100644 --- a/apps/permission/fixtures/initial.json +++ b/apps/permission/fixtures/initial.json @@ -1391,12 +1391,12 @@ "wei", "weiregistration" ], - "query": "{\"wei\": [\"club\"], \"wei__membership_end__gte\": [\"today\"]}", + "query": "[\"AND\", {\"wei\": [\"club\"], \"wei__membership_end__gte\": [\"today\"]}, {\"deposit_type\": \"note\"}]", "type": "change", "mask": 2, "field": "caution_check", "permanent": false, - "description": "Dire si un chèque de caution est donné pour une inscription WEI" + "description": "Autoriser une transaction de caution WEI" } }, { @@ -4366,6 +4366,38 @@ "description": "Modifier l'équipe d'une adhésion WEI à son bus" } }, + { + "model": "permission.permission", + "pk": 294, + "fields": { + "model": [ + "wei", + "weiregistration" + ], + "query": "[\"AND\", {\"wei__year\": [\"today\", \"year\"], \"wei__membership_start__lte\": [\"today\"], \"wei__membership_end__gte\": [\"today\"]}, {\"deposit_type\": \"check\"}]", + "type": "change", + "mask": 2, + "field": "caution_check", + "permanent": false, + "description": "Dire si un chèque de caution a été donné" + } + }, + { + "model": "permission.permission", + "pk": 295, + "fields": { + "model": [ + "wei", + "weiregistration" + ], + "query": "{\"wei__year\": [\"today\", \"year\"]}", + "type": "view", + "mask": 2, + "field": "", + "permanent": false, + "description": "Voir toutes les inscriptions au WEI courant" + } + }, { "model": "permission.role", "pk": 1, @@ -4647,7 +4679,9 @@ 176, 177, 178, - 183 + 183, + 294, + 295 ] } }, diff --git a/apps/wei/api/views.py b/apps/wei/api/views.py index 9f25e4d3..99f36d1c 100644 --- a/apps/wei/api/views.py +++ b/apps/wei/api/views.py @@ -77,7 +77,7 @@ class WEIRegistrationViewSet(ReadProtectedModelViewSet): filter_backends = [DjangoFilterBackend, RegexSafeSearchFilter] filterset_fields = ['user', 'user__username', 'user__first_name', 'user__last_name', 'user__email', 'user__note__alias__name', 'user__note__alias__normalized_name', 'wei', 'wei__name', - 'wei__email', 'wei__year', 'soge_credit', 'deposit_check', 'birth_date', 'gender', + 'wei__email', 'wei__year', 'soge_credit', 'deposit_given', 'birth_date', 'gender', 'clothing_cut', 'clothing_size', 'first_year', 'emergency_contact_name', 'emergency_contact_phone', ] search_fields = ['$user__username', '$user__first_name', '$user__last_name', '$user__email', diff --git a/apps/wei/forms/registration.py b/apps/wei/forms/registration.py index 4bf0dcd2..6c8f07cb 100644 --- a/apps/wei/forms/registration.py +++ b/apps/wei/forms/registration.py @@ -44,7 +44,7 @@ class WEIRegistrationForm(forms.ModelForm): fields = [ 'user', 'soge_credit', 'birth_date', 'gender', 'clothing_size', 'health_issues', 'emergency_contact_name', 'emergency_contact_phone', - 'first_year', 'information_json', 'deposit_check', 'deposit_type' + 'first_year', 'information_json', 'deposit_given', 'deposit_type' ] widgets = { "user": Autocomplete( @@ -59,7 +59,7 @@ class WEIRegistrationForm(forms.ModelForm): 'minDate': '1900-01-01', 'maxDate': '2100-01-01' }), - "deposit_check": forms.BooleanField( + "deposit_given": forms.BooleanField( required=False, ), "deposit_type": forms.RadioSelect(), @@ -161,7 +161,7 @@ class WEIMembership1AForm(WEIMembershipForm): """ Used to confirm registrations of first year members without choosing a bus now. """ - deposit_check = None + deposit_given = None roles = None def clean(self): diff --git a/apps/wei/migrations/0018_remove_weiregistration_deposit_check_and_more.py b/apps/wei/migrations/0018_remove_weiregistration_deposit_check_and_more.py new file mode 100644 index 00000000..fbc5cc8a --- /dev/null +++ b/apps/wei/migrations/0018_remove_weiregistration_deposit_check_and_more.py @@ -0,0 +1,22 @@ +# Generated by Django 5.2.4 on 2025-08-02 17:59 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('wei', '0017_alter_weiclub_fee_soge_credit'), + ] + + operations = [ + migrations.RemoveField( + model_name='weiregistration', + name='deposit_check', + ), + migrations.AddField( + model_name='weiregistration', + name='deposit_given', + field=models.BooleanField(default=False, verbose_name='Deposit given'), + ), + ] diff --git a/apps/wei/models.py b/apps/wei/models.py index 2c0653c7..5aa4e94f 100644 --- a/apps/wei/models.py +++ b/apps/wei/models.py @@ -202,9 +202,9 @@ class WEIRegistration(models.Model): verbose_name=_("Credit from Société générale"), ) - deposit_check = models.BooleanField( + deposit_given = models.BooleanField( default=False, - verbose_name=_("Deposit check given") + verbose_name=_("Deposit given") ) deposit_type = models.CharField( diff --git a/apps/wei/tables.py b/apps/wei/tables.py index cd493087..7dc0d531 100644 --- a/apps/wei/tables.py +++ b/apps/wei/tables.py @@ -84,6 +84,35 @@ class WEIRegistrationTable(tables.Table): }, ) + def render_deposit_type(self, record): + if record.first_year: + return format_html("∅") + if record.deposit_type == 'check': + # TODO Install Font Awesome 6 to acces more icons (and keep compaibility with current used v4) + return format_html(""" + + + + """) + if record.deposit_type == 'note': + return format_html("") + def render_validate(self, record): hasperm = PermissionBackend.check_perm( get_current_request(), "wei.add_weimembership", WEIMembership( @@ -125,8 +154,8 @@ class WEIRegistrationTable(tables.Table): order_by = ('validate', 'user',) model = WEIRegistration template_name = 'django_tables2/bootstrap4.html' - fields = ('user', 'user__first_name', 'user__last_name', 'first_year', 'deposit_check', - 'edit', 'validate', 'delete',) + fields = ('user', 'user__first_name', 'user__last_name', 'first_year', 'deposit_given', + 'deposit_type', 'edit', 'validate', 'delete',) row_attrs = { 'class': 'table-row', 'id': lambda record: "row-" + str(record.pk), @@ -165,7 +194,7 @@ class WEIMembershipTable(tables.Table): model = WEIMembership template_name = 'django_tables2/bootstrap4.html' fields = ('user', 'user__last_name', 'user__first_name', 'registration__gender', 'user__profile__department', - 'year', 'bus', 'team', 'registration__deposit_check', ) + 'year', 'bus', 'team', 'registration__deposit_given', ) row_attrs = { 'class': 'table-row', 'id': lambda record: "row-" + str(record.pk), diff --git a/apps/wei/templates/wei/weimembership_form.html b/apps/wei/templates/wei/weimembership_form.html index b0c15225..d73c1be0 100644 --- a/apps/wei/templates/wei/weimembership_form.html +++ b/apps/wei/templates/wei/weimembership_form.html @@ -96,7 +96,7 @@ SPDX-License-Identifier: GPL-3.0-or-later {% endif %} {% else %}
{% trans 'Deposit check given'|capfirst %}
-
{{ registration.deposit_check|yesno }}
+
{{ registration.deposit_given|yesno }}
{% with information=registration.information %}
{% trans 'preferred bus'|capfirst %}
@@ -169,9 +169,9 @@ SPDX-License-Identifier: GPL-3.0-or-later {% endblocktrans %}

- {% if not registration.deposit_check and not registration.first_year and registration.caution_type == 'check' %} + {% if not registration.deposit_given and not registration.first_year and registration.caution_type == 'check' %}
- {% trans "The user didn't give her/his caution check." %} + {% trans "The user didn't give her/his caution." %}
{% endif %} diff --git a/apps/wei/tests/test_wei_algorithm_2025.py b/apps/wei/tests/test_wei_algorithm_2025.py index 883b6e5a..912f0e90 100644 --- a/apps/wei/tests/test_wei_algorithm_2025.py +++ b/apps/wei/tests/test_wei_algorithm_2025.py @@ -126,7 +126,8 @@ class TestWEIAlgorithm(TestCase): for r2 in WEIRegistration.objects.filter(wei=self.wei, pk__gt=r1.pk): survey2 = WEISurvey2025(r2) bus2 = survey2.information.get_selected_bus() - + prefer_switch_bus_words = survey1.score_words(bus2) > survey1.score_words(bus1) and survey2.score_words(bus1) > survey2.score_words(bus2) - prefer_switch_bus_questions = survey1.score_questions(bus2) > survey1.score_questions(bus1) and survey2.score_questions(bus1) > survey2.score_questions(bus2) - self.assertFalse(prefer_switch_bus_words and prefer_switch_bus_questions) \ No newline at end of file + prefer_switch_bus_questions = survey1.score_questions(bus2) > survey1.score_questions(bus1) and\ + survey2.score_questions(bus1) > survey2.score_questions(bus2) + self.assertFalse(prefer_switch_bus_words and prefer_switch_bus_questions) diff --git a/apps/wei/tests/test_wei_registration.py b/apps/wei/tests/test_wei_registration.py index 185ee374..ca8f08e9 100644 --- a/apps/wei/tests/test_wei_registration.py +++ b/apps/wei/tests/test_wei_registration.py @@ -101,7 +101,7 @@ class TestWEIRegistration(TestCase): user_id=self.user.id, wei_id=self.wei.id, soge_credit=True, - deposit_check=True, + deposit_given=True, birth_date=date(2000, 1, 1), gender="nonbinary", clothing_cut="male", @@ -642,7 +642,7 @@ class TestWEIRegistration(TestCase): last_name="admin", first_name="admin", bank="Société générale", - deposit_check=True, + deposit_given=True, )) self.assertEqual(response.status_code, 200) self.assertFalse(response.context["form"].is_valid()) @@ -657,7 +657,7 @@ class TestWEIRegistration(TestCase): last_name="admin", first_name="admin", bank="Société générale", - deposit_check=True, + deposit_given=True, )) self.assertRedirects(response, reverse("wei:wei_registrations", kwargs=dict(pk=self.registration.wei.pk)), 302, 200) @@ -813,7 +813,7 @@ class TestWeiAPI(TestAPI): user_id=self.user.id, wei_id=self.wei.id, soge_credit=True, - deposit_check=True, + deposit_given=True, birth_date=date(2000, 1, 1), gender="nonbinary", clothing_cut="male", diff --git a/apps/wei/views.py b/apps/wei/views.py index d180d3d9..1fa6e4e0 100644 --- a/apps/wei/views.py +++ b/apps/wei/views.py @@ -594,8 +594,8 @@ class WEIRegister1AView(ProtectQuerysetMixin, ProtectedCreateView): # Cacher les champs pendant l'inscription initiale if "first_year" in form.fields: del form.fields["first_year"] - if "deposit_check" in form.fields: - del form.fields["deposit_check"] + if "deposit_given" in form.fields: + del form.fields["deposit_given"] if "information_json" in form.fields: del form.fields["information_json"] if "deposit_type" in form.fields: @@ -704,8 +704,8 @@ class WEIRegister2AView(ProtectQuerysetMixin, ProtectedCreateView): # Cacher les champs pendant l'inscription initiale if "first_year" in form.fields: del form.fields["first_year"] - if "deposit_check" in form.fields: - del form.fields["deposit_check"] + if "deposit_given" in form.fields: + del form.fields["deposit_given"] if "information_json" in form.fields: del form.fields["information_json"] @@ -806,9 +806,9 @@ class WEIUpdateRegistrationView(ProtectQuerysetMixin, LoginRequiredMixin, Update # The auto-json-format may cause issues with the default field remove if "information_json" in form.fields: del form.fields["information_json"] - # Masquer le champ deposit_check pour tout le monde dans le formulaire de modification - if "deposit_check" in form.fields: - del form.fields["deposit_check"] + # Masquer le champ deposit_given pour tout le monde dans le formulaire de modification + if "deposit_given" in form.fields: + del form.fields["deposit_given"] # S'assurer que le champ deposit_type est obligatoire pour les 2A+ if "deposit_type" in form.fields: @@ -818,6 +818,14 @@ class WEIUpdateRegistrationView(ProtectQuerysetMixin, LoginRequiredMixin, Update form.fields["deposit_type"].required = True form.fields["deposit_type"].help_text = _("Choose how you want to pay the deposit") + if not self.object.first_year and self.object.deposit_type == 'check': + form.fields["deposit_given"] = forms.BooleanField( + required=False, + initial=self.object.deposit_given, + label=_("Deposit check given"), + help_text=_("Tick if the deposit check has been given") + ) + if self.object.user.profile.soge: form.fields["soge_credit"].disabled = True form.fields["soge_credit"].help_text = _("You already opened an account in the Société générale.") @@ -1016,17 +1024,18 @@ class WEIValidateRegistrationView(ProtectQuerysetMixin, ProtectedCreateView): form.fields["last_name"].initial = registration.user.last_name form.fields["first_name"].initial = registration.user.first_name - # Ajouter le champ deposit_check uniquement pour les non-première année et le rendre obligatoire + # Ajouter le champ deposit_given uniquement pour les non-première année et le rendre obligatoire if not registration.first_year: if registration.deposit_type == 'check': - form.fields["deposit_check"] = forms.BooleanField( + form.fields["deposit_given"] = forms.BooleanField( required=True, - initial=registration.deposit_check, + disabled=True, + initial=registration.deposit_given, label=_("Deposit check given"), - help_text=_("Please make sure the check is given before validating the registration") + help_text=_("Only treasurers can validate this field") ) else: - form.fields["deposit_check"] = forms.BooleanField( + form.fields["deposit_given"] = forms.BooleanField( required=True, initial=False, label=_("Create deposit transaction"), @@ -1067,8 +1076,8 @@ class WEIValidateRegistrationView(ProtectQuerysetMixin, ProtectedCreateView): club = registration.wei user = registration.user - if "deposit_check" in form.data: - registration.deposit_check = form.data["deposit_check"] == "on" + if "deposit_given" in form.data: + registration.deposit_given = form.data["deposit_given"] == "on" registration.save() membership = form.instance membership.user = user @@ -1180,7 +1189,7 @@ class WEIValidateRegistrationView(ProtectQuerysetMixin, ProtectedCreateView): def form_invalid(self, form): registration = getattr(form.instance, "registration", None) if registration is not None: - registration.deposit_check = False + registration.deposit_given = False registration.save() return super().form_invalid(form)