Remove bank, Kfet and add BDA and BDS (need to fix activity, permission and registration)
This commit is contained in:
parent
3a3e3be64c
commit
838bd2bb23
43 changed files with 128 additions and 639 deletions
|
|
@ -20,9 +20,9 @@ from .models import Activity, Guest
|
||||||
class ActivityForm(forms.ModelForm):
|
class ActivityForm(forms.ModelForm):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
# By default, the Kfet club is attended
|
# By default, the BDE club is attended
|
||||||
self.fields["attendees_club"].initial = Club.objects.get(name="Kfet")
|
self.fields["attendees_club"].initial = Club.objects.get(name="BDE")
|
||||||
self.fields["attendees_club"].widget.attrs["placeholder"] = "Kfet"
|
self.fields["attendees_club"].widget.attrs["placeholder"] = "BDE"
|
||||||
clubs = list(Club.objects.filter(PermissionBackend
|
clubs = list(Club.objects.filter(PermissionBackend
|
||||||
.filter_queryset(get_current_request(), Club, "view")).all())
|
.filter_queryset(get_current_request(), Club, "view")).all())
|
||||||
shuffle(clubs)
|
shuffle(clubs)
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
# Generated by Django 2.2.16 on 2020-09-04 21:41
|
# Generated by Django 2.2.28 on 2022-08-17 20:53
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
import django.utils.timezone
|
import django.utils.timezone
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
# Generated by Django 2.2.16 on 2020-09-04 21:41
|
# Generated by Django 2.2.28 on 2022-08-17 20:53
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
@ -10,10 +10,10 @@ class Migration(migrations.Migration):
|
||||||
initial = True
|
initial = True
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
('activity', '0001_initial'),
|
|
||||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
|
||||||
('member', '0001_initial'),
|
('member', '0001_initial'),
|
||||||
|
('activity', '0001_initial'),
|
||||||
('note', '0001_initial'),
|
('note', '0001_initial'),
|
||||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
]
|
]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
|
|
@ -73,7 +73,7 @@ class Activity(models.Model):
|
||||||
max_length=255,
|
max_length=255,
|
||||||
blank=True,
|
blank=True,
|
||||||
default="",
|
default="",
|
||||||
help_text=_("Place where the activity is organized, eg. Kfet."),
|
help_text=_("Place where the activity is organized, eg. BDE."),
|
||||||
)
|
)
|
||||||
|
|
||||||
activity_type = models.ForeignKey(
|
activity_type = models.ForeignKey(
|
||||||
|
|
@ -102,7 +102,7 @@ class Activity(models.Model):
|
||||||
on_delete=models.PROTECT,
|
on_delete=models.PROTECT,
|
||||||
related_name='+',
|
related_name='+',
|
||||||
verbose_name=_('attendees club'),
|
verbose_name=_('attendees club'),
|
||||||
help_text=_("Club that is authorized to join the activity. Mostly the Kfet club."),
|
help_text=_("Club that is authorized to join the activity."),
|
||||||
)
|
)
|
||||||
|
|
||||||
date_start = models.DateTimeField(
|
date_start = models.DateTimeField(
|
||||||
|
|
|
||||||
|
|
@ -150,8 +150,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
"source": credit_id,
|
"source": credit_id,
|
||||||
"destination": target.attr('data-inviter'),
|
"destination": target.attr('data-inviter'),
|
||||||
"last_name": last_name,
|
"last_name": last_name,
|
||||||
"first_name": first_name,
|
"first_name": first_name
|
||||||
"bank": ""
|
|
||||||
}).done(function () {
|
}).done(function () {
|
||||||
makeTransaction();
|
makeTransaction();
|
||||||
reset();
|
reset();
|
||||||
|
|
|
||||||
|
|
@ -38,8 +38,8 @@ class TestActivities(TestCase):
|
||||||
location="Earth",
|
location="Earth",
|
||||||
activity_type=ActivityType.objects.get(name="Activit\u00e9 gratuite ouverte"),
|
activity_type=ActivityType.objects.get(name="Activit\u00e9 gratuite ouverte"),
|
||||||
creater=self.user,
|
creater=self.user,
|
||||||
organizer=Club.objects.get(name="Kfet"),
|
organizer=Club.objects.get(name="BDE"),
|
||||||
attendees_club=Club.objects.get(name="Kfet"),
|
attendees_club=Club.objects.get(name="BDE"),
|
||||||
date_start=timezone.now(),
|
date_start=timezone.now(),
|
||||||
date_end=timezone.now() + timedelta(days=2),
|
date_end=timezone.now() + timedelta(days=2),
|
||||||
valid=True,
|
valid=True,
|
||||||
|
|
@ -72,8 +72,8 @@ class TestActivities(TestCase):
|
||||||
location="Earth",
|
location="Earth",
|
||||||
activity_type=ActivityType.objects.get(name="Soir\u00e9e").id,
|
activity_type=ActivityType.objects.get(name="Soir\u00e9e").id,
|
||||||
creater=self.user.id,
|
creater=self.user.id,
|
||||||
organizer=Club.objects.get(name="Kfet").id,
|
organizer=Club.objects.get(name="BDE").id,
|
||||||
attendees_club=Club.objects.get(name="Kfet").id,
|
attendees_club=Club.objects.get(name="BDE").id,
|
||||||
date_start="{:%Y-%m-%d %H:%M}".format(timezone.now()),
|
date_start="{:%Y-%m-%d %H:%M}".format(timezone.now()),
|
||||||
date_end="{:%Y-%m-%d %H:%M}".format(timezone.now() + timedelta(days=2)),
|
date_end="{:%Y-%m-%d %H:%M}".format(timezone.now() + timedelta(days=2)),
|
||||||
valid=True,
|
valid=True,
|
||||||
|
|
@ -102,8 +102,8 @@ class TestActivities(TestCase):
|
||||||
location="Earth",
|
location="Earth",
|
||||||
activity_type=ActivityType.objects.get(name="Soir\u00e9e").id,
|
activity_type=ActivityType.objects.get(name="Soir\u00e9e").id,
|
||||||
creater=self.user.id,
|
creater=self.user.id,
|
||||||
organizer=Club.objects.get(name="Kfet").id,
|
organizer=Club.objects.get(name="BDE").id,
|
||||||
attendees_club=Club.objects.get(name="Kfet").id,
|
attendees_club=Club.objects.get(name="BDE").id,
|
||||||
date_start="{:%Y-%m-%d %H:%M}".format(timezone.now()),
|
date_start="{:%Y-%m-%d %H:%M}".format(timezone.now()),
|
||||||
date_end="{:%Y-%m-%d %H:%M}".format(timezone.now() + timedelta(days=2)),
|
date_end="{:%Y-%m-%d %H:%M}".format(timezone.now() + timedelta(days=2)),
|
||||||
valid=True,
|
valid=True,
|
||||||
|
|
@ -188,8 +188,8 @@ class TestActivityAPI(TestAPI):
|
||||||
location="Earth",
|
location="Earth",
|
||||||
activity_type=ActivityType.objects.get(name="Activit\u00e9 gratuite ouverte"),
|
activity_type=ActivityType.objects.get(name="Activit\u00e9 gratuite ouverte"),
|
||||||
creater=self.user,
|
creater=self.user,
|
||||||
organizer=Club.objects.get(name="Kfet"),
|
organizer=Club.objects.get(name="BDE"),
|
||||||
attendees_club=Club.objects.get(name="Kfet"),
|
attendees_club=Club.objects.get(name="BDE"),
|
||||||
date_start=timezone.now(),
|
date_start=timezone.now(),
|
||||||
date_end=timezone.now() + timedelta(days=2),
|
date_end=timezone.now() + timedelta(days=2),
|
||||||
valid=True,
|
valid=True,
|
||||||
|
|
|
||||||
|
|
@ -340,7 +340,7 @@ UID:{md5((activity.name + "$" + str(activity.id) + str(activity.date_start)).enc
|
||||||
SUMMARY;CHARSET=UTF-8:{self.multilines(activity.name, 75, 22)}
|
SUMMARY;CHARSET=UTF-8:{self.multilines(activity.name, 75, 22)}
|
||||||
DTSTART;TZID=Europe/Berlin:{"{:%Y%m%dT%H%M%S}".format(activity.date_start)}
|
DTSTART;TZID=Europe/Berlin:{"{:%Y%m%dT%H%M%S}".format(activity.date_start)}
|
||||||
DTEND;TZID=Europe/Berlin:{"{:%Y%m%dT%H%M%S}".format(activity.date_end)}
|
DTEND;TZID=Europe/Berlin:{"{:%Y%m%dT%H%M%S}".format(activity.date_end)}
|
||||||
LOCATION:{self.multilines(activity.location, 75, 9) if activity.location else "Kfet"}
|
LOCATION:{self.multilines(activity.location, 75, 9) if activity.location else "BDA"}
|
||||||
DESCRIPTION;CHARSET=UTF-8:""" + self.multilines(activity.description.replace("\n", "\\n"), 75, 26) + """
|
DESCRIPTION;CHARSET=UTF-8:""" + self.multilines(activity.description.replace("\n", "\\n"), 75, 26) + """
|
||||||
-- {activity.organizer.name}
|
-- {activity.organizer.name}
|
||||||
END:VEVENT
|
END:VEVENT
|
||||||
|
|
|
||||||
|
|
@ -186,11 +186,6 @@ class MembershipForm(forms.ModelForm):
|
||||||
required=False,
|
required=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
bank = forms.CharField(
|
|
||||||
label=_("Bank"),
|
|
||||||
required=False,
|
|
||||||
)
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Membership
|
model = Membership
|
||||||
fields = ('user', 'date_start')
|
fields = ('user', 'date_start')
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
# Generated by Django 2.2.16 on 2020-09-04 21:41
|
# Generated by Django 2.2.28 on 2022-08-17 20:53
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
|
@ -40,12 +40,12 @@ class Migration(migrations.Migration):
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
('phone_number', phonenumber_field.modelfields.PhoneNumberField(blank=True, max_length=50, null=True, region=None, verbose_name='phone number')),
|
('phone_number', phonenumber_field.modelfields.PhoneNumberField(blank=True, max_length=50, null=True, region=None, verbose_name='phone number')),
|
||||||
('section', models.CharField(blank=True, help_text='e.g. "1A0", "9A♥", "SAPHIRE"', max_length=255, null=True, verbose_name='section')),
|
('section', models.CharField(blank=True, default='', help_text='e.g. "1A0", "9A♥", "SAPHIRE"', max_length=255, verbose_name='section')),
|
||||||
('department', models.CharField(choices=[('A0', 'Informatics (A0)'), ('A1', 'Mathematics (A1)'), ('A2', 'Physics (A2)'), ("A'2", "Applied physics (A'2)"), ('A2', "Chemistry (A''2)"), ('A3', 'Biology (A3)'), ('B1234', 'SAPHIRE (B1234)'), ('B1', 'Mechanics (B1)'), ('B2', 'Civil engineering (B2)'), ('B3', 'Mechanical engineering (B3)'), ('B4', 'EEA (B4)'), ('C', 'Design (C)'), ('D2', 'Economy-management (D2)'), ('D3', 'Social sciences (D3)'), ('E', 'English (E)'), ('EXT', 'External (EXT)')], max_length=8, verbose_name='department')),
|
('department', models.CharField(choices=[('INFO', 'Informatique'), ('MATH', 'Mathématiques'), ('DEM', 'Droit - économie - management'), ('MECATRO', 'Mécatronique'), ('2SEP', 'Sciences du sport et éducation physique'), ('SE', 'Sciences pour l’Environnement'), ('EXT', 'Externe')], max_length=8, verbose_name='department')),
|
||||||
('promotion', models.PositiveSmallIntegerField(default=2020, help_text='Year of entry to the school (None if not ENS student)', null=True, verbose_name='promotion')),
|
('promotion', models.PositiveSmallIntegerField(default=2022, help_text='Year of entry to the school (None if not ENS student)', null=True, verbose_name='promotion')),
|
||||||
('address', models.CharField(blank=True, max_length=255, null=True, verbose_name='address')),
|
('address', models.CharField(blank=True, default='', max_length=255, verbose_name='address')),
|
||||||
('paid', models.BooleanField(default=False, help_text='Tells if the user receive a salary.', verbose_name='paid')),
|
('paid', models.BooleanField(default=False, help_text='Tells if the user receive a salary.', verbose_name='paid')),
|
||||||
('ml_events_registration', models.CharField(blank=True, choices=[(None, 'No'), ('fr', 'Yes (receive them in french)'), ('en', 'Yes (receive them in english)')], default=None, max_length=2, null=True, verbose_name='Register on the mailing list to stay informed of the events of the campus (1 mail/week)')),
|
('ml_events_registration', models.CharField(blank=True, choices=[('', 'No'), ('fr', 'Yes')], default='', max_length=2, verbose_name='Register on the mailing list to stay informed of the events of the campus (1 mail/week)')),
|
||||||
('ml_sport_registration', models.BooleanField(default=False, verbose_name='Register on the mailing list to stay informed of the sport events of the campus (1 mail/week)')),
|
('ml_sport_registration', models.BooleanField(default=False, verbose_name='Register on the mailing list to stay informed of the sport events of the campus (1 mail/week)')),
|
||||||
('ml_art_registration', models.BooleanField(default=False, verbose_name='Register on the mailing list to stay informed of the art events of the campus (1 mail/week)')),
|
('ml_art_registration', models.BooleanField(default=False, verbose_name='Register on the mailing list to stay informed of the art events of the campus (1 mail/week)')),
|
||||||
('report_frequency', models.PositiveSmallIntegerField(default=0, verbose_name='report frequency (in days)')),
|
('report_frequency', models.PositiveSmallIntegerField(default=0, verbose_name='report frequency (in days)')),
|
||||||
|
|
|
||||||
|
|
@ -1,42 +0,0 @@
|
||||||
# Generated by Django 2.2.16 on 2020-09-04 21:41
|
|
||||||
|
|
||||||
from django.conf import settings
|
|
||||||
from django.db import migrations, models
|
|
||||||
import django.db.models.deletion
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
initial = True
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('permission', '0001_initial'),
|
|
||||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
|
||||||
('member', '0001_initial'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='membership',
|
|
||||||
name='roles',
|
|
||||||
field=models.ManyToManyField(to='permission.Role', verbose_name='roles'),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='membership',
|
|
||||||
name='user',
|
|
||||||
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='memberships', to=settings.AUTH_USER_MODEL, verbose_name='user'),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='club',
|
|
||||||
name='parent_club',
|
|
||||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='member.Club', verbose_name='parent club'),
|
|
||||||
),
|
|
||||||
migrations.AddIndex(
|
|
||||||
model_name='profile',
|
|
||||||
index=models.Index(fields=['user'], name='member_prof_user_id_30c316_idx'),
|
|
||||||
),
|
|
||||||
migrations.AddIndex(
|
|
||||||
model_name='membership',
|
|
||||||
index=models.Index(fields=['user'], name='member_memb_user_id_945dbc_idx'),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
|
|
@ -1,71 +0,0 @@
|
||||||
from django.db import migrations
|
|
||||||
|
|
||||||
|
|
||||||
def create_bde_and_kfet(apps, schema_editor):
|
|
||||||
"""
|
|
||||||
The clubs BDE and Kfet are pre-injected.
|
|
||||||
"""
|
|
||||||
Club = apps.get_model("member", "club")
|
|
||||||
NoteClub = apps.get_model("note", "noteclub")
|
|
||||||
Alias = apps.get_model("note", "alias")
|
|
||||||
ContentType = apps.get_model('contenttypes', 'ContentType')
|
|
||||||
polymorphic_ctype_id = ContentType.objects.get_for_model(NoteClub).id
|
|
||||||
|
|
||||||
Club.objects.get_or_create(
|
|
||||||
id=1,
|
|
||||||
name="BDE",
|
|
||||||
email="tresorerie.bde@example.com",
|
|
||||||
require_memberships=True,
|
|
||||||
membership_fee_paid=500,
|
|
||||||
membership_fee_unpaid=500,
|
|
||||||
membership_duration=396,
|
|
||||||
membership_start="2021-08-01",
|
|
||||||
membership_end="2022-09-30",
|
|
||||||
)
|
|
||||||
Club.objects.get_or_create(
|
|
||||||
id=2,
|
|
||||||
name="Kfet",
|
|
||||||
parent_club_id=1,
|
|
||||||
email="tresorerie.bde@example.com",
|
|
||||||
require_memberships=True,
|
|
||||||
membership_fee_paid=3500,
|
|
||||||
membership_fee_unpaid=3500,
|
|
||||||
membership_duration=396,
|
|
||||||
membership_start="2021-08-01",
|
|
||||||
membership_end="2022-09-30",
|
|
||||||
)
|
|
||||||
|
|
||||||
NoteClub.objects.get_or_create(
|
|
||||||
id=5,
|
|
||||||
club_id=1,
|
|
||||||
polymorphic_ctype_id=polymorphic_ctype_id,
|
|
||||||
)
|
|
||||||
NoteClub.objects.get_or_create(
|
|
||||||
id=6,
|
|
||||||
club_id=2,
|
|
||||||
polymorphic_ctype_id=polymorphic_ctype_id,
|
|
||||||
)
|
|
||||||
|
|
||||||
Alias.objects.get_or_create(
|
|
||||||
id=5,
|
|
||||||
note_id=5,
|
|
||||||
name="BDE",
|
|
||||||
normalized_name="bde",
|
|
||||||
)
|
|
||||||
Alias.objects.get_or_create(
|
|
||||||
id=6,
|
|
||||||
note_id=6,
|
|
||||||
name="Kfet",
|
|
||||||
normalized_name="kfet",
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
dependencies = [
|
|
||||||
('member', '0002_auto_20200904_2341'),
|
|
||||||
('note', '0002_create_special_notes'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.RunPython(create_bde_and_kfet),
|
|
||||||
]
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
from django.db import migrations
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('member', '0003_create_bde_and_kfet'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.RunSQL(
|
|
||||||
"UPDATE member_profile SET address = '' WHERE address IS NULL;",
|
|
||||||
),
|
|
||||||
migrations.RunSQL(
|
|
||||||
"UPDATE member_profile SET ml_events_registration = '' WHERE ml_events_registration IS NULL;",
|
|
||||||
),
|
|
||||||
migrations.RunSQL(
|
|
||||||
"UPDATE member_profile SET section = '' WHERE section IS NULL;",
|
|
||||||
),
|
|
||||||
]
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
# Generated by Django 2.2.16 on 2020-09-06 19:17
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('member', '0004_replace_null_by_blank'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='profile',
|
|
||||||
name='address',
|
|
||||||
field=models.CharField(blank=True, default='', max_length=255, verbose_name='address'),
|
|
||||||
),
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='profile',
|
|
||||||
name='ml_events_registration',
|
|
||||||
field=models.CharField(blank=True, choices=[('', 'No'), ('fr', 'Yes (receive them in french)'), ('en', 'Yes (receive them in english)')], default='', max_length=2, verbose_name='Register on the mailing list to stay informed of the events of the campus (1 mail/week)'),
|
|
||||||
),
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='profile',
|
|
||||||
name='section',
|
|
||||||
field=models.CharField(blank=True, default='', help_text='e.g. "1A0", "9A♥", "SAPHIRE"', max_length=255, verbose_name='section'),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
|
|
@ -1,50 +0,0 @@
|
||||||
import sys
|
|
||||||
|
|
||||||
from django.db import migrations
|
|
||||||
|
|
||||||
|
|
||||||
def give_note_account_permissions(apps, schema_editor):
|
|
||||||
"""
|
|
||||||
Automatically manage the membership of the Note account.
|
|
||||||
"""
|
|
||||||
User = apps.get_model("auth", "user")
|
|
||||||
Membership = apps.get_model("member", "membership")
|
|
||||||
Role = apps.get_model("permission", "role")
|
|
||||||
|
|
||||||
note = User.objects.filter(username="note")
|
|
||||||
if not note.exists():
|
|
||||||
# We are in a test environment, don't log error message
|
|
||||||
if len(sys.argv) > 1 and sys.argv[1] == 'test':
|
|
||||||
return
|
|
||||||
print("Warning: Note account was not found. The note account was not imported.")
|
|
||||||
print("Make sure you have imported the NK15 database. The new import script handles correctly the permissions.")
|
|
||||||
print("This migration will be ignored, you can re-run it if you forgot the note account or ignore it if you "
|
|
||||||
"don't want this account.")
|
|
||||||
return
|
|
||||||
|
|
||||||
note = note.get()
|
|
||||||
|
|
||||||
# Set for the two clubs a large expiration date and the correct role.
|
|
||||||
for m in Membership.objects.filter(user_id=note.id).all():
|
|
||||||
m.date_end = "3142-12-12"
|
|
||||||
m.roles.set(Role.objects.filter(name="PC Kfet").all())
|
|
||||||
m.save()
|
|
||||||
# By default, the note account is only authorized to be logged from localhost.
|
|
||||||
note.password = "ipbased$127.0.0.1"
|
|
||||||
note.is_active = True
|
|
||||||
note.save()
|
|
||||||
# Ensure that the note of the account is disabled
|
|
||||||
note.note.inactivity_reason = 'forced'
|
|
||||||
note.note.is_active = False
|
|
||||||
note.save()
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
dependencies = [
|
|
||||||
('member', '0005_remove_null_tag_on_charfields'),
|
|
||||||
('permission', '0001_initial'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.RunPython(give_note_account_permissions),
|
|
||||||
]
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
# Generated by Django 2.2.19 on 2021-03-13 11:35
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('member', '0006_create_note_account_bde_membership'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='membership',
|
|
||||||
name='roles',
|
|
||||||
field=models.ManyToManyField(related_name='memberships', to='permission.Role', verbose_name='roles'),
|
|
||||||
),
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='profile',
|
|
||||||
name='promotion',
|
|
||||||
field=models.PositiveSmallIntegerField(default=2021, help_text='Year of entry to the school (None if not ENS student)', null=True, verbose_name='promotion'),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
# Generated by Django 2.2.24 on 2021-10-05 13:44
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('member', '0007_auto_20210313_1235'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='profile',
|
|
||||||
name='department',
|
|
||||||
field=models.CharField(choices=[('A0', 'Informatics (A0)'), ('A1', 'Mathematics (A1)'), ('A2', 'Physics (A2)'), ("A'2", "Applied physics (A'2)"), ("A''2", "Chemistry (A''2)"), ('A3', 'Biology (A3)'), ('B1234', 'SAPHIRE (B1234)'), ('B1', 'Mechanics (B1)'), ('B2', 'Civil engineering (B2)'), ('B3', 'Mechanical engineering (B3)'), ('B4', 'EEA (B4)'), ('C', 'Design (C)'), ('D2', 'Economy-management (D2)'), ('D3', 'Social sciences (D3)'), ('E', 'English (E)'), ('EXT', 'External (EXT)')], max_length=8, verbose_name='department'),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
|
|
@ -381,9 +381,12 @@ class Membership(models.Model):
|
||||||
if self.club.parent_club.name == "BDE":
|
if self.club.parent_club.name == "BDE":
|
||||||
parent_membership.roles.set(
|
parent_membership.roles.set(
|
||||||
Role.objects.filter(Q(name="Adhérent BDE") | Q(name="Membre de club")).all())
|
Role.objects.filter(Q(name="Adhérent BDE") | Q(name="Membre de club")).all())
|
||||||
elif self.club.parent_club.name == "Kfet":
|
elif self.club.parent_club.name == "BDA":
|
||||||
parent_membership.roles.set(
|
parent_membership.roles.set(
|
||||||
Role.objects.filter(Q(name="Adhérent Kfet") | Q(name="Membre de club")).all())
|
Role.objects.filter(Q(name="Adhérent BDA") | Q(name="Membre de club")).all())
|
||||||
|
elif self.club.parent_club.name == "BDS":
|
||||||
|
parent_membership.roles.set(
|
||||||
|
Role.objects.filter(Q(name="Adhérent BDS") | Q(name="Membre de club")).all())
|
||||||
else:
|
else:
|
||||||
parent_membership.roles.set(Role.objects.filter(name="Membre de club").all())
|
parent_membership.roles.set(Role.objects.filter(name="Membre de club").all())
|
||||||
parent_membership.save()
|
parent_membership.save()
|
||||||
|
|
|
||||||
|
|
@ -13,29 +13,15 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
{% if additional_fee_renewal %}
|
{% if additional_fee_renewal %}
|
||||||
<div class="alert alert-warning">
|
<div class="alert alert-warning">
|
||||||
{% if renewal %}
|
{% if renewal %}
|
||||||
{% if club.name == "Kfet" %} {# Auto-renewal #}
|
{% blocktrans trimmed with clubs=clubs_renewal|join:", " pretty_fee=additional_fee_renewal|pretty_money %}
|
||||||
{% blocktrans trimmed with clubs=clubs_renewal|join:", " pretty_fee=additional_fee_renewal|pretty_money %}
|
The user is not a member of the club·s {{ clubs }}. Please create the required memberships,
|
||||||
The user is not a member of the club·s {{ clubs }}. An additional fee of {{ pretty_fee }}
|
otherwise it will fail.
|
||||||
will be charged to renew automatically the membership in this/these club·s.
|
{% endblocktrans %}
|
||||||
{% endblocktrans %}
|
|
||||||
{% else %}
|
|
||||||
{% blocktrans trimmed with clubs=clubs_renewal|join:", " pretty_fee=additional_fee_renewal|pretty_money %}
|
|
||||||
The user is not a member of the club·s {{ clubs }}. Please create the required memberships,
|
|
||||||
otherwise it will fail.
|
|
||||||
{% endblocktrans %}
|
|
||||||
{% endif %}
|
|
||||||
{% else %}
|
{% else %}
|
||||||
{% if club.name == "Kfet" %}
|
{% blocktrans trimmed with clubs=clubs_renewal|join:", " pretty_fee=additional_fee_renewal|pretty_money %}
|
||||||
{% blocktrans trimmed with clubs=clubs_renewal|join:", " pretty_fee=additional_fee_renewal|pretty_money %}
|
This club has parents {{ clubs }}. Please make sure that the user is a member of this or these club·s,
|
||||||
This club has parents {{ clubs }}. An additional fee of {{ pretty_fee }}
|
otherwise the creation of this membership will fail.
|
||||||
will be charged to adhere automatically to this/these club·s.
|
{% endblocktrans %}
|
||||||
{% endblocktrans %}
|
|
||||||
{% else %}
|
|
||||||
{% blocktrans trimmed with clubs=clubs_renewal|join:", " pretty_fee=additional_fee_renewal|pretty_money %}
|
|
||||||
This club has parents {{ clubs }}. Please make sure that the user is a member of this or these club·s,
|
|
||||||
otherwise the creation of this membership will fail.
|
|
||||||
{% endblocktrans %}
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
@ -69,10 +55,6 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
let credit_amount = $("#id_credit_amount");
|
let credit_amount = $("#id_credit_amount");
|
||||||
credit_amount.attr('disabled', true);
|
credit_amount.attr('disabled', true);
|
||||||
credit_amount.val('{{ total_fee }}');
|
credit_amount.val('{{ total_fee }}');
|
||||||
|
|
||||||
let bank = $("#id_bank");
|
|
||||||
bank.attr('disabled', true);
|
|
||||||
bank.val('Société générale');
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
@ -179,20 +179,17 @@ class TestMemberships(TestCase):
|
||||||
|
|
||||||
# We create a club without any parent and one club with parent BDE (that is the club Kfet)
|
# We create a club without any parent and one club with parent BDE (that is the club Kfet)
|
||||||
for bde_parent in False, True:
|
for bde_parent in False, True:
|
||||||
if bde_parent:
|
club = Club.objects.create(
|
||||||
club = Club.objects.get(name="Kfet")
|
name="Second club " + ("with BDE" if bde_parent else "without BDE"),
|
||||||
else:
|
parent_club=None,
|
||||||
club = Club.objects.create(
|
email="newclub@example.com",
|
||||||
name="Second club " + ("with BDE" if bde_parent else "without BDE"),
|
require_memberships=True,
|
||||||
parent_club=None,
|
membership_fee_paid=1000,
|
||||||
email="newclub@example.com",
|
membership_fee_unpaid=500,
|
||||||
require_memberships=True,
|
membership_start=date.today(),
|
||||||
membership_fee_paid=1000,
|
membership_end=date.today() + timedelta(days=366),
|
||||||
membership_fee_unpaid=500,
|
membership_duration=366,
|
||||||
membership_start=date.today(),
|
)
|
||||||
membership_end=date.today() + timedelta(days=366),
|
|
||||||
membership_duration=366,
|
|
||||||
)
|
|
||||||
|
|
||||||
response = self.client.get(reverse("member:club_add_member", args=(club.pk,)))
|
response = self.client.get(reverse("member:club_add_member", args=(club.pk,)))
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
|
|
@ -204,8 +201,7 @@ class TestMemberships(TestCase):
|
||||||
credit_type=NoteSpecial.objects.get(special_type="Espèces").id,
|
credit_type=NoteSpecial.objects.get(special_type="Espèces").id,
|
||||||
credit_amount=4200,
|
credit_amount=4200,
|
||||||
last_name="TOTO",
|
last_name="TOTO",
|
||||||
first_name="Toto",
|
first_name="Toto"
|
||||||
bank="Le matelas",
|
|
||||||
))
|
))
|
||||||
self.assertRedirects(response, user.profile.get_absolute_url(), 302, 200)
|
self.assertRedirects(response, user.profile.get_absolute_url(), 302, 200)
|
||||||
|
|
||||||
|
|
@ -223,11 +219,6 @@ class TestMemberships(TestCase):
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
|
|
||||||
bde_membership = self.bde_membership
|
bde_membership = self.bde_membership
|
||||||
if bde_parent:
|
|
||||||
bde_membership = Membership.objects.get(club__name="BDE", user=user)
|
|
||||||
bde_membership.date_start = date(year=2000, month=1, day=1)
|
|
||||||
bde_membership.date_end = date(year=2000, month=12, day=31)
|
|
||||||
bde_membership.save()
|
|
||||||
|
|
||||||
response = self.client.get(reverse("member:club_renew_membership", args=(bde_membership.pk,)))
|
response = self.client.get(reverse("member:club_renew_membership", args=(bde_membership.pk,)))
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
|
|
@ -243,7 +234,6 @@ class TestMemberships(TestCase):
|
||||||
credit_amount=14242,
|
credit_amount=14242,
|
||||||
last_name="TOTO",
|
last_name="TOTO",
|
||||||
first_name="Toto",
|
first_name="Toto",
|
||||||
bank="Bank",
|
|
||||||
))
|
))
|
||||||
self.assertRedirects(response, user.profile.get_absolute_url(), 302, 200)
|
self.assertRedirects(response, user.profile.get_absolute_url(), 302, 200)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -656,12 +656,7 @@ class ClubAddMemberView(ProtectQuerysetMixin, ProtectedCreateView):
|
||||||
if not credit_type:
|
if not credit_type:
|
||||||
credit_amount = 0
|
credit_amount = 0
|
||||||
|
|
||||||
if user.note.balance + credit_amount < fee and not Membership.objects.filter(
|
if user.note.balance + credit_amount < fee:
|
||||||
club__name="Kfet",
|
|
||||||
user=user,
|
|
||||||
date_start__lte=date.today(),
|
|
||||||
date_end__gte=date.today(),
|
|
||||||
).exists():
|
|
||||||
# Users without a valid Kfet membership can't have a negative balance.
|
# Users without a valid Kfet membership can't have a negative balance.
|
||||||
# TODO Send a notification to the user (with a mail?) to tell her/him to credit her/his note
|
# TODO Send a notification to the user (with a mail?) to tell her/him to credit her/his note
|
||||||
form.add_error('user',
|
form.add_error('user',
|
||||||
|
|
@ -678,7 +673,7 @@ class ClubAddMemberView(ProtectQuerysetMixin, ProtectedCreateView):
|
||||||
error = True
|
error = True
|
||||||
|
|
||||||
# Must join the parent club before joining this club, except for the Kfet club where it can be at the same time.
|
# Must join the parent club before joining this club, except for the Kfet club where it can be at the same time.
|
||||||
if club.name != "Kfet" and club.parent_club and not Membership.objects.filter(
|
if club.parent_club and not Membership.objects.filter(
|
||||||
user=form.instance.user,
|
user=form.instance.user,
|
||||||
club=club.parent_club,
|
club=club.parent_club,
|
||||||
date_start__gte=club.parent_club.membership_start,
|
date_start__gte=club.parent_club.membership_start,
|
||||||
|
|
@ -726,7 +721,6 @@ class ClubAddMemberView(ProtectQuerysetMixin, ProtectedCreateView):
|
||||||
credit_amount = form.cleaned_data["credit_amount"]
|
credit_amount = form.cleaned_data["credit_amount"]
|
||||||
last_name = form.cleaned_data["last_name"]
|
last_name = form.cleaned_data["last_name"]
|
||||||
first_name = form.cleaned_data["first_name"]
|
first_name = form.cleaned_data["first_name"]
|
||||||
bank = form.cleaned_data["bank"]
|
|
||||||
|
|
||||||
|
|
||||||
if credit_type is None:
|
if credit_type is None:
|
||||||
|
|
@ -750,7 +744,7 @@ class ClubAddMemberView(ProtectQuerysetMixin, ProtectedCreateView):
|
||||||
|
|
||||||
# Now, all is fine, the membership can be created.
|
# Now, all is fine, the membership can be created.
|
||||||
|
|
||||||
if club.name == "BDE" or club.name == "Kfet":
|
if club.name == "BDE":
|
||||||
# When we renew the BDE membership, we update the profile section
|
# When we renew the BDE membership, we update the profile section
|
||||||
# that should happens at least once a year.
|
# that should happens at least once a year.
|
||||||
user.profile.section = user.profile.section_generated
|
user.profile.section = user.profile.section_generated
|
||||||
|
|
@ -767,7 +761,6 @@ class ClubAddMemberView(ProtectQuerysetMixin, ProtectedCreateView):
|
||||||
reason="Crédit " + credit_type.special_type + " (Adhésion " + club.name + ")",
|
reason="Crédit " + credit_type.special_type + " (Adhésion " + club.name + ")",
|
||||||
last_name=last_name,
|
last_name=last_name,
|
||||||
first_name=first_name,
|
first_name=first_name,
|
||||||
bank=bank,
|
|
||||||
valid=True,
|
valid=True,
|
||||||
)
|
)
|
||||||
transaction._force_save = True
|
transaction._force_save = True
|
||||||
|
|
@ -780,8 +773,10 @@ class ClubAddMemberView(ProtectQuerysetMixin, ProtectedCreateView):
|
||||||
ret = super().form_valid(form)
|
ret = super().form_valid(form)
|
||||||
|
|
||||||
member_role = Role.objects.filter(Q(name="Adhérent BDE") | Q(name="Membre de club")).all() \
|
member_role = Role.objects.filter(Q(name="Adhérent BDE") | Q(name="Membre de club")).all() \
|
||||||
if club.name == "BDE" else Role.objects.filter(Q(name="Adhérent Kfet") | Q(name="Membre de club")).all() \
|
if club.name == "BDE" else Role.objects.filter(Q(name="Adhérent BDA") | Q(name="Membre de club")).all() \
|
||||||
if club.name == "Kfet"else Role.objects.filter(name="Membre de club").all()
|
if club.name == "BDA" else Role.objects.filter(Q(name="Adhérent BDS") | Q(name="Membre de club")).all() \
|
||||||
|
if club.name == "BDS" else Role.objects.filter(name="Membre de club").all()
|
||||||
|
|
||||||
# Set the same roles as before
|
# Set the same roles as before
|
||||||
if old_membership:
|
if old_membership:
|
||||||
member_role = member_role.union(old_membership.roles.all())
|
member_role = member_role.union(old_membership.roles.all())
|
||||||
|
|
|
||||||
|
|
@ -160,7 +160,7 @@ class ConsumerSerializer(serializers.ModelSerializer):
|
||||||
memberships = Membership.objects.filter(
|
memberships = Membership.objects.filter(
|
||||||
PermissionBackend.filter_queryset(get_current_request(), Membership, "view")).filter(
|
PermissionBackend.filter_queryset(get_current_request(), Membership, "view")).filter(
|
||||||
user=obj.note.user,
|
user=obj.note.user,
|
||||||
club=2, # Kfet
|
club=2, # BDA
|
||||||
).order_by("-date_start")
|
).order_by("-date_start")
|
||||||
if memberships.exists():
|
if memberships.exists():
|
||||||
return MembershipSerializer().to_representation(memberships.first())
|
return MembershipSerializer().to_representation(memberships.first())
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
# Generated by Django 2.2.16 on 2020-09-04 21:41
|
# Generated by Django 2.2.28 on 2022-08-17 20:53
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
@ -11,9 +11,9 @@ class Migration(migrations.Migration):
|
||||||
initial = True
|
initial = True
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
|
||||||
('member', '0001_initial'),
|
('member', '0001_initial'),
|
||||||
('contenttypes', '0002_remove_content_type_name'),
|
('contenttypes', '0002_remove_content_type_name'),
|
||||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
]
|
]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
|
|
@ -26,7 +26,7 @@ class Migration(migrations.Migration):
|
||||||
('display_image', models.ImageField(default='pic/default.png', max_length=255, upload_to='pic/', verbose_name='display image')),
|
('display_image', models.ImageField(default='pic/default.png', max_length=255, upload_to='pic/', verbose_name='display image')),
|
||||||
('created_at', models.DateTimeField(default=django.utils.timezone.now, verbose_name='created at')),
|
('created_at', models.DateTimeField(default=django.utils.timezone.now, verbose_name='created at')),
|
||||||
('is_active', models.BooleanField(default=True, help_text='Designates whether this note should be treated as active. Unselect this instead of deleting notes.', verbose_name='active')),
|
('is_active', models.BooleanField(default=True, help_text='Designates whether this note should be treated as active. Unselect this instead of deleting notes.', verbose_name='active')),
|
||||||
('inactivity_reason', models.CharField(choices=[('manual', 'The user blocked his/her note manually, eg. when he/she left the school for holidays. It can be reactivated at any time.'), ('forced', "The note is blocked by the the BDE and can't be manually reactivated.")], default=None, max_length=255, null=True)),
|
('inactivity_reason', models.CharField(blank=True, choices=[('manual', 'The user blocked his/her note manually, eg. when he/she left the school for holidays. It can be reactivated at any time.'), ('forced', "The note is blocked by the the BDE and can't be manually reactivated.")], default='', max_length=255)),
|
||||||
('polymorphic_ctype', models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='polymorphic_note.note_set+', to='contenttypes.ContentType')),
|
('polymorphic_ctype', models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='polymorphic_note.note_set+', to='contenttypes.ContentType')),
|
||||||
],
|
],
|
||||||
options={
|
options={
|
||||||
|
|
@ -56,7 +56,7 @@ class Migration(migrations.Migration):
|
||||||
('amount', models.PositiveIntegerField(verbose_name='amount')),
|
('amount', models.PositiveIntegerField(verbose_name='amount')),
|
||||||
('reason', models.CharField(max_length=255, verbose_name='reason')),
|
('reason', models.CharField(max_length=255, verbose_name='reason')),
|
||||||
('valid', models.BooleanField(default=True, verbose_name='valid')),
|
('valid', models.BooleanField(default=True, verbose_name='valid')),
|
||||||
('invalidity_reason', models.CharField(blank=True, default=None, max_length=255, null=True, verbose_name='invalidity reason')),
|
('invalidity_reason', models.CharField(blank=True, default='', max_length=255, verbose_name='invalidity reason')),
|
||||||
('destination', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='+', to='note.Note', verbose_name='destination')),
|
('destination', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='+', to='note.Note', verbose_name='destination')),
|
||||||
('polymorphic_ctype', models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='polymorphic_note.transaction_set+', to='contenttypes.ContentType')),
|
('polymorphic_ctype', models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='polymorphic_note.transaction_set+', to='contenttypes.ContentType')),
|
||||||
('source', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='+', to='note.Note', verbose_name='source')),
|
('source', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='+', to='note.Note', verbose_name='source')),
|
||||||
|
|
@ -128,7 +128,6 @@ class Migration(migrations.Migration):
|
||||||
('transaction_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='note.Transaction')),
|
('transaction_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='note.Transaction')),
|
||||||
('last_name', models.CharField(max_length=255, verbose_name='name')),
|
('last_name', models.CharField(max_length=255, verbose_name='name')),
|
||||||
('first_name', models.CharField(max_length=255, verbose_name='first_name')),
|
('first_name', models.CharField(max_length=255, verbose_name='first_name')),
|
||||||
('bank', models.CharField(blank=True, max_length=255, verbose_name='bank')),
|
|
||||||
],
|
],
|
||||||
options={
|
options={
|
||||||
'verbose_name': 'Special transaction',
|
'verbose_name': 'Special transaction',
|
||||||
|
|
@ -142,13 +141,26 @@ class Migration(migrations.Migration):
|
||||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
('name', models.CharField(max_length=255, unique=True, verbose_name='name')),
|
('name', models.CharField(max_length=255, unique=True, verbose_name='name')),
|
||||||
('normalized_name', models.CharField(editable=False, max_length=255, unique=True)),
|
('normalized_name', models.CharField(editable=False, max_length=255, unique=True)),
|
||||||
('note', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='note.Note')),
|
('note', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='alias', to='note.Note')),
|
||||||
],
|
],
|
||||||
options={
|
options={
|
||||||
'verbose_name': 'alias',
|
'verbose_name': 'alias',
|
||||||
'verbose_name_plural': 'aliases',
|
'verbose_name_plural': 'aliases',
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Trust',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('trusted', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='trusted', to='note.Note', verbose_name='trusted')),
|
||||||
|
('trusting', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='trusting', to='note.Note', verbose_name='trusting')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'frienship',
|
||||||
|
'verbose_name_plural': 'friendships',
|
||||||
|
'unique_together': {('trusting', 'trusted')},
|
||||||
|
},
|
||||||
|
),
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='TransactionTemplate',
|
name='TransactionTemplate',
|
||||||
fields=[
|
fields=[
|
||||||
|
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
from django.db import migrations
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('note', '0002_create_special_notes'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.RunSQL(
|
|
||||||
"UPDATE note_note SET inactivity_reason = '' WHERE inactivity_reason IS NULL;"
|
|
||||||
),
|
|
||||||
migrations.RunSQL(
|
|
||||||
"UPDATE note_transaction SET invalidity_reason = '' WHERE invalidity_reason IS NULL;"
|
|
||||||
),
|
|
||||||
]
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
# Generated by Django 2.2.16 on 2020-09-06 19:17
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('note', '0003_replace_null_by_blank'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='note',
|
|
||||||
name='inactivity_reason',
|
|
||||||
field=models.CharField(blank=True, choices=[('manual', 'The user blocked his/her note manually, eg. when he/she left the school for holidays. It can be reactivated at any time.'), ('forced', "The note is blocked by the the BDE and can't be manually reactivated.")], default='', max_length=255),
|
|
||||||
),
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='transaction',
|
|
||||||
name='invalidity_reason',
|
|
||||||
field=models.CharField(blank=True, default='', max_length=255, verbose_name='invalidity reason'),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
# Generated by Django 2.2.19 on 2021-03-13 11:35
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
import django.db.models.deletion
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('note', '0004_remove_null_tag_on_charfields'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='alias',
|
|
||||||
name='note',
|
|
||||||
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='alias', to='note.Note'),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
# Generated by Django 2.2.24 on 2021-09-05 19:16
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
import django.db.models.deletion
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('note', '0005_auto_20210313_1235'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.CreateModel(
|
|
||||||
name='Trust',
|
|
||||||
fields=[
|
|
||||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
||||||
('trusted', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='trusted', to='note.Note', verbose_name='trusted')),
|
|
||||||
('trusting', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='trusting', to='note.Note', verbose_name='trusting')),
|
|
||||||
],
|
|
||||||
options={
|
|
||||||
'verbose_name': 'frienship',
|
|
||||||
'verbose_name_plural': 'friendships',
|
|
||||||
'unique_together': {('trusting', 'trusted')},
|
|
||||||
},
|
|
||||||
),
|
|
||||||
]
|
|
||||||
|
|
@ -306,11 +306,6 @@ class SpecialTransaction(Transaction):
|
||||||
verbose_name=_("first_name"),
|
verbose_name=_("first_name"),
|
||||||
)
|
)
|
||||||
|
|
||||||
bank = models.CharField(
|
|
||||||
max_length=255,
|
|
||||||
verbose_name=_("bank"),
|
|
||||||
blank=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def type(self):
|
def type(self):
|
||||||
|
|
@ -346,20 +341,16 @@ class SpecialTransaction(Transaction):
|
||||||
credit_type = form.cleaned_data["credit_type"]
|
credit_type = form.cleaned_data["credit_type"]
|
||||||
last_name = form.cleaned_data["last_name"]
|
last_name = form.cleaned_data["last_name"]
|
||||||
first_name = form.cleaned_data["first_name"]
|
first_name = form.cleaned_data["first_name"]
|
||||||
bank = form.cleaned_data["bank"]
|
|
||||||
|
|
||||||
error = False
|
error = False
|
||||||
|
|
||||||
if not last_name or not first_name or (not bank and credit_type.special_type == "Chèque"):
|
if not last_name or not first_name:
|
||||||
if not last_name:
|
if not last_name:
|
||||||
form.add_error('last_name', _("This field is required."))
|
form.add_error('last_name', _("This field is required."))
|
||||||
error = True
|
error = True
|
||||||
if not first_name:
|
if not first_name:
|
||||||
form.add_error('first_name', _("This field is required."))
|
form.add_error('first_name', _("This field is required."))
|
||||||
error = True
|
error = True
|
||||||
if not bank and credit_type.special_type == "Chèque":
|
|
||||||
form.add_error('bank', _("This field is required."))
|
|
||||||
error = True
|
|
||||||
|
|
||||||
return not error
|
return not error
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -139,12 +139,6 @@ SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
<input type="text" id="first_name" class="form-control" />
|
<input type="text" id="first_name" class="form-control" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row">
|
|
||||||
<div class="col-md-12">
|
|
||||||
<label for="bank">{% trans "Bank" %} :</label>
|
|
||||||
<input type="text" id="bank" class="form-control" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<hr>
|
<hr>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ class TestTransactions(TestCase):
|
||||||
membership = Membership.objects.create(club=Club.objects.get(name="BDE"), user=self.user)
|
membership = Membership.objects.create(club=Club.objects.get(name="BDE"), user=self.user)
|
||||||
membership.roles.add(Role.objects.get(name="Respo info"))
|
membership.roles.add(Role.objects.get(name="Respo info"))
|
||||||
membership.save()
|
membership.save()
|
||||||
Membership.objects.create(club=Club.objects.get(name="Kfet"), user=self.user)
|
Membership.objects.create(club=Club.objects.get(name="BDA"), user=self.user)
|
||||||
self.user.note.refresh_from_db()
|
self.user.note.refresh_from_db()
|
||||||
|
|
||||||
self.second_user = User.objects.create(
|
self.second_user = User.objects.create(
|
||||||
|
|
@ -377,7 +377,7 @@ class TestNoteAPI(TestAPI):
|
||||||
membership = Membership.objects.create(club=Club.objects.get(name="BDE"), user=self.user)
|
membership = Membership.objects.create(club=Club.objects.get(name="BDE"), user=self.user)
|
||||||
membership.roles.add(Role.objects.get(name="Respo info"))
|
membership.roles.add(Role.objects.get(name="Respo info"))
|
||||||
membership.save()
|
membership.save()
|
||||||
Membership.objects.create(club=Club.objects.get(name="Kfet"), user=self.user)
|
Membership.objects.create(club=Club.objects.get(name="BDA"), user=self.user)
|
||||||
self.user.note.last_negative = timezone.now()
|
self.user.note.last_negative = timezone.now()
|
||||||
self.user.note.save()
|
self.user.note.save()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
# Generated by Django 2.2.16 on 2020-09-04 21:41
|
# Generated by Django 2.2.28 on 2022-08-17 20:53
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
import django.db.models.deletion
|
import django.db.models.deletion
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@ from django.utils.crypto import get_random_string
|
||||||
from activity.models import Activity
|
from activity.models import Activity
|
||||||
from member.models import Club, Membership
|
from member.models import Club, Membership
|
||||||
from note.models import NoteUser
|
from note.models import NoteUser
|
||||||
from wei.models import WEIClub, Bus, WEIRegistration
|
|
||||||
|
|
||||||
|
|
||||||
class TestPermissionDenied(TestCase):
|
class TestPermissionDenied(TestCase):
|
||||||
|
|
@ -79,56 +78,6 @@ class TestPermissionDenied(TestCase):
|
||||||
response = self.client.get(reverse("member:club_renew_membership", kwargs=dict(pk=membership.pk)))
|
response = self.client.get(reverse("member:club_renew_membership", kwargs=dict(pk=membership.pk)))
|
||||||
self.assertEqual(response.status_code, 403)
|
self.assertEqual(response.status_code, 403)
|
||||||
|
|
||||||
def test_create_weiclub(self):
|
|
||||||
response = self.client.get(reverse("wei:wei_create"))
|
|
||||||
self.assertEqual(response.status_code, 403)
|
|
||||||
|
|
||||||
def test_create_wei_bus(self):
|
|
||||||
wei = WEIClub.objects.create(
|
|
||||||
membership_start=date.today(),
|
|
||||||
date_start=date.today() + timedelta(days=1),
|
|
||||||
date_end=date.today() + timedelta(days=1),
|
|
||||||
)
|
|
||||||
response = self.client.get(reverse("wei:add_bus", kwargs=dict(pk=wei.pk)))
|
|
||||||
self.assertEqual(response.status_code, 403)
|
|
||||||
|
|
||||||
def test_create_wei_team(self):
|
|
||||||
wei = WEIClub.objects.create(
|
|
||||||
membership_start=date.today(),
|
|
||||||
date_start=date.today() + timedelta(days=1),
|
|
||||||
date_end=date.today() + timedelta(days=1),
|
|
||||||
)
|
|
||||||
bus = Bus.objects.create(wei=wei)
|
|
||||||
response = self.client.get(reverse("wei:add_team", kwargs=dict(pk=bus.pk)))
|
|
||||||
self.assertEqual(response.status_code, 403)
|
|
||||||
|
|
||||||
def test_create_1a_weiregistration(self):
|
|
||||||
wei = WEIClub.objects.create(
|
|
||||||
membership_start=date.today(),
|
|
||||||
date_start=date.today() + timedelta(days=1),
|
|
||||||
date_end=date.today() + timedelta(days=1),
|
|
||||||
)
|
|
||||||
response = self.client.get(reverse("wei:wei_register_1A", kwargs=dict(wei_pk=wei.pk)))
|
|
||||||
self.assertEqual(response.status_code, 403)
|
|
||||||
|
|
||||||
def test_create_old_weiregistration(self):
|
|
||||||
wei = WEIClub.objects.create(
|
|
||||||
membership_start=date.today(),
|
|
||||||
date_start=date.today() + timedelta(days=1),
|
|
||||||
date_end=date.today() + timedelta(days=1),
|
|
||||||
)
|
|
||||||
response = self.client.get(reverse("wei:wei_register_2A", kwargs=dict(wei_pk=wei.pk)))
|
|
||||||
self.assertEqual(response.status_code, 403)
|
|
||||||
|
|
||||||
def test_validate_weiregistration(self):
|
|
||||||
wei = WEIClub.objects.create(
|
|
||||||
membership_start=date.today(),
|
|
||||||
date_start=date.today() + timedelta(days=1),
|
|
||||||
date_end=date.today() + timedelta(days=1),
|
|
||||||
)
|
|
||||||
registration = WEIRegistration.objects.create(wei=wei, user=self.user, birth_date="2000-01-01")
|
|
||||||
response = self.client.get(reverse("wei:validate_registration", kwargs=dict(pk=registration.pk)))
|
|
||||||
self.assertEqual(response.status_code, 403)
|
|
||||||
|
|
||||||
def test_create_invoice(self):
|
def test_create_invoice(self):
|
||||||
response = self.client.get(reverse("treasury:invoice_create"))
|
response = self.client.get(reverse("treasury:invoice_create"))
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ from django.test import TestCase
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from member.models import Club, Membership
|
from member.models import Club, Membership
|
||||||
from note.models import NoteUser, Note, NoteClub, NoteSpecial
|
from note.models import NoteUser, Note, NoteClub, NoteSpecial
|
||||||
from wei.models import WEIMembership, WEIRegistration, WEIClub, Bus, BusTeam
|
|
||||||
|
|
||||||
from ..models import Permission
|
from ..models import Permission
|
||||||
|
|
||||||
|
|
@ -23,44 +23,16 @@ class PermissionQueryTestCase(TestCase):
|
||||||
def setUpTestData(cls):
|
def setUpTestData(cls):
|
||||||
user = User.objects.create(username="user")
|
user = User.objects.create(username="user")
|
||||||
NoteUser.objects.create(user=user)
|
NoteUser.objects.create(user=user)
|
||||||
wei = WEIClub.objects.create(
|
|
||||||
name="wei",
|
|
||||||
date_start=date.today(),
|
|
||||||
date_end=date.today(),
|
|
||||||
)
|
|
||||||
NoteClub.objects.create(club=wei)
|
|
||||||
weiregistration = WEIRegistration.objects.create(
|
|
||||||
user=user,
|
|
||||||
wei=wei,
|
|
||||||
birth_date=date.today(),
|
|
||||||
)
|
|
||||||
bus = Bus.objects.create(
|
|
||||||
name="bus",
|
|
||||||
wei=wei,
|
|
||||||
)
|
|
||||||
team = BusTeam.objects.create(
|
|
||||||
name="team",
|
|
||||||
bus=bus,
|
|
||||||
color=0xFFFFFF,
|
|
||||||
)
|
|
||||||
WEIMembership.objects.create(
|
|
||||||
user=user,
|
|
||||||
club=wei,
|
|
||||||
registration=weiregistration,
|
|
||||||
bus=bus,
|
|
||||||
team=team,
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_permission_queries(self):
|
def test_permission_queries(self):
|
||||||
"""
|
"""
|
||||||
Check for all permissions that the query is compilable and that the database can parse the query.
|
Check for all permissions that the query is compilable and that the database can parse the query.
|
||||||
We use a random user with a random WEIClub (to use permissions for the WEI) in a random team in a random bus.
|
We use a random user.
|
||||||
"""
|
"""
|
||||||
for perm in Permission.objects.all():
|
for perm in Permission.objects.all():
|
||||||
try:
|
try:
|
||||||
instanced = perm.about(
|
instanced = perm.about(
|
||||||
user=User.objects.get(),
|
user=User.objects.get(),
|
||||||
club=WEIClub.objects.get(),
|
|
||||||
membership=Membership.objects.get(),
|
membership=Membership.objects.get(),
|
||||||
User=User,
|
User=User,
|
||||||
Club=Club,
|
Club=Club,
|
||||||
|
|
|
||||||
|
|
@ -74,20 +74,21 @@ class ValidationForm(forms.Form):
|
||||||
required=False,
|
required=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
bank = forms.CharField(
|
|
||||||
label=_("Bank"),
|
|
||||||
required=False,
|
|
||||||
)
|
|
||||||
|
|
||||||
join_bde = forms.BooleanField(
|
join_bde = forms.BooleanField(
|
||||||
label=_("Join BDE Club"),
|
label=_("Join BDE Club"),
|
||||||
required=False,
|
required=False,
|
||||||
initial=True,
|
initial=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
# The user can join the Kfet club at the inscription
|
join_bda = forms.BooleanField(
|
||||||
join_kfet = forms.BooleanField(
|
label=_("Join BDA Club"),
|
||||||
label=_("Join Kfet Club"),
|
|
||||||
required=False,
|
required=False,
|
||||||
initial=True,
|
initial=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
join_bds = forms.BooleanField(
|
||||||
|
label=_("Join BDS Club"),
|
||||||
|
required=False,
|
||||||
|
initial=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -82,10 +82,6 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
credit_amount.attr('disabled', true);
|
credit_amount.attr('disabled', true);
|
||||||
credit_amount.val('{{ total_fee }}');
|
credit_amount.val('{{ total_fee }}');
|
||||||
|
|
||||||
let bank = $("#id_bank");
|
|
||||||
bank.attr('disabled', true);
|
|
||||||
bank.val('Société générale');
|
|
||||||
|
|
||||||
let join_bde = $("#id_join_bde");
|
let join_bde = $("#id_join_bde");
|
||||||
|
|
||||||
join_bde.attr('disabled', true);
|
join_bde.attr('disabled', true);
|
||||||
|
|
|
||||||
|
|
@ -193,7 +193,6 @@ class TestValidateRegistration(TestCase):
|
||||||
credit_amount=4200,
|
credit_amount=4200,
|
||||||
last_name="TOTO",
|
last_name="TOTO",
|
||||||
first_name="Toto",
|
first_name="Toto",
|
||||||
bank="Société générale",
|
|
||||||
join_bde=False,
|
join_bde=False,
|
||||||
join_kfet=False,
|
join_kfet=False,
|
||||||
))
|
))
|
||||||
|
|
@ -206,7 +205,6 @@ class TestValidateRegistration(TestCase):
|
||||||
credit_amount=0,
|
credit_amount=0,
|
||||||
last_name="TOTO",
|
last_name="TOTO",
|
||||||
first_name="Toto",
|
first_name="Toto",
|
||||||
bank="Société générale",
|
|
||||||
join_bde=False,
|
join_bde=False,
|
||||||
join_kfet=True,
|
join_kfet=True,
|
||||||
))
|
))
|
||||||
|
|
@ -219,7 +217,6 @@ class TestValidateRegistration(TestCase):
|
||||||
credit_amount=0,
|
credit_amount=0,
|
||||||
last_name="TOTO",
|
last_name="TOTO",
|
||||||
first_name="Toto",
|
first_name="Toto",
|
||||||
bank="J'ai pas d'argent",
|
|
||||||
join_bde=True,
|
join_bde=True,
|
||||||
join_kfet=True,
|
join_kfet=True,
|
||||||
))
|
))
|
||||||
|
|
@ -232,7 +229,6 @@ class TestValidateRegistration(TestCase):
|
||||||
credit_amount=4000,
|
credit_amount=4000,
|
||||||
last_name="",
|
last_name="",
|
||||||
first_name="",
|
first_name="",
|
||||||
bank="",
|
|
||||||
join_bde=True,
|
join_bde=True,
|
||||||
join_kfet=True,
|
join_kfet=True,
|
||||||
))
|
))
|
||||||
|
|
@ -248,7 +244,6 @@ class TestValidateRegistration(TestCase):
|
||||||
credit_amount=500,
|
credit_amount=500,
|
||||||
last_name="TOTO",
|
last_name="TOTO",
|
||||||
first_name="Toto",
|
first_name="Toto",
|
||||||
bank="Société générale",
|
|
||||||
join_bde=True,
|
join_bde=True,
|
||||||
join_kfet=False,
|
join_kfet=False,
|
||||||
))
|
))
|
||||||
|
|
@ -273,7 +268,6 @@ class TestValidateRegistration(TestCase):
|
||||||
credit_amount=500,
|
credit_amount=500,
|
||||||
last_name="TOTO",
|
last_name="TOTO",
|
||||||
first_name="Toto",
|
first_name="Toto",
|
||||||
bank="Société générale",
|
|
||||||
join_bde=True,
|
join_bde=True,
|
||||||
join_kfet=False,
|
join_kfet=False,
|
||||||
))
|
))
|
||||||
|
|
@ -307,16 +301,17 @@ class TestValidateRegistration(TestCase):
|
||||||
credit_amount=4000,
|
credit_amount=4000,
|
||||||
last_name="TOTO",
|
last_name="TOTO",
|
||||||
first_name="Toto",
|
first_name="Toto",
|
||||||
bank="Société générale",
|
|
||||||
join_bde=True,
|
join_bde=True,
|
||||||
join_kfet=True,
|
join_bda=True,
|
||||||
|
join_bds=True
|
||||||
))
|
))
|
||||||
self.assertRedirects(response, self.user.profile.get_absolute_url(), 302, 200)
|
self.assertRedirects(response, self.user.profile.get_absolute_url(), 302, 200)
|
||||||
self.user.profile.refresh_from_db()
|
self.user.profile.refresh_from_db()
|
||||||
self.assertTrue(self.user.profile.registration_valid)
|
self.assertTrue(self.user.profile.registration_valid)
|
||||||
self.assertTrue(NoteUser.objects.filter(user=self.user).exists())
|
self.assertTrue(NoteUser.objects.filter(user=self.user).exists())
|
||||||
self.assertTrue(Membership.objects.filter(club__name="BDE", user=self.user).exists())
|
self.assertTrue(Membership.objects.filter(club__name="BDE", user=self.user).exists())
|
||||||
self.assertTrue(Membership.objects.filter(club__name="Kfet", user=self.user).exists())
|
self.assertTrue(Membership.objects.filter(club__name="BDA", user=self.user).exists())
|
||||||
|
self.assertTrue(Membership.objects.filter(club__name="BDS", user=self.user).exists())
|
||||||
self.assertEqual(Transaction.objects.filter(
|
self.assertEqual(Transaction.objects.filter(
|
||||||
Q(source=self.user.note) | Q(destination=self.user.note)).count(), 3)
|
Q(source=self.user.note) | Q(destination=self.user.note)).count(), 3)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -225,9 +225,10 @@ class FutureUserDetailView(ProtectQuerysetMixin, LoginRequiredMixin, FormMixin,
|
||||||
user = self.get_object()
|
user = self.get_object()
|
||||||
fee = 0
|
fee = 0
|
||||||
bde = Club.objects.get(name="BDE")
|
bde = Club.objects.get(name="BDE")
|
||||||
fee += bde.membership_fee_paid if user.profile.paid else bde.membership_fee_unpaid
|
bda = Club.objects.get(name="BDA")
|
||||||
kfet = Club.objects.get(name="Kfet")
|
bds = Club.objects.get(name="BDS")
|
||||||
fee += kfet.membership_fee_paid if user.profile.paid else kfet.membership_fee_unpaid
|
for auto_club in [bde, bda, bds]:
|
||||||
|
fee += auto_club.membership_fee_paid if user.profile.paid else auto_club.membership_fee_unpaid
|
||||||
ctx["total_fee"] = "{:.02f}".format(fee / 100, )
|
ctx["total_fee"] = "{:.02f}".format(fee / 100, )
|
||||||
|
|
||||||
return ctx
|
return ctx
|
||||||
|
|
@ -256,30 +257,20 @@ class FutureUserDetailView(ProtectQuerysetMixin, LoginRequiredMixin, FormMixin,
|
||||||
credit_amount = form.cleaned_data["credit_amount"]
|
credit_amount = form.cleaned_data["credit_amount"]
|
||||||
last_name = form.cleaned_data["last_name"]
|
last_name = form.cleaned_data["last_name"]
|
||||||
first_name = form.cleaned_data["first_name"]
|
first_name = form.cleaned_data["first_name"]
|
||||||
bank = form.cleaned_data["bank"]
|
|
||||||
join_bde = form.cleaned_data["join_bde"]
|
join_bde = form.cleaned_data["join_bde"]
|
||||||
join_kfet = form.cleaned_data["join_kfet"]
|
join_bda = form.cleaned_data["join_bda"]
|
||||||
|
join_bds = form.cleaned_data["join_bds"]
|
||||||
|
|
||||||
|
|
||||||
if not join_bde:
|
|
||||||
# This software belongs to the BDE.
|
|
||||||
form.add_error('join_bde', _("You must join the BDE."))
|
|
||||||
return super().form_invalid(form)
|
|
||||||
|
|
||||||
# Calculate required registration fee
|
# Calculate required registration fee
|
||||||
fee = 0
|
fee = 0
|
||||||
bde = Club.objects.get(name="BDE")
|
bde = Club.objects.get(name="BDE")
|
||||||
bde_fee = bde.membership_fee_paid if user.profile.paid else bde.membership_fee_unpaid
|
bda = Club.objects.get(name="BDA")
|
||||||
# This is mandatory.
|
bds = Club.objects.get(name="BDS")
|
||||||
fee += bde_fee if join_bde else 0
|
for auto_club, auto_join in zip([bde, bda, bds], [join_bde, join_bda, join_bds]):
|
||||||
kfet = Club.objects.get(name="Kfet")
|
bd_fee = auto_club.membership_fee_paid if user.profile.paid else auto_club.membership_fee_unpaid
|
||||||
kfet_fee = kfet.membership_fee_paid if user.profile.paid else kfet.membership_fee_unpaid
|
fee += bd_fee if auto_join else 0
|
||||||
# Add extra fee for the full membership
|
|
||||||
fee += kfet_fee if join_kfet else 0
|
|
||||||
|
|
||||||
# If the bank pays, then we don't credit now. Treasurers will validate the transaction
|
|
||||||
# and credit the note later.
|
|
||||||
credit_type = credit_type
|
|
||||||
|
|
||||||
# If the user does not select any payment method, then no credit will be performed.
|
# If the user does not select any payment method, then no credit will be performed.
|
||||||
credit_amount = 0 if credit_type is None else credit_amount
|
credit_amount = 0 if credit_type is None else credit_amount
|
||||||
|
|
@ -314,35 +305,22 @@ class FutureUserDetailView(ProtectQuerysetMixin, LoginRequiredMixin, FormMixin,
|
||||||
reason="Crédit " + credit_type.special_type + " (Inscription)",
|
reason="Crédit " + credit_type.special_type + " (Inscription)",
|
||||||
last_name=last_name,
|
last_name=last_name,
|
||||||
first_name=first_name,
|
first_name=first_name,
|
||||||
bank=bank,
|
|
||||||
valid=True,
|
valid=True,
|
||||||
)
|
)
|
||||||
|
for auto_club, auto_join, name in zip([bde, bda, bds], [join_bde, join_bda, join_bds], ["Adhérent BDE", "Adhérent BDA", "Adhérent BDS"]):
|
||||||
|
bd_fee = auto_club.membership_fee_paid if user.profile.paid else auto_club.membership_fee_unpaid
|
||||||
|
|
||||||
if join_bde:
|
if auto_join:
|
||||||
# Create membership for the user to the BDE starting today
|
# Create membership for the user to the BDEAS starting today
|
||||||
membership = Membership(
|
membership = Membership(
|
||||||
club=bde,
|
club=auto_club,
|
||||||
user=user,
|
user=user,
|
||||||
fee=bde_fee,
|
fee=bd_fee,
|
||||||
)
|
)
|
||||||
membership.save()
|
membership.save()
|
||||||
membership.refresh_from_db()
|
membership.refresh_from_db()
|
||||||
membership.roles.add(Role.objects.get(name="Adhérent BDE"))
|
membership.roles.add(Role.objects.get(name=name))
|
||||||
membership.save()
|
membership.save()
|
||||||
|
|
||||||
if join_kfet:
|
|
||||||
# Create membership for the user to the Kfet starting today
|
|
||||||
membership = Membership(
|
|
||||||
club=kfet,
|
|
||||||
user=user,
|
|
||||||
fee=kfet_fee,
|
|
||||||
)
|
|
||||||
|
|
||||||
membership.save()
|
|
||||||
membership.refresh_from_db()
|
|
||||||
membership.roles.add(Role.objects.get(name="Adhérent Kfet"))
|
|
||||||
membership.save()
|
|
||||||
|
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -132,8 +132,6 @@ class LinkTransactionToRemittanceForm(forms.ModelForm):
|
||||||
|
|
||||||
first_name = forms.Field(label=_("First name"))
|
first_name = forms.Field(label=_("First name"))
|
||||||
|
|
||||||
bank = forms.Field(label=_("Bank"))
|
|
||||||
|
|
||||||
amount = forms.IntegerField(label=_("Amount"), min_value=0, widget=AmountInput(), disabled=True, required=False)
|
amount = forms.IntegerField(label=_("Amount"), min_value=0, widget=AmountInput(), disabled=True, required=False)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
|
@ -148,7 +146,6 @@ class LinkTransactionToRemittanceForm(forms.ModelForm):
|
||||||
cleaned_data = super().clean()
|
cleaned_data = super().clean()
|
||||||
self.instance.transaction.last_name = cleaned_data["last_name"]
|
self.instance.transaction.last_name = cleaned_data["last_name"]
|
||||||
self.instance.transaction.first_name = cleaned_data["first_name"]
|
self.instance.transaction.first_name = cleaned_data["first_name"]
|
||||||
self.instance.transaction.bank = cleaned_data["bank"]
|
|
||||||
return cleaned_data
|
return cleaned_data
|
||||||
|
|
||||||
@transaction.atomic
|
@transaction.atomic
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
# Generated by Django 2.2.28 on 2022-08-06 13:33
|
# Generated by Django 2.2.28 on 2022-08-17 20:53
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
import django.core.validators
|
import django.core.validators
|
||||||
|
|
@ -12,7 +12,7 @@ class Migration(migrations.Migration):
|
||||||
initial = True
|
initial = True
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
('note', '0006_trust'),
|
('note', '0001_initial'),
|
||||||
]
|
]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
|
|
|
||||||
|
|
@ -118,5 +118,5 @@ class SpecialTransactionTable(tables.Table):
|
||||||
}
|
}
|
||||||
model = SpecialTransaction
|
model = SpecialTransaction
|
||||||
template_name = 'django_tables2/bootstrap4.html'
|
template_name = 'django_tables2/bootstrap4.html'
|
||||||
fields = ('created_at', 'source', 'destination', 'last_name', 'first_name', 'bank', 'amount', 'reason',)
|
fields = ('created_at', 'source', 'destination', 'last_name', 'first_name', 'amount', 'reason',)
|
||||||
order_by = ('-created_at',)
|
order_by = ('-created_at',)
|
||||||
|
|
|
||||||
|
|
@ -187,7 +187,6 @@ class TestRemittances(TestCase):
|
||||||
reason="Credit",
|
reason="Credit",
|
||||||
last_name="TOTO",
|
last_name="TOTO",
|
||||||
first_name="Toto",
|
first_name="Toto",
|
||||||
bank="Société générale",
|
|
||||||
)
|
)
|
||||||
|
|
||||||
self.second_credit = SpecialTransaction.objects.create(
|
self.second_credit = SpecialTransaction.objects.create(
|
||||||
|
|
@ -197,7 +196,6 @@ class TestRemittances(TestCase):
|
||||||
reason="Second credit",
|
reason="Second credit",
|
||||||
last_name="TOTO",
|
last_name="TOTO",
|
||||||
first_name="Toto",
|
first_name="Toto",
|
||||||
bank="Société générale",
|
|
||||||
)
|
)
|
||||||
|
|
||||||
self.remittance = Remittance.objects.create(
|
self.remittance = Remittance.objects.create(
|
||||||
|
|
@ -275,7 +273,6 @@ class TestRemittances(TestCase):
|
||||||
remittance=self.remittance.pk,
|
remittance=self.remittance.pk,
|
||||||
last_name="Last Name",
|
last_name="Last Name",
|
||||||
first_name="First Name",
|
first_name="First Name",
|
||||||
bank="Bank",
|
|
||||||
))
|
))
|
||||||
self.assertRedirects(response, reverse("treasury:remittance_list"), 302, 200)
|
self.assertRedirects(response, reverse("treasury:remittance_list"), 302, 200)
|
||||||
self.credit.refresh_from_db()
|
self.credit.refresh_from_db()
|
||||||
|
|
@ -320,8 +317,7 @@ class TestTreasuryAPI(TestAPI):
|
||||||
amount=4200,
|
amount=4200,
|
||||||
reason="Credit",
|
reason="Credit",
|
||||||
last_name="TOTO",
|
last_name="TOTO",
|
||||||
first_name="Toto",
|
first_name="Toto"
|
||||||
bank="Société générale",
|
|
||||||
)
|
)
|
||||||
|
|
||||||
self.remittance = Remittance.objects.create(
|
self.remittance = Remittance.objects.create(
|
||||||
|
|
@ -332,7 +328,7 @@ class TestTreasuryAPI(TestAPI):
|
||||||
self.credit.specialtransactionproxy.remittance = self.remittance
|
self.credit.specialtransactionproxy.remittance = self.remittance
|
||||||
self.credit.specialtransactionproxy.save()
|
self.credit.specialtransactionproxy.save()
|
||||||
|
|
||||||
self.kfet = Club.objects.get(name="Kfet")
|
self.kfet = Club.objects.get(name="BDA")
|
||||||
self.bde = self.kfet.parent_club
|
self.bde = self.kfet.parent_club
|
||||||
|
|
||||||
self.kfet_membership = Membership(
|
self.kfet_membership = Membership(
|
||||||
|
|
|
||||||
|
|
@ -174,7 +174,7 @@ class InvoiceUpdateView(ProtectQuerysetMixin, LoginRequiredMixin, UpdateView):
|
||||||
|
|
||||||
class InvoiceDeleteView(ProtectQuerysetMixin, LoginRequiredMixin, DeleteView):
|
class InvoiceDeleteView(ProtectQuerysetMixin, LoginRequiredMixin, DeleteView):
|
||||||
"""
|
"""
|
||||||
Delete a non-validated WEI registration
|
Delete a non-validated registration
|
||||||
"""
|
"""
|
||||||
model = Invoice
|
model = Invoice
|
||||||
extra_context = {"title": _("Delete invoice")}
|
extra_context = {"title": _("Delete invoice")}
|
||||||
|
|
@ -368,7 +368,6 @@ class LinkTransactionToRemittanceView(ProtectQuerysetMixin, LoginRequiredMixin,
|
||||||
form = context["form"]
|
form = context["form"]
|
||||||
form.fields["last_name"].initial = self.object.transaction.last_name
|
form.fields["last_name"].initial = self.object.transaction.last_name
|
||||||
form.fields["first_name"].initial = self.object.transaction.first_name
|
form.fields["first_name"].initial = self.object.transaction.first_name
|
||||||
form.fields["bank"].initial = self.object.transaction.bank
|
|
||||||
form.fields["amount"].initial = self.object.transaction.amount
|
form.fields["amount"].initial = self.object.transaction.amount
|
||||||
form.fields["remittance"].queryset = form.fields["remittance"] \
|
form.fields["remittance"].queryset = form.fields["remittance"] \
|
||||||
.queryset.filter(remittance_type__note=self.object.transaction.source)
|
.queryset.filter(remittance_type__note=self.object.transaction.source)
|
||||||
|
|
|
||||||
|
|
@ -148,29 +148,12 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
<div class="{% block containertype %}container{% endblock %} my-3">
|
<div class="{% block containertype %}container{% endblock %} my-3">
|
||||||
<div id="messages">
|
<div id="messages">
|
||||||
{% if user.is_authenticated %}
|
{% if user.is_authenticated %}
|
||||||
{% if not user|is_member:"BDE" %}
|
|
||||||
<div class="alert alert-danger">
|
|
||||||
{% trans "You are not a BDE member anymore. Please renew your membership if you want to use the note." %}
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if not user.profile.email_confirmed %}
|
{% if not user.profile.email_confirmed %}
|
||||||
<div class="alert alert-warning">
|
<div class="alert alert-warning">
|
||||||
{% trans "Your e-mail address is not validated. Please check your mail inbox and click on the validation link." %}
|
{% trans "Your e-mail address is not validated. Please check your mail inbox and click on the validation link." %}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if user.sogecredit and not user.sogecredit.valid %}
|
|
||||||
<div class="alert alert-info">
|
|
||||||
{% blocktrans trimmed %}
|
|
||||||
You declared that you opened a bank account in the Société générale. The bank did not validate
|
|
||||||
the creation of the account to the BDE, so the membership and the WEI are not paid yet.
|
|
||||||
This verification procedure may last a few days.
|
|
||||||
Please make sure that you go to the end of the account creation.
|
|
||||||
{% endblocktrans %}
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
{# TODO Add banners #}
|
|
||||||
</div>
|
</div>
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<p>Default content...</p>
|
<p>Default content...</p>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue