diff --git a/profiles/migrations/0016_auto_20211225_1242.py b/profiles/migrations/0016_auto_20211225_1242.py new file mode 100644 index 0000000000000000000000000000000000000000..5a74061e2a7434166c44f73b521ce36c4bf7504e --- /dev/null +++ b/profiles/migrations/0016_auto_20211225_1242.py @@ -0,0 +1,18 @@ +# Generated by Django 2.2 on 2021-12-25 11:42 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('profiles', '0015_student_updated_date'), + ] + + operations = [ + migrations.AlterField( + model_name='tutor', + name='promotion', + field=models.IntegerField(choices=[(2024, '2024'), (2023, '2023'), (2022, '2022'), (2021, '2021'), (2020, '2020')], default=2024), + ), + ] diff --git a/visits/admin.py b/visits/admin.py index 99427d63a4a26b1fd3aee8449d3c387960cd7eec..3e2376a8db9efcf944ebf26939811a48f3e1b553 100644 --- a/visits/admin.py +++ b/visits/admin.py @@ -63,7 +63,6 @@ class RegistrationsOpenFilter(admin.SimpleListFilter): class VisitForm(forms.ModelForm): """Custom admin form for Visit.""" - class Meta: # noqa model = Visit fields = '__all__' @@ -107,18 +106,18 @@ class ParticipationInline(admin.TabularInline): def school(self, participation: Participation): """Return a link to the participation's user's school.""" - school = Student.objects.get(user = participation.user).school + school = Student.objects.get(user=participation.user).school return school school.short_description = "Établissement" - def name(self, participation: Participation): """Returns the participation's user's name""" return participation.user.first_name + " " + participation.user.last_name name.short_description = "Nom" class Media: - css = { "all" : ("css/hide_admin_original.css",) } + css = {"all": ("css/hide_admin_original.css",)} + def accept_selected_participations(modeladmin, request, queryset): """Accept selected participations in list view.""" @@ -143,12 +142,25 @@ def reject_selected_participations(modeladmin, request, queryset): count = queryset.count() s = pluralize(count) messages.add_message(request, messages.SUCCESS, - f'{count} participation{s} acceptée{s} avec succès.') + f'{count} participation{s} rejetée{s} avec succès.') ## rejeté place accepté reject_selected_participations.short_description = ( 'Rejeter les participations sélectionnées') +def wait_selected_participations(modeladmin, request, queryset): + """Reject selected participations in list view.""" + for obj in queryset: + obj.accepted = 2 #in wait + obj.save() + count = queryset.count() + s = pluralize(count) + messages.add_message(request, messages.SUCCESS, + f'{count} participation{s} en attente{s} avec succès.') + + +wait_selected_participations.short_description = ( + 'Mettre en attentes les participations sélectionnées') @admin.register(Participation) class ParticipationAdmin(admin.ModelAdmin): diff --git a/visits/migrations/0003_auto_20211225_1242.py b/visits/migrations/0003_auto_20211225_1242.py new file mode 100644 index 0000000000000000000000000000000000000000..bacb64cbecebd0f6a14b7fb1e37cfa056abddaea --- /dev/null +++ b/visits/migrations/0003_auto_20211225_1242.py @@ -0,0 +1,18 @@ +# Generated by Django 2.2 on 2021-12-25 11:42 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('visits', '0002_visit_context_sheet'), + ] + + operations = [ + migrations.AlterField( + model_name='participation', + name='accepted', + field=models.IntegerField(choices=[(0, 'refusé'), (1, 'accepté'), (2, 'en attente')], default=0, help_text='Cocher pour confirmer au tutoré sa participation à la sortie.'), + ), + ] diff --git a/visits/models.py b/visits/models.py index 7c5a8f8885b8a2393d9ddc967addbb506327996e..65fb58b98c7a359223205b32bfdba128a42a2a32 100644 --- a/visits/models.py +++ b/visits/models.py @@ -42,7 +42,11 @@ class Participation(models.Model): Allows to store whether the user was present to the visit, and whether their files were validated. """ - + STATUS_CHOICES = ( + ( 0 , 'refusé' ), + ( 1 , 'accepté' ), + ( 2 , 'en attente' ), + ) user = models.ForeignKey('users.User', verbose_name='utilisateur', related_name='participations', on_delete=models.CASCADE, null=True) @@ -53,8 +57,9 @@ class Participation(models.Model): auto_now_add=True, null=True, verbose_name='soumis le', help_text='Date de soumission de la participation') - accepted = models.NullBooleanField( - 'accepté', + accepted = models.IntegerField( + default=0, + choices=STATUS_CHOICES, help_text=( "Cocher pour confirmer au tutoré sa participation à la sortie.")) present = models.NullBooleanField( diff --git a/visits/notifications.py b/visits/notifications.py index da91e740ae79a7aa3925fe4cc704ccf68fe8dca3..13e25da73177cc1ff53ffd76903c7468d9c8ba20 100644 --- a/visits/notifications.py +++ b/visits/notifications.py @@ -32,7 +32,28 @@ class ConfirmParticipation(Notification): template_name = 'visits/confirm_participation.md' args = ('participation',) + + def get_subject(self): + return f'Participation à la sortie : {self.participation.visit}' + + def get_recipients(self): + return [self.participation.user.email] + + @classmethod + def example(cls): + user = User(email='john.doe@example.com', first_name='John') + visit = Visit(title='Visite du Palais de la Découverte', date=now()) + participation = Participation( + user=user, visit=visit, accepted=True, submitted=now()) + return cls(participation=participation) + + +class ConfirmParticipationWait(Notification): + """ConfirmParticipation whether a user can participate to a visit.""" + template_name = 'visits/confirm_participation_wait.md' + args = ('participation',) + def get_subject(self): return f'Participation à la sortie : {self.participation.visit}' diff --git a/visits/signals.py b/visits/signals.py index 3527e3fabf3d90bf5a1108e7a1905984748e060b..49653bef932951ccb827ab84958c3792a191fad3 100644 --- a/visits/signals.py +++ b/visits/signals.py @@ -5,6 +5,7 @@ from django.dispatch import Signal, receiver from .models import Participation from .notifications import ConfirmParticipation +from .notifications import ConfirmParticipationWait accepted_changed = Signal() @@ -24,4 +25,7 @@ def notify_participation(sender, instance: Participation, **kwargs): """ if instance.accepted is None: return - ConfirmParticipation(participation=instance).send() + if instance.accepted == 2 : + ConfirmParticipationWait(participation=instance).send() + else : + ConfirmParticipation(participation=instance).send() diff --git a/visits/templates/visits/confirm_participation.md b/visits/templates/visits/confirm_participation.md index 01466352b7109e7616e393a213df1f23ebb96964..60ad2fd979ee5459f17ecc4e90ac26689d6a8e55 100644 --- a/visits/templates/visits/confirm_participation.md +++ b/visits/templates/visits/confirm_participation.md @@ -7,7 +7,11 @@ Bonjour{% if participation.user.first_name %} {{ participation.user.first_name } {% block body %} {% if participation.submitted %}Le {{ participation.submitted|date }}, tu{% else %}Tu{% endif%} as demandé à t'inscrire à la sortie **{{ participation.visit }}** organisée le **{{ participation.visit.date|date }}**. + + {% if participation.accepted %} + + Bonne nouvelle : nous avons validé ta participation à la sortie. ✅ Avant la sortie, tu pourras, en te rendant sur [l'espace sorties]({{ participation.visit.get_site_url }}) : @@ -16,6 +20,7 @@ Avant la sortie, tu pourras, en te rendant sur [l'espace sorties]({{ participati - Télécharger la fiche sortie ; - Télécharger l'autorisation de sortie, à faire remplir par tes parents. + {% else %} Malheureusement, en raison du nombre de places limité, tu ne pourras pas participer à cette sortie. 😔 diff --git a/visits/templates/visits/confirm_participation_wait.md b/visits/templates/visits/confirm_participation_wait.md new file mode 100644 index 0000000000000000000000000000000000000000..6d704cc618a330ffe1308646b67940ac46777227 --- /dev/null +++ b/visits/templates/visits/confirm_participation_wait.md @@ -0,0 +1,22 @@ +{% extends 'mails/notification.md' %} + +{% block greeting %} +Bonjour{% if participation.user.first_name %} {{ participation.user.first_name }}{% endif %}, +{% endblock %} + +{% block body %} +{% if participation.submitted %}Le {{ participation.submitted|date }}, tu{% else %}Tu{% endif%} as demandé à t'inscrire à la sortie **{{ participation.visit }}** organisée le **{{ participation.visit.date|date }}**. + + +Malheureusement, en raison du nombre de places limité, tu es sur liste d'attente pour participer à cette sortie. 😔 + +Nous te recontacterons si des places se libèrent suite à des désistements. + +{% endblock %} + +{% block signature %} +À très bientôt, +Les organisateurs + +Nous contacter : oser.sortie@gmail.fr +{% endblock %}