1
0
mirror of https://gitlab.crans.org/bde/nk20 synced 2025-06-21 01:48:21 +02:00

Adhere to parent clubs automatically, adhere to Kfet automatically when registering to the WEI

This commit is contained in:
Yohann D'ANELLO
2020-08-04 20:04:41 +02:00
parent 358691aaa9
commit a096dc4427
16 changed files with 588 additions and 266 deletions

View File

@ -10,6 +10,7 @@ from django.core.exceptions import ValidationError
from django.db import models
from django.template import loader
from django.urls import reverse, reverse_lazy
from django.utils import timezone
from django.utils.encoding import force_bytes
from django.utils.http import urlsafe_base64_encode
from django.utils.translation import gettext_lazy as _
@ -301,13 +302,34 @@ class Membership(models.Model):
else:
return self.date_start.toordinal() <= datetime.datetime.now().toordinal()
def renew(self):
if Membership.objects.filter(
user=self.user,
club=self.club,
date_start__gte=self.club.membership_start,
).exists():
# Membership is already renewed
return
new_membership = Membership(
user=self.user,
club=self.club,
date_start=max(self.date_end + datetime.timedelta(days=1), self.club.membership_start),
)
from django.forms import model_to_dict
if hasattr(self, '_force_renew_parent') and self._force_renew_parent:
new_membership._force_renew_parent = True
if hasattr(self, '_soge') and self._soge:
new_membership._soge = True
if hasattr(self, '_force_save') and self._force_save:
new_membership._force_save = True
new_membership.save()
new_membership.roles.set(self.roles.all())
new_membership.save()
def save(self, *args, **kwargs):
"""
Calculate fee and end date before saving the membership and creating the transaction if needed.
"""
if self.club.parent_club is not None:
if not Membership.objects.filter(user=self.user, club=self.club.parent_club).exists():
raise ValidationError(_('User is not a member of the parent club') + ' ' + self.club.parent_club.name)
if self.pk:
for role in self.roles.all():
@ -327,17 +349,54 @@ class Membership(models.Model):
).exists():
raise ValidationError(_('User is already a member of the club'))
if self.user.profile.paid:
self.fee = self.club.membership_fee_paid
else:
self.fee = self.club.membership_fee_unpaid
if self.club.parent_club is not None:
if not Membership.objects.filter(
user=self.user,
club=self.club.parent_club,
date_start__gte=self.club.parent_club.membership_start,
).exists():
if hasattr(self, '_force_renew_parent') and self._force_renew_parent:
parent_membership = Membership.objects.filter(
user=self.user,
club=self.club.parent_club,
).order_by("-date_start")
if parent_membership.exists():
# Renew the previous membership of the parent club
parent_membership = parent_membership.first()
parent_membership._force_renew_parent = True
if hasattr(self, '_soge'):
parent_membership._soge = True
if hasattr(self, '_force_save'):
parent_membership._force_save = True
parent_membership.renew()
else:
# Create a new membership in the parent club
parent_membership = Membership(
user=self.user,
club=self.club.parent_club,
date_start=self.date_start,
)
parent_membership._force_renew_parent = True
if hasattr(self, '_soge'):
parent_membership._soge = True
if hasattr(self, '_force_save'):
parent_membership._force_save = True
parent_membership.save()
else:
raise ValidationError(_('User is not a member of the parent club')
+ ' ' + self.club.parent_club.name)
if self.club.membership_duration is not None:
self.date_end = self.date_start + datetime.timedelta(days=self.club.membership_duration)
else:
self.date_end = self.date_start + datetime.timedelta(days=424242)
if self.club.membership_end is not None and self.date_end > self.club.membership_end:
self.date_end = self.club.membership_end
if self.user.profile.paid:
self.fee = self.club.membership_fee_paid
else:
self.fee = self.club.membership_fee_unpaid
if self.club.membership_duration is not None:
self.date_end = self.date_start + datetime.timedelta(days=self.club.membership_duration)
else:
self.date_end = self.date_start + datetime.timedelta(days=424242)
if self.club.membership_end is not None and self.date_end > self.club.membership_end:
self.date_end = self.club.membership_end
super().save(*args, **kwargs)
@ -360,8 +419,9 @@ class Membership(models.Model):
reason="Adhésion " + self.club.name,
)
transaction._force_save = True
print(hasattr(self, '_soge'))
if hasattr(self, '_soge') and "treasury" in settings.INSTALLED_APPS:
if hasattr(self, '_soge') and "treasury" in settings.INSTALLED_APPS\
and (self.club.name == "BDE" or self.club.name == "Kfet" or
("wei" in settings.INSTALLED_APPS and hasattr(self.club, "weiclub") and self.club.weiclub)):
# If the soge pays, then the transaction is unvalidated in a first time, then submitted for control
# to treasurers.
transaction.valid = False

View File

@ -442,6 +442,16 @@ class ClubAddMemberView(ProtectQuerysetMixin, LoginRequiredMixin, CreateView):
.get(pk=self.kwargs["club_pk"], weiclub=None)
form.fields['credit_amount'].initial = club.membership_fee_paid
c = club
clubs_renewal = []
additional_fee_renewal = 0
while c.parent_club is not None:
c = c.parent_club
clubs_renewal.append(c)
additional_fee_renewal += c.membership_fee_paid if user.profile.paid else c.membership_fee_unpaid
context["clubs_renewal"] = clubs_renewal
context["additional_fee_renewal"] = additional_fee_renewal
# If the concerned club is the BDE, then we add the option that Société générale pays the membership.
if club.name != "BDE":
del form.fields['soge']
@ -454,26 +464,54 @@ class ClubAddMemberView(ProtectQuerysetMixin, LoginRequiredMixin, CreateView):
context["total_fee"] = "{:.02f}".format(fee / 100, )
else:
# This is a renewal. Fields can be pre-completed.
context["renewal"] = True
old_membership = self.get_queryset().get(pk=self.kwargs["pk"])
club = old_membership.club
user = old_membership.user
c = club
clubs_renewal = []
additional_fee_renewal = 0
while c.parent_club is not None:
c = c.parent_club
if not Membership.objects.filter(
club=c,
user=user,
date_start__gte=c.membership_start,
).exists():
clubs_renewal.append(c)
additional_fee_renewal += c.membership_fee_paid if user.profile.paid else c.membership_fee_unpaid
context["clubs_renewal"] = clubs_renewal
context["additional_fee_renewal"] = additional_fee_renewal
form.fields['user'].initial = user
form.fields['user'].disabled = True
form.fields['date_start'].initial = old_membership.date_end + timedelta(days=1)
form.fields['credit_amount'].initial = club.membership_fee_paid if user.profile.paid \
else club.membership_fee_unpaid
form.fields['credit_amount'].initial = (club.membership_fee_paid if user.profile.paid
else club.membership_fee_unpaid) + additional_fee_renewal
form.fields['last_name'].initial = user.last_name
form.fields['first_name'].initial = user.first_name
# If this is a renewal of a BDE membership, Société générale can pays, if it is not yet done
if club.name != "BDE" or user.profile.soge:
if (club.name != "BDE" and club.name != "Kfet") or user.profile.soge:
del form.fields['soge']
else:
fee = 0
bde = Club.objects.get(name="BDE")
fee += bde.membership_fee_paid if user.profile.paid else bde.membership_fee_unpaid
if not Membership.objects.filter(
club=bde,
user=user,
date_start__gte=bde.membership_start,
).exists():
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
if not Membership.objects.filter(
club=kfet,
user=user,
date_start__gte=bde.membership_start,
).exists():
fee += kfet.membership_fee_paid if user.profile.paid else kfet.membership_fee_unpaid
context["total_fee"] = "{:.02f}".format(fee / 100, )
context['club'] = club
@ -502,7 +540,7 @@ class ClubAddMemberView(ProtectQuerysetMixin, LoginRequiredMixin, CreateView):
last_name = form.cleaned_data["last_name"]
first_name = form.cleaned_data["first_name"]
bank = form.cleaned_data["bank"]
soge = form.cleaned_data["soge"] and not user.profile.soge and club.name == "BDE"
soge = form.cleaned_data["soge"] and not user.profile.soge and (club.name == "BDE" or club.name == "Kfet")
# If Société générale pays, then we store that information but the payment must be controlled by treasurers
# later. The membership transaction will be invalidated.
@ -513,10 +551,17 @@ class ClubAddMemberView(ProtectQuerysetMixin, LoginRequiredMixin, CreateView):
if credit_type is None:
credit_amount = 0
if user.profile.paid:
fee = club.membership_fee_paid
else:
fee = club.membership_fee_unpaid
fee = 0
c = club
while c is not None:
if not Membership.objects.filter(
club=c,
user=user,
date_start__gte=c.membership_start,
).exists():
fee += c.membership_fee_paid if user.profile.paid else c.membership_fee_unpaid
c = c.parent_club
if user.note.balance + credit_amount < fee and not Membership.objects.filter(
club__name="Kfet",
user=user,
@ -524,22 +569,11 @@ class ClubAddMemberView(ProtectQuerysetMixin, LoginRequiredMixin, CreateView):
date_end__gte=datetime.now().date(),
).exists():
# Users without a valid Kfet membership can't have a negative balance.
# Club 2 = Kfet (hard-code :'( )
# TODO Send a notification to the user (with a mail?) to tell her/him to credit her/his note
form.add_error('user',
_("This user don't have enough money to join this club, and can't have a negative balance."))
return super().form_invalid(form)
if club.parent_club is not None:
if not Membership.objects.filter(
user=form.instance.user,
club=club.parent_club,
date_start__lte=form.instance.date_start,
date_end__gte=form.instance.date_start,
).exists():
form.add_error('user', _('User is not a member of the parent club') + ' ' + club.parent_club.name)
return super().form_invalid(form)
if Membership.objects.filter(
user=form.instance.user,
club=club,
@ -561,7 +595,7 @@ class ClubAddMemberView(ProtectQuerysetMixin, LoginRequiredMixin, CreateView):
# Now, all is fine, the membership can be created.
if club.name == "BDE":
if club.name == "BDE" or club.name == "Kfet":
# When we renew the BDE membership, we update the profile section.
# We could automate that and remove the section field from the Profile model,
# but with this way users can customize their section as they want.
@ -593,6 +627,8 @@ class ClubAddMemberView(ProtectQuerysetMixin, LoginRequiredMixin, CreateView):
transaction._force_save = True
transaction.save()
form.instance._force_renew_parent = True
ret = super().form_valid(form)
member_role = Role.objects.filter(name="Membre de club").all()
@ -603,33 +639,40 @@ class ClubAddMemberView(ProtectQuerysetMixin, LoginRequiredMixin, CreateView):
# If Société générale pays, then we assume that this is the BDE membership, and we auto-renew the
# Kfet membership.
if soge:
# If not already done, create BDE and Kfet memberships
bde = Club.objects.get(name="BDE")
kfet = Club.objects.get(name="Kfet")
kfet_fee = kfet.membership_fee_paid if user.profile.paid else kfet.membership_fee_unpaid
# Get current membership, to get the end date
old_membership = Membership.objects.filter(
club__name="Kfet",
user=user,
date_start__lte=datetime.today(),
date_end__gte=datetime.today(),
)
soge_clubs = [bde, kfet]
for club in soge_clubs:
fee = club.membership_fee_paid if user.profile.paid else club.membership_fee_unpaid
membership = Membership(
club=kfet,
user=user,
fee=kfet_fee,
date_start=old_membership.get().date_end + timedelta(days=1)
if old_membership.exists() else form.instance.date_start,
)
membership._force_save = True
membership._soge = True
membership.save()
membership.refresh_from_db()
if old_membership.exists():
membership.roles.set(old_membership.get().roles.all())
else:
membership.roles.add(Role.objects.get(name="Adhérent Kfet"))
membership.save()
# Get current membership, to get the end date
old_membership = Membership.objects.filter(
club=club,
user=user,
).order_by("-date_start")
if old_membership.filter(date_start__gte=club.membership_start).exists():
# Membership is already renewed
continue
membership = Membership(
club=club,
user=user,
fee=fee,
date_start=max(old_membership.first().date_end + timedelta(days=1), club.membership_start)
if old_membership.exists() else form.instance.date_start,
)
membership._force_save = True
membership._soge = True
membership.save()
membership.refresh_from_db()
if old_membership.exists():
membership.roles.set(old_membership.get().roles.all())
else:
membership.roles.add(Role.objects.get(name="Adhérent Kfet"))
membership.save()
return ret