The BDE offers 80 € to each new member that registers to the Société générale

This commit is contained in:
Yohann D'ANELLO 2020-09-07 21:33:23 +02:00
parent dc6a5f56f6
commit fa3c723140
10 changed files with 60 additions and 32 deletions

View File

@ -27,8 +27,8 @@ def create_bde_and_kfet(apps, schema_editor):
parent_club_id=1,
email="tresorerie.bde@example.com",
require_memberships=True,
membership_fee_paid=500,
membership_fee_unpaid=500,
membership_fee_paid=3500,
membership_fee_unpaid=3500,
membership_duration=396,
membership_start="2020-08-01",
membership_end="2021-09-30",

View File

@ -138,7 +138,7 @@ class UserDetailView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView):
"""
We can't display information of a not registered user.
"""
return super().get_queryset().filter(profile__registration_valid=True)
return super().get_queryset(**kwargs).filter(profile__registration_valid=True)
def get_context_data(self, **kwargs):
"""

View File

@ -175,7 +175,7 @@ class Transaction(PolymorphicModel):
created = self.pk is None
to_transfer = self.amount * self.quantity
if not created:
if not created and not self.valid and not hasattr(self, "_force_save"):
# Revert old transaction
old_transaction = Transaction.objects.get(pk=self.pk)
# Check that nothing important changed

View File

@ -8,6 +8,7 @@ from django.contrib.auth.models import User
from django.core.exceptions import PermissionDenied
from django.db.models import Q
from django.forms import HiddenInput
from django.http import Http404
from django.utils.translation import gettext_lazy as _
from django.views.generic import UpdateView, TemplateView, CreateView
from member.models import Membership
@ -24,9 +25,20 @@ class ProtectQuerysetMixin:
Display 404 error if the user can't see an object, remove the fields the user can't
update on an update form (useful if the user can't change only specified fields).
"""
def get_queryset(self, **kwargs):
def get_queryset(self, filter_permissions=True, **kwargs):
qs = super().get_queryset(**kwargs)
return qs.filter(PermissionBackend.filter_queryset(self.request.user, qs.model, "view")).distinct()
return qs.filter(PermissionBackend.filter_queryset(self.request.user, qs.model, "view")).distinct()\
if filter_permissions else qs
def get_object(self, queryset=None):
try:
return super().get_object(queryset)
except Http404 as e:
try:
super().get_object(self.get_queryset(filter_permissions=False))
raise PermissionDenied()
except Http404:
raise e
def get_form(self, form_class=None):
form = super().get_form(form_class)

View File

@ -364,7 +364,7 @@ class TestValidateRegistration(TestCase):
self.assertTrue(Membership.objects.filter(club__name="Kfet", user=self.user).exists())
self.assertTrue(SogeCredit.objects.filter(user=self.user).exists())
self.assertEqual(Transaction.objects.filter(
Q(source=self.user.note) | Q(destination=self.user.note)).count(), 2)
Q(source=self.user.note) | Q(destination=self.user.note)).count(), 3)
self.assertFalse(Transaction.objects.filter(valid=True).exists())
response = self.client.get(self.user.profile.get_absolute_url())

View File

@ -21,6 +21,7 @@ from note.templatetags.pretty_money import pretty_money
from permission.backends import PermissionBackend
from permission.models import Role
from permission.views import ProtectQuerysetMixin
from treasury.models import SogeCredit
from .forms import SignUpForm, ValidationForm
from .tables import FutureUserTable
@ -219,6 +220,9 @@ class FutureUserDetailView(ProtectQuerysetMixin, LoginRequiredMixin, FormMixin,
fee += bde.membership_fee_paid if user.profile.paid else bde.membership_fee_unpaid
kfet = Club.objects.get(name="Kfet")
fee += kfet.membership_fee_paid if user.profile.paid else kfet.membership_fee_unpaid
# In 2020, for COVID-19 reasons, the BDE offered 80 € to each new member that opens a Sogé account,
# since there is no WEI.
fee += 8000
ctx["total_fee"] = "{:.02f}".format(fee / 100, )
return ctx
@ -342,6 +346,11 @@ class FutureUserDetailView(ProtectQuerysetMixin, LoginRequiredMixin, FormMixin,
membership.roles.add(Role.objects.get(name="Adhérent Kfet"))
membership.save()
if soge:
soge_credit = SogeCredit.objects.get(user=user)
# Update the credit transaction amount
soge_credit.save()
return ret
def get_success_url(self):

View File

@ -291,11 +291,11 @@ class SogeCredit(models.Model):
@property
def valid(self):
return self.credit_transaction is not None
return self.credit_transaction.valid
@property
def amount(self):
return sum(transaction.total for transaction in self.transactions.all())
return sum(transaction.total for transaction in self.transactions.all()) + 8000
def invalidate(self):
"""
@ -304,11 +304,7 @@ class SogeCredit(models.Model):
"""
if self.valid:
self.credit_transaction.valid = False
self.credit_transaction._force_save = True
self.credit_transaction.save()
self.credit_transaction._force_delete = True
self.credit_transaction.delete()
self.credit_transaction = None
for transaction in self.transactions.all():
transaction.valid = False
transaction._force_save = True
@ -321,17 +317,10 @@ class SogeCredit(models.Model):
# First invalidate all transaction and delete the credit if already did (and force mode)
self.invalidate()
self.credit_transaction = SpecialTransaction.objects.create(
source=NoteSpecial.objects.get(special_type="Virement bancaire"),
destination=self.user.note,
quantity=1,
amount=self.amount,
reason="Crédit société générale",
last_name=self.user.last_name,
first_name=self.user.first_name,
bank="Société générale",
created_at=self.transactions.order_by("-created_at").first().created_at,
)
# Refresh credit amount
self.save()
self.credit_transaction.valid = True
self.credit_transaction.save()
self.save()
for transaction in self.transactions.all():
@ -340,6 +329,25 @@ class SogeCredit(models.Model):
transaction.created_at = timezone.now()
transaction.save()
def save(self, *args, **kwargs):
if not self.credit_transaction:
self.credit_transaction = SpecialTransaction.objects.create(
source=NoteSpecial.objects.get(special_type="Virement bancaire"),
destination=self.user.note,
quantity=1,
amount=0,
reason="Crédit société générale",
last_name=self.user.last_name,
first_name=self.user.first_name,
bank="Société générale",
valid=False,
)
elif not self.valid:
self.credit_transaction.amount = self.amount
self.credit_transaction._force_save = True
self.credit_transaction.save()
super().save(*args, **kwargs)
def delete(self, **kwargs):
"""
Deleting a SogeCredit is equivalent to say that the Société générale didn't pay.
@ -358,6 +366,9 @@ class SogeCredit(models.Model):
transaction.valid = True
transaction.created_at = timezone.now()
transaction.save()
self.credit_transaction.valid = False
self.credit_transaction.reason += " (invalide)"
self.credit_transaction.save()
super().delete(**kwargs)
class Meta:

View File

@ -30,7 +30,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
<input id="searchbar" type="text" class="form-control" placeholder="Nom/prénom/note ...">
<div class="form-check">
<label for="invalid_only" class="form-check-label">
<input id="invalid_only" name="invalid_only" type="checkbox" class="checkboxinput form-check-input">
<input id="invalid_only" name="invalid_only" type="checkbox" class="checkboxinput form-check-input" checked>
{% trans "Filter with unvalidated credits only" %}
</label>
</div>

View File

@ -353,7 +353,6 @@ class TestSogeCredits(TestCase):
soge_credit.refresh_from_db()
self.assertTrue(soge_credit.valid)
self.user.note.refresh_from_db()
self.assertEqual(self.user.note.balance, 0)
self.assertEqual(
Transaction.objects.filter(Q(source=self.user.note) | Q(destination=self.user.note)).count(), 3)
self.assertTrue(self.user.profile.soge)
@ -391,7 +390,7 @@ class TestSogeCredits(TestCase):
self.user.note.refresh_from_db()
self.assertEqual(self.user.note.balance, 0)
self.assertEqual(
Transaction.objects.filter(Q(source=self.user.note) | Q(destination=self.user.note)).count(), 3)
Transaction.objects.filter(Q(source=self.user.note) | Q(destination=self.user.note)).count(), 4)
self.assertFalse(self.user.profile.soge)
def test_invoice_api(self):

View File

@ -425,11 +425,8 @@ class SogeCreditListView(LoginRequiredMixin, ProtectQuerysetMixin, SingleTableVi
| Q(user__note__alias__normalized_name__iregex="^" + Alias.normalize(pattern))
)
if "valid" in self.request.GET:
q = Q(credit_transaction=None)
if not self.request.GET["valid"]:
q = ~q
qs = qs.filter(q)
if "valid" not in self.request.GET or not self.request.GET["valid"]:
qs = qs.filter(credit_transaction__valid=False)
return qs[:20]