diff --git a/apps/activity/models.py b/apps/activity/models.py index 29f04b39..cab229c4 100644 --- a/apps/activity/models.py +++ b/apps/activity/models.py @@ -139,7 +139,7 @@ class Entry(models.Model): verbose_name = _("entry") verbose_name_plural = _("entries") - def save(self, *args,**kwargs): + def save(self, *args, **kwargs): qs = Entry.objects.filter(~Q(pk=self.pk), activity=self.activity, note=self.note, guest=self.guest) if qs.exists(): @@ -153,7 +153,7 @@ class Entry(models.Model): if self.note.balance < 0: raise ValidationError(_("The balance is negative.")) - ret = super().save(*args,**kwargs) + ret = super().save(*args, **kwargs) if insert and self.guest: GuestTransaction.objects.create( diff --git a/apps/activity/views.py b/apps/activity/views.py index 14746929..12386bd1 100644 --- a/apps/activity/views.py +++ b/apps/activity/views.py @@ -45,8 +45,8 @@ class ActivityListView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableView context['title'] = _("Activities") upcoming_activities = Activity.objects.filter(date_end__gt=datetime.now()) - context['upcoming'] = ActivityTable(data=upcoming_activities - .filter(PermissionBackend.filter_queryset(self.request.user, Activity, "view"))) + context['upcoming'] = ActivityTable( + data=upcoming_activities.filter(PermissionBackend.filter_queryset(self.request.user, Activity, "view"))) return context @@ -153,9 +153,9 @@ class ActivityEntryView(LoginRequiredMixin, TemplateView): context["title"] = _('Entry for activity "{}"').format(activity.name) context["noteuser_ctype"] = ContentType.objects.get_for_model(NoteUser).pk context["notespecial_ctype"] = ContentType.objects.get_for_model(NoteSpecial).pk - + context["activities_open"] = Activity.objects.filter(open=True).filter( PermissionBackend.filter_queryset(self.request.user, Activity, "view")).filter( PermissionBackend.filter_queryset(self.request.user, Activity, "change")).all() - return context \ No newline at end of file + return context diff --git a/apps/treasury/views.py b/apps/treasury/views.py index 7361d1d2..8d744443 100644 --- a/apps/treasury/views.py +++ b/apps/treasury/views.py @@ -203,9 +203,9 @@ class RemittanceCreateView(ProtectQuerysetMixin, LoginRequiredMixin, CreateView) def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - context["table"] = RemittanceTable(data=Remittance.objects - .filter(PermissionBackend.filter_queryset(self.request.user, Remittance, "view")) - .all()) + context["table"] = RemittanceTable( + data=Remittance.objects.filter( + PermissionBackend.filter_queryset(self.request.user, Remittance, "view")).all()) context["special_transactions"] = SpecialTransactionTable(data=SpecialTransaction.objects.none()) return context diff --git a/apps/wei/__init__.py b/apps/wei/__init__.py new file mode 100644 index 00000000..ad360dae --- /dev/null +++ b/apps/wei/__init__.py @@ -0,0 +1,4 @@ +# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay +# SPDX-License-Identifier: GPL-3.0-or-later + +default_app_config = 'wei.apps.WeiConfig' diff --git a/apps/wei/admin.py b/apps/wei/admin.py new file mode 100644 index 00000000..4e945ad5 --- /dev/null +++ b/apps/wei/admin.py @@ -0,0 +1,2 @@ +# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay +# SPDX-License-Identifier: GPL-3.0-or-later diff --git a/apps/wei/apps.py b/apps/wei/apps.py new file mode 100644 index 00000000..f6332232 --- /dev/null +++ b/apps/wei/apps.py @@ -0,0 +1,11 @@ +# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay +# SPDX-License-Identifier: GPL-3.0-or-later + +from django.apps import AppConfig +from django.utils.translation import gettext_lazy as _ + + +class WeiConfig(AppConfig): + name = 'wei' + verbose_name = _('WEI') + diff --git a/apps/wei/migrations/__init__.py b/apps/wei/migrations/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/apps/wei/models.py b/apps/wei/models.py new file mode 100644 index 00000000..910f8309 --- /dev/null +++ b/apps/wei/models.py @@ -0,0 +1,243 @@ +# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay +# SPDX-License-Identifier: GPL-3.0-or-later + +from django.contrib.auth.models import User +from django.db import models +from django.utils.translation import gettext_lazy as _ + +from note.models import NoteSpecial + + +class WEI(models.Model): + """ + Store WEI information + """ + name = models.CharField( + max_length=255, + unique=True, + verbose_name=_("name"), + ) + + year = models.PositiveIntegerField( + unique=True, + verbose_name=_("year"), + ) + + start = models.DateField( + verbose_name=_("start date"), + ) + + end = models.DateField( + verbose_name=_("end date"), + ) + + price_paid = models.PositiveIntegerField( + verbose_name=_("Price for paid students"), + ) + + price_unpaid = models.PositiveIntegerField( + verbose_name=_("Price for unpaid students"), + ) + + email = models.EmailField( + verbose_name=_("contact email"), + ) + + registrations_open = models.BooleanField( + verbose_name=_("registrations open"), + ) + + def __str__(self): + return self.name + + class Meta: + verbose_name = _("WEI") + verbose_name_plural = _("WEI") + + +class Bus(models.Model): + """ + The best bus for the best WEI + """ + wei = models.ForeignKey( + WEI, + on_delete=models.PROTECT, + related_name="buses", + verbose_name=_("WEI"), + ) + + name = models.CharField( + max_length=255, + verbose_name=_("name"), + ) + + def __str__(self): + return self.name + + class Meta: + unique_together = ('wei', 'name',) + + +class BusTeam(models.Model): + """ + A bus has multiple teams + """ + bus = models.ForeignKey( + Bus, + on_delete=models.CASCADE, + related_name="teams", + verbose_name=_("bus"), + ) + + name = models.CharField( + max_length=255, + ) + + color = models.PositiveIntegerField( # Use a color picker to get the hexa code + verbose_name=_("color"), + help_text=_("The color of the T-Shirt, stored with its number equivalent"), + ) + + def __str__(self): + return self.name + " (" + str(self.bus) + ")" + + class Meta: + unique_together = ('bus', 'name',) + verbose_name = _("Bus team") + verbose_name_plural = _("Bus teams") + + +class WEIRole(models.Model): + """ + A Role for the WEI can be bus chief, team chief, free electron, ... + """ + name = models.CharField( + max_length=255, + unique=True, + ) + + +class WEIUser(models.Model): + """ + Store personal data that can be useful for the WEI. + """ + + user = models.ForeignKey( + User, + on_delete=models.PROTECT, + related_name="wei", + verbose_name=_("user"), + ) + + wei = models.ForeignKey( + WEI, + on_delete=models.PROTECT, + related_name="users", + verbose_name=_("WEI"), + ) + + role = models.ForeignKey( + WEIRole, + on_delete=models.PROTECT, + verbose_name=_("role"), + ) + + birth_date = models.DateField( + verbose_name=_("birth date"), + ) + + gender = models.CharField( + max_length=16, + choices=( + ('male', _("Male")), + ('female', _("Female")), + ('nonbinary', _("Non binary")), + ), + verbose_name=_("gender"), + ) + + health_issues = models.TextField( + verbose_name=_("health issues"), + ) + + emergency_contact_name = models.CharField( + max_length=255, + verbose_name=_("emergency contact name"), + ) + + emergency_contact_phone = models.CharField( + max_length=32, + verbose_name=_("emergency contact phone"), + ) + + payment_method = models.ForeignKey( + NoteSpecial, + on_delete=models.PROTECT, + null=True, # null = no credit, paid with note + related_name="+", + verbose_name=_("payment method"), + ) + + soge_credit = models.BooleanField( + verbose_name=_("Credit from Société générale"), + ) + + ml_events_registation = models.BooleanField( + verbose_name=_("Register on the mailing list to stay informed of the events of the campus (1 mail/week)"), + ) + + ml_sport_registation = models.BooleanField( + verbose_name=_("Register on the mailing list to stay informed of the sport events of the campus (1 mail/week)"), + ) + + ml_art_registation = models.BooleanField( + verbose_name=_("Register on the mailing list to stay informed of the art events of the campus (1 mail/week)"), + ) + + team = models.ForeignKey( + BusTeam, + on_delete=models.PROTECT, + related_name="users", + null=True, + blank=True, + verbose_name=_("team"), + ) + + bus_choice1 = models.ForeignKey( + Bus, + on_delete=models.PROTECT, + related_name="+", + verbose_name=_("bus choice 1"), + ) + + bus_choice2 = models.ForeignKey( + Bus, + on_delete=models.PROTECT, + related_name="+", + null=True, + blank=True, + verbose_name=_("bus choice 2"), + ) + + bus_choice3 = models.ForeignKey( + Bus, + on_delete=models.PROTECT, + related_name="+", + null=True, + blank=True, + verbose_name=_("bus choice 3"), + ) + + asked_roles = models.ManyToManyField( + WEIRole, + related_name="+", + verbose_name=_("asked roles"), + ) + + def __str__(self): + return str(self.user) + + class Meta: + unique_together = ('user', 'wei',) + verbose_name = _("WEI User") + verbose_name_plural = _("WEI Users") diff --git a/apps/wei/urls.py b/apps/wei/urls.py new file mode 100644 index 00000000..afd1c566 --- /dev/null +++ b/apps/wei/urls.py @@ -0,0 +1,9 @@ +# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay +# SPDX-License-Identifier: GPL-3.0-or-later + +from django.urls import path + + +app_name = 'wei' +urlpatterns = [ +] diff --git a/apps/wei/views.py b/apps/wei/views.py new file mode 100644 index 00000000..8b245779 --- /dev/null +++ b/apps/wei/views.py @@ -0,0 +1,5 @@ +# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay +# SPDX-License-Identifier: GPL-3.0-or-later + +from django.shortcuts import render + diff --git a/note_kfet/settings/base.py b/note_kfet/settings/base.py index 283f8e56..5ed8b1d8 100644 --- a/note_kfet/settings/base.py +++ b/note_kfet/settings/base.py @@ -62,6 +62,7 @@ INSTALLED_APPS = [ 'permission', 'registration', 'treasury', + 'wei', ] LOGIN_REDIRECT_URL = '/note/transfer/' diff --git a/note_kfet/urls.py b/note_kfet/urls.py index 90d44a07..4311c0b5 100644 --- a/note_kfet/urls.py +++ b/note_kfet/urls.py @@ -19,6 +19,7 @@ urlpatterns = [ path('registration/', include('registration.urls')), path('activity/', include('activity.urls')), path('treasury/', include('treasury.urls')), + path('wei/', include('wei.urls')), # Include Django Contrib and Core routers path('i18n/', include('django.conf.urls.i18n')),