mirror of
https://gitlab.crans.org/bde/nk20
synced 2025-07-20 08:01:26 +02:00
Add fee field to WEIRegistration to be able to sort on validation status
This commit is contained in:
@ -6,7 +6,7 @@ from django.conf import settings
|
|||||||
from django.db.models.signals import post_save
|
from django.db.models.signals import post_save
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
from .signals import save_user_profile
|
from .signals import save_user_profile, update_wei_registration_fee_on_membership_creation, update_wei_registration_fee_on_club_change
|
||||||
|
|
||||||
|
|
||||||
class MemberConfig(AppConfig):
|
class MemberConfig(AppConfig):
|
||||||
@ -17,7 +17,16 @@ class MemberConfig(AppConfig):
|
|||||||
"""
|
"""
|
||||||
Define app internal signals to interact with other apps
|
Define app internal signals to interact with other apps
|
||||||
"""
|
"""
|
||||||
|
from .models import Membership, Club
|
||||||
post_save.connect(
|
post_save.connect(
|
||||||
save_user_profile,
|
save_user_profile,
|
||||||
sender=settings.AUTH_USER_MODEL,
|
sender=settings.AUTH_USER_MODEL,
|
||||||
)
|
)
|
||||||
|
post_save.connect(
|
||||||
|
update_wei_registration_fee_on_membership_creation,
|
||||||
|
sender=Membership
|
||||||
|
)
|
||||||
|
post_save.connect(
|
||||||
|
update_wei_registration_fee_on_club_change,
|
||||||
|
sender=Club
|
||||||
|
)
|
||||||
|
@ -13,3 +13,25 @@ def save_user_profile(instance, created, raw, **_kwargs):
|
|||||||
instance.profile.email_confirmed = True
|
instance.profile.email_confirmed = True
|
||||||
instance.profile.registration_valid = True
|
instance.profile.registration_valid = True
|
||||||
instance.profile.save()
|
instance.profile.save()
|
||||||
|
|
||||||
|
|
||||||
|
def update_wei_registration_fee_on_membership_creation(sender, instance, created, **kwargs):
|
||||||
|
if created:
|
||||||
|
from wei.models import WEIRegistration
|
||||||
|
if instance.club.id == 1 or instance.club.id == 2:
|
||||||
|
registrations = WEIRegistration.objects.filter(
|
||||||
|
user=instance.user,
|
||||||
|
wei__year=instance.date_start.year,
|
||||||
|
)
|
||||||
|
for r in registrations:
|
||||||
|
r.save()
|
||||||
|
|
||||||
|
|
||||||
|
def update_wei_registration_fee_on_club_change(sender, instance, **kwargs):
|
||||||
|
from wei.models import WEIRegistration
|
||||||
|
if instance.id == 1 or instance.id == 2:
|
||||||
|
registrations = WEIRegistration.objects.filter(
|
||||||
|
wei__year=instance.membership_start.year,
|
||||||
|
)
|
||||||
|
for r in registrations:
|
||||||
|
r.save()
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
# Generated by Django 5.2.4 on 2025-07-19 12:17
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('wei', '0015_remove_weiclub_caution_amount_and_more'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='weiregistration',
|
||||||
|
name='fee',
|
||||||
|
field=models.PositiveIntegerField(blank=True, default=0, verbose_name='fee'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='weiclub',
|
||||||
|
name='fee_soge_credit',
|
||||||
|
field=models.PositiveIntegerField(default=2000, verbose_name='membership fee (soge credit)'),
|
||||||
|
),
|
||||||
|
]
|
@ -285,6 +285,12 @@ class WEIRegistration(models.Model):
|
|||||||
"encoded in JSON"),
|
"encoded in JSON"),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
fee = models.PositiveIntegerField(
|
||||||
|
default=0,
|
||||||
|
verbose_name=_('fee'),
|
||||||
|
blank=True,
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
unique_together = ('user', 'wei',)
|
unique_together = ('user', 'wei',)
|
||||||
verbose_name = _("WEI User")
|
verbose_name = _("WEI User")
|
||||||
@ -309,7 +315,25 @@ class WEIRegistration(models.Model):
|
|||||||
self.information_json = json.dumps(information, indent=2)
|
self.information_json = json.dumps(information, indent=2)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def fee(self):
|
def is_validated(self):
|
||||||
|
try:
|
||||||
|
return self.membership is not None
|
||||||
|
except AttributeError:
|
||||||
|
return False
|
||||||
|
|
||||||
|
@property
|
||||||
|
def validation_status(self):
|
||||||
|
"""
|
||||||
|
Define an order to have easier access to validatable registrations
|
||||||
|
"""
|
||||||
|
if self.fee + (self.wei.deposit_amount if self.deposit_type == 'note' else 0) > self.user.note.balance:
|
||||||
|
return 2
|
||||||
|
elif self.first_year:
|
||||||
|
return 1
|
||||||
|
else:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def calculate_fee(self):
|
||||||
bde = Club.objects.get(pk=1)
|
bde = Club.objects.get(pk=1)
|
||||||
kfet = Club.objects.get(pk=2)
|
kfet = Club.objects.get(pk=2)
|
||||||
|
|
||||||
@ -336,12 +360,9 @@ class WEIRegistration(models.Model):
|
|||||||
|
|
||||||
return fee
|
return fee
|
||||||
|
|
||||||
@property
|
def save(self, *args, **kwargs):
|
||||||
def is_validated(self):
|
self.fee = self.calculate_fee()
|
||||||
try:
|
super().save(*args, **kwargs)
|
||||||
return self.membership is not None
|
|
||||||
except AttributeError:
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
class WEIMembership(Membership):
|
class WEIMembership(Membership):
|
||||||
|
@ -56,10 +56,13 @@ class WEIRegistrationTable(tables.Table):
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
validate = tables.Column(
|
validate = tables.LinkColumn(
|
||||||
|
'wei:wei_update_registration',
|
||||||
|
args=[A('pk')],
|
||||||
verbose_name=_("Validate"),
|
verbose_name=_("Validate"),
|
||||||
orderable=False,
|
orderable=True,
|
||||||
accessor=A('pk'),
|
accessor='validate_status',
|
||||||
|
text=_("Validate"),
|
||||||
attrs={
|
attrs={
|
||||||
'th': {
|
'th': {
|
||||||
'id': 'validate-membership-header'
|
'id': 'validate-membership-header'
|
||||||
@ -100,10 +103,11 @@ class WEIRegistrationTable(tables.Table):
|
|||||||
|
|
||||||
url = reverse_lazy('wei:wei_update_registration', args=(record.pk,)) + '?validate=true'
|
url = reverse_lazy('wei:wei_update_registration', args=(record.pk,)) + '?validate=true'
|
||||||
text = _('Validate')
|
text = _('Validate')
|
||||||
if record.fee > record.user.note.balance and not record.soge_credit:
|
status = record.validation_status
|
||||||
|
if status == 2:
|
||||||
btn_class = 'btn-secondary'
|
btn_class = 'btn-secondary'
|
||||||
tooltip = _("The user does not have enough money.")
|
tooltip = _("The user does not have enough money.")
|
||||||
elif record.first_year:
|
elif status == 1:
|
||||||
btn_class = 'btn-info'
|
btn_class = 'btn-info'
|
||||||
tooltip = _("The user is in first year. You may validate the credit, the algorithm will run later.")
|
tooltip = _("The user is in first year. You may validate the credit, the algorithm will run later.")
|
||||||
else:
|
else:
|
||||||
@ -121,6 +125,7 @@ class WEIRegistrationTable(tables.Table):
|
|||||||
attrs = {
|
attrs = {
|
||||||
'class': 'table table-condensed table-striped table-hover'
|
'class': 'table table-condensed table-striped table-hover'
|
||||||
}
|
}
|
||||||
|
order_by = ('validate', 'user',)
|
||||||
model = WEIRegistration
|
model = WEIRegistration
|
||||||
template_name = 'django_tables2/bootstrap4.html'
|
template_name = 'django_tables2/bootstrap4.html'
|
||||||
fields = ('user', 'user__first_name', 'user__last_name', 'first_year', 'deposit_check',
|
fields = ('user', 'user__first_name', 'user__last_name', 'first_year', 'deposit_check',
|
||||||
|
@ -13,7 +13,7 @@ from django.contrib.auth.mixins import LoginRequiredMixin
|
|||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.core.exceptions import PermissionDenied
|
from django.core.exceptions import PermissionDenied
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
from django.db.models import Q, Count
|
from django.db.models import Q, Count, Case, When, Value, IntegerField, F
|
||||||
from django.db.models.functions.text import Lower
|
from django.db.models.functions.text import Lower
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.http import HttpResponse, Http404
|
from django.http import HttpResponse, Http404
|
||||||
@ -133,6 +133,23 @@ class WEIDetailView(ProtectQuerysetMixin, LoginRequiredMixin, MultiTableMixin, D
|
|||||||
membership=None,
|
membership=None,
|
||||||
wei=club
|
wei=club
|
||||||
)
|
)
|
||||||
|
# Annotate the query to be able to sort registrations on validate status
|
||||||
|
pre_registrations = pre_registrations.annotate(
|
||||||
|
deposit=Case(
|
||||||
|
When(deposit_type='note', then=F('wei__deposit_amount')),
|
||||||
|
default=Value(0),
|
||||||
|
output_field=IntegerField()
|
||||||
|
)
|
||||||
|
).annotate(
|
||||||
|
total_fee=F('fee') + F('deposit')
|
||||||
|
).annotate(
|
||||||
|
validate_status=Case(
|
||||||
|
When(total_fee__gt=F('user__note__balance'), then=Value(2)),
|
||||||
|
When(first_year=True, then=Value(1)),
|
||||||
|
default=Value(0),
|
||||||
|
output_field=IntegerField(),
|
||||||
|
)
|
||||||
|
)
|
||||||
buses = Bus.objects.filter(PermissionBackend.filter_queryset(self.request, Bus, "view")) \
|
buses = Bus.objects.filter(PermissionBackend.filter_queryset(self.request, Bus, "view")) \
|
||||||
.filter(wei=self.object).annotate(count=Count("memberships")).order_by("name")
|
.filter(wei=self.object).annotate(count=Count("memberships")).order_by("name")
|
||||||
return [club_transactions, club_member, pre_registrations, buses, ]
|
return [club_transactions, club_member, pre_registrations, buses, ]
|
||||||
@ -261,6 +278,23 @@ class WEIRegistrationsView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTable
|
|||||||
def get_queryset(self, **kwargs):
|
def get_queryset(self, **kwargs):
|
||||||
qs = super().get_queryset(**kwargs).filter(wei=self.club, membership=None).distinct()
|
qs = super().get_queryset(**kwargs).filter(wei=self.club, membership=None).distinct()
|
||||||
|
|
||||||
|
qs = qs.annotate(
|
||||||
|
deposit=Case(
|
||||||
|
When(deposit_type='note', then=F('wei__deposit_amount')),
|
||||||
|
default=Value(0),
|
||||||
|
output_field=IntegerField()
|
||||||
|
)
|
||||||
|
).annotate(
|
||||||
|
total_fee=F('fee') + F('deposit')
|
||||||
|
).annotate(
|
||||||
|
validate_status=Case(
|
||||||
|
When(total_fee__gt=F('user__note__balance'), then=Value(2)),
|
||||||
|
When(first_year=True, then=Value(1)),
|
||||||
|
default=Value(0),
|
||||||
|
output_field=IntegerField(),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
pattern = self.request.GET.get("search", "")
|
pattern = self.request.GET.get("search", "")
|
||||||
|
|
||||||
if pattern:
|
if pattern:
|
||||||
@ -963,9 +997,9 @@ class WEIValidateRegistrationView(ProtectQuerysetMixin, ProtectedCreateView):
|
|||||||
|
|
||||||
form = context["form"]
|
form = context["form"]
|
||||||
if registration.soge_credit:
|
if registration.soge_credit:
|
||||||
form.fields["credit_amount"].initial = registration.fee
|
form.fields["credit_amount"].initial = fee
|
||||||
else:
|
else:
|
||||||
form.fields["credit_amount"].initial = max(0, registration.fee - registration.user.note.balance)
|
form.fields["credit_amount"].initial = max(0, fee - registration.user.note.balance)
|
||||||
|
|
||||||
return context
|
return context
|
||||||
|
|
||||||
@ -1052,7 +1086,7 @@ class WEIValidateRegistrationView(ProtectQuerysetMixin, ProtectedCreateView):
|
|||||||
|
|
||||||
fee = club.membership_fee_paid if user.profile.paid else club.membership_fee_unpaid
|
fee = club.membership_fee_paid if user.profile.paid else club.membership_fee_unpaid
|
||||||
if registration.soge_credit:
|
if registration.soge_credit:
|
||||||
fee = 2000
|
fee = registration.wei.fee_soge_credit
|
||||||
|
|
||||||
kfet = club.parent_club
|
kfet = club.parent_club
|
||||||
bde = kfet.parent_club
|
bde = kfet.parent_club
|
||||||
|
Reference in New Issue
Block a user