mirror of
https://gitlab.crans.org/bde/nk20
synced 2025-06-20 17:41:55 +02:00
Membership fees for paid and unpaid students, closes #43
This commit is contained in:
@ -6,7 +6,8 @@
|
||||
"name": "BDE",
|
||||
"email": "tresorerie.bde@example.com",
|
||||
"require_memberships": true,
|
||||
"membership_fee": 500,
|
||||
"membership_fee_paid": 500,
|
||||
"membership_fee_unpaid": 500,
|
||||
"membership_duration": 396,
|
||||
"membership_start": "2019-08-31",
|
||||
"membership_end": "2020-09-30"
|
||||
@ -20,7 +21,8 @@
|
||||
"email": "tresorerie.bde@example.com",
|
||||
"parent_club": 1,
|
||||
"require_memberships": true,
|
||||
"membership_fee": 3500,
|
||||
"membership_fee_paid": 3500,
|
||||
"membership_fee_unpaid": 3500,
|
||||
"membership_duration": 396,
|
||||
"membership_start": "2019-08-31",
|
||||
"membership_end": "2020-09-30"
|
||||
|
@ -4,7 +4,6 @@
|
||||
from django import forms
|
||||
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
|
||||
from django.contrib.auth.models import User
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from note_kfet.inputs import Autocomplete, AmountInput, DatePickerInput
|
||||
from permission.models import PermissionMask
|
||||
|
||||
@ -46,7 +45,8 @@ class ClubForm(forms.ModelForm):
|
||||
model = Club
|
||||
fields = '__all__'
|
||||
widgets = {
|
||||
"membership_fee": AmountInput(),
|
||||
"membership_fee_paid": AmountInput(),
|
||||
"membership_fee_unpaid": AmountInput(),
|
||||
"parent_club": Autocomplete(
|
||||
Club,
|
||||
attrs={
|
||||
|
@ -9,7 +9,6 @@ from django.core.exceptions import ValidationError, PermissionDenied
|
||||
from django.db import models
|
||||
from django.urls import reverse, reverse_lazy
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from note.models import MembershipTransaction
|
||||
|
||||
|
||||
@ -89,9 +88,14 @@ class Club(models.Model):
|
||||
help_text=_("Uncheck if this club don't require memberships."),
|
||||
)
|
||||
|
||||
membership_fee = models.PositiveIntegerField(
|
||||
membership_fee_paid = models.PositiveIntegerField(
|
||||
default=0,
|
||||
verbose_name=_('membership fee'),
|
||||
verbose_name=_('membership fee (paid students)'),
|
||||
)
|
||||
|
||||
membership_fee_unpaid = models.PositiveIntegerField(
|
||||
default=0,
|
||||
verbose_name=_('membership fee (unpaid students)'),
|
||||
)
|
||||
|
||||
membership_duration = models.PositiveIntegerField(
|
||||
@ -136,7 +140,8 @@ class Club(models.Model):
|
||||
def save(self, force_insert=False, force_update=False, using=None,
|
||||
update_fields=None):
|
||||
if not self.require_memberships:
|
||||
self.membership_fee = 0
|
||||
self.membership_fee_paid = 0
|
||||
self.membership_fee_unpaid = 0
|
||||
self.membership_duration = None
|
||||
self.membership_start = None
|
||||
self.membership_end = None
|
||||
@ -225,7 +230,10 @@ class Membership(models.Model):
|
||||
).exists():
|
||||
raise ValidationError(_('User is already a member of the club'))
|
||||
|
||||
self.fee = self.club.membership_fee
|
||||
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:
|
||||
@ -235,18 +243,23 @@ class Membership(models.Model):
|
||||
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
if created and self.fee:
|
||||
try:
|
||||
MembershipTransaction.objects.create(
|
||||
membership=self,
|
||||
source=self.user.note,
|
||||
destination=self.club.note,
|
||||
quantity=1,
|
||||
amount=self.fee,
|
||||
reason="Adhésion",
|
||||
)
|
||||
except PermissionDenied:
|
||||
self.delete()
|
||||
self.make_transaction()
|
||||
|
||||
def make_transaction(self):
|
||||
if self.transaction is not None or not self.fee:
|
||||
return
|
||||
|
||||
if self.fee:
|
||||
transaction = MembershipTransaction(
|
||||
membership=self,
|
||||
source=self.user.note,
|
||||
destination=self.club.note,
|
||||
quantity=1,
|
||||
amount=self.fee,
|
||||
reason="Adhésion",
|
||||
)
|
||||
transaction._force_save = True
|
||||
transaction.save(force_insert=True)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('membership')
|
||||
|
@ -5,11 +5,10 @@ import django_tables2 as tables
|
||||
from django.contrib.auth.models import User
|
||||
from django.urls import reverse_lazy
|
||||
from django.utils.html import format_html
|
||||
from django_tables2 import A
|
||||
|
||||
from note.templatetags.pretty_money import pretty_money
|
||||
from note_kfet.middlewares import get_current_authenticated_user
|
||||
from permission.backends import PermissionBackend
|
||||
|
||||
from .models import Club, Membership
|
||||
|
||||
|
||||
|
@ -380,7 +380,7 @@ class ClubAddMemberView(ProtectQuerysetMixin, LoginRequiredMixin, CreateView):
|
||||
return super().form_invalid(form)
|
||||
|
||||
if form.instance.date_start > form.instance.club.membership_end:
|
||||
form.add_error('user', _("The membership must end before {:%m-%d-%Y}.")
|
||||
form.add_error('user', _("The membership must begin before {:%m-%d-%Y}.")
|
||||
.format(form.instance.club.membership_start))
|
||||
return super().form_invalid(form)
|
||||
|
||||
@ -412,7 +412,7 @@ class ClubManageRolesView(ProtectQuerysetMixin, LoginRequiredMixin, UpdateView):
|
||||
return super().form_invalid(form)
|
||||
|
||||
if form.instance.date_start > form.instance.club.membership_end:
|
||||
form.add_error('user', _("The membership must end before {:%m-%d-%Y}.")
|
||||
form.add_error('user', _("The membership must begin before {:%m-%d-%Y}.")
|
||||
.format(form.instance.club.membership_start))
|
||||
return super().form_invalid(form)
|
||||
|
||||
|
@ -798,6 +798,51 @@
|
||||
"description": "Update club"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "permission.permission",
|
||||
"pk": 48,
|
||||
"fields": {
|
||||
"model": [
|
||||
"member",
|
||||
"membership"
|
||||
],
|
||||
"query": "{\"user\": [\"user\"]}",
|
||||
"type": "view",
|
||||
"mask": 1,
|
||||
"field": "",
|
||||
"description": "View our memberships"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "permission.permission",
|
||||
"pk": 49,
|
||||
"fields": {
|
||||
"model": [
|
||||
"member",
|
||||
"membership"
|
||||
],
|
||||
"query": "{\"club\": [\"club\"]}",
|
||||
"type": "view",
|
||||
"mask": 1,
|
||||
"field": "",
|
||||
"description": "View club's memberships"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "permission.permission",
|
||||
"pk": 50,
|
||||
"fields": {
|
||||
"model": [
|
||||
"member",
|
||||
"membership"
|
||||
],
|
||||
"query": "{\"club\": [\"club\"]}",
|
||||
"type": "add",
|
||||
"mask": 2,
|
||||
"field": "",
|
||||
"description": "Add a membership to a club"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "permission.rolepermissions",
|
||||
"pk": 1,
|
||||
@ -810,7 +855,8 @@
|
||||
8,
|
||||
9,
|
||||
10,
|
||||
11
|
||||
11,
|
||||
48
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -906,5 +952,64 @@
|
||||
47
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "permission.rolepermissions",
|
||||
"pk": 7,
|
||||
"fields": {
|
||||
"role": 5,
|
||||
"permissions": [
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9,
|
||||
10,
|
||||
11,
|
||||
12,
|
||||
13,
|
||||
14,
|
||||
15,
|
||||
16,
|
||||
17,
|
||||
18,
|
||||
19,
|
||||
20,
|
||||
21,
|
||||
22,
|
||||
23,
|
||||
24,
|
||||
25,
|
||||
26,
|
||||
27,
|
||||
28,
|
||||
29,
|
||||
30,
|
||||
31,
|
||||
32,
|
||||
33,
|
||||
34,
|
||||
35,
|
||||
36,
|
||||
37,
|
||||
38,
|
||||
39,
|
||||
40,
|
||||
41,
|
||||
42,
|
||||
43,
|
||||
44,
|
||||
45,
|
||||
46,
|
||||
47,
|
||||
48,
|
||||
49,
|
||||
50
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
|
@ -49,6 +49,8 @@ class InstancedPermission:
|
||||
# Force insertion, no data verification, no trigger
|
||||
obj._force_save = True
|
||||
Model.save(obj, force_insert=True)
|
||||
# We don't want log anything
|
||||
obj._no_log = True
|
||||
ret = self.model.model_class().objects.filter(self.query & Q(pk=obj.pk)).exists()
|
||||
# Delete testing object
|
||||
obj._force_delete = True
|
||||
|
@ -2,8 +2,6 @@
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
from django.core.exceptions import PermissionDenied
|
||||
from django.db.models.signals import pre_save, pre_delete, post_save, post_delete
|
||||
from logs import signals as logs_signals
|
||||
from note_kfet.middlewares import get_current_authenticated_user
|
||||
from permission.backends import PermissionBackend
|
||||
|
||||
@ -29,7 +27,7 @@ def pre_save_object(sender, instance, **kwargs):
|
||||
if instance._meta.label_lower in EXCLUDED:
|
||||
return
|
||||
|
||||
if hasattr(instance, "_force_save"):
|
||||
if hasattr(instance, "_no_log"):
|
||||
return
|
||||
|
||||
user = get_current_authenticated_user()
|
||||
@ -76,7 +74,7 @@ def pre_delete_object(instance, **kwargs):
|
||||
if instance._meta.label_lower in EXCLUDED:
|
||||
return
|
||||
|
||||
if hasattr(instance, "_force_delete"):
|
||||
if hasattr(instance, "_no_log"):
|
||||
return
|
||||
|
||||
user = get_current_authenticated_user()
|
||||
|
Reference in New Issue
Block a user