mirror of
				https://gitlab.com/animath/si/plateforme.git
				synced 2025-11-04 00:52:03 +01:00 
			
		
		
		
	Add button to update notes
Add jury president field for pools Signed-off-by: Emmy D'Anello <emmy.danello@animath.fr>
This commit is contained in:
		@@ -43,7 +43,7 @@ class SynthesisInline(admin.TabularInline):
 | 
			
		||||
class PoolInline(admin.TabularInline):
 | 
			
		||||
    model = Pool
 | 
			
		||||
    extra = 0
 | 
			
		||||
    autocomplete_fields = ('tournament', 'participations', 'juries',)
 | 
			
		||||
    autocomplete_fields = ('tournament', 'participations', 'jury_president', 'juries',)
 | 
			
		||||
    show_change_link = True
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -100,10 +100,10 @@ class ParticipationAdmin(admin.ModelAdmin):
 | 
			
		||||
 | 
			
		||||
@admin.register(Pool)
 | 
			
		||||
class PoolAdmin(admin.ModelAdmin):
 | 
			
		||||
    list_display = ('__str__', 'tournament', 'round', 'letter', 'teams',)
 | 
			
		||||
    list_display = ('__str__', 'tournament', 'round', 'letter', 'teams', 'jury_president',)
 | 
			
		||||
    list_filter = ('tournament', 'round', 'letter',)
 | 
			
		||||
    search_fields = ('participations__team__name', 'participations__team__trigram',)
 | 
			
		||||
    autocomplete_fields = ('tournament', 'participations', 'juries',)
 | 
			
		||||
    autocomplete_fields = ('tournament', 'participations', 'jury_president', 'juries',)
 | 
			
		||||
    inlines = (PassageInline, TweakInline,)
 | 
			
		||||
 | 
			
		||||
    @admin.display(description=_("teams"))
 | 
			
		||||
 
 | 
			
		||||
@@ -218,19 +218,19 @@ class AddJuryForm(forms.ModelForm):
 | 
			
		||||
            Div(
 | 
			
		||||
                Div(
 | 
			
		||||
                    Field('email', autofocus="autofocus", list="juries-email"),
 | 
			
		||||
                    css_class='col-md-5',
 | 
			
		||||
                    css_class='col-md-5 px-1',
 | 
			
		||||
                ),
 | 
			
		||||
                Div(
 | 
			
		||||
                    Field('first_name', list="juries-first-name"),
 | 
			
		||||
                    css_class='col-md-3',
 | 
			
		||||
                    css_class='col-md-3 px-1',
 | 
			
		||||
                ),
 | 
			
		||||
                Div(
 | 
			
		||||
                    Field('last_name', list="juries-last-name"),
 | 
			
		||||
                    css_class='col-md-3',
 | 
			
		||||
                    css_class='col-md-3 px-1',
 | 
			
		||||
                ),
 | 
			
		||||
                Div(
 | 
			
		||||
                    Submit('submit', _("Add")),
 | 
			
		||||
                    css_class='col-md-1 py-md-4',
 | 
			
		||||
                    css_class='col-md-1 py-md-4 px-1',
 | 
			
		||||
                ),
 | 
			
		||||
                css_class='row',
 | 
			
		||||
            )
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										27
									
								
								participation/migrations/0009_pool_jury_president.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								participation/migrations/0009_pool_jury_president.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
# Generated by Django 5.0.2 on 2024-03-24 14:31
 | 
			
		||||
 | 
			
		||||
import django.db.models.deletion
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("participation", "0008_alter_participation_options"),
 | 
			
		||||
        ("registration", "0012_payment_token_alter_payment_type"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name="pool",
 | 
			
		||||
            name="jury_president",
 | 
			
		||||
            field=models.ForeignKey(
 | 
			
		||||
                default=None,
 | 
			
		||||
                null=True,
 | 
			
		||||
                on_delete=django.db.models.deletion.SET_NULL,
 | 
			
		||||
                related_name="pools_presided",
 | 
			
		||||
                to="registration.volunteerregistration",
 | 
			
		||||
                verbose_name="president of the jury",
 | 
			
		||||
            ),
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
@@ -8,7 +8,7 @@ from django.conf import settings
 | 
			
		||||
from django.core.exceptions import ValidationError
 | 
			
		||||
from django.core.validators import MaxValueValidator, MinValueValidator, RegexValidator
 | 
			
		||||
from django.db import models
 | 
			
		||||
from django.db.models import Index
 | 
			
		||||
from django.db.models import F, Index, Q
 | 
			
		||||
from django.urls import reverse_lazy
 | 
			
		||||
from django.utils import timezone
 | 
			
		||||
from django.utils.crypto import get_random_string
 | 
			
		||||
@@ -543,6 +543,15 @@ class Pool(models.Model):
 | 
			
		||||
        verbose_name=_("juries"),
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    jury_president = models.ForeignKey(
 | 
			
		||||
        VolunteerRegistration,
 | 
			
		||||
        on_delete=models.SET_NULL,
 | 
			
		||||
        null=True,
 | 
			
		||||
        default=None,
 | 
			
		||||
        related_name="pools_presided",
 | 
			
		||||
        verbose_name=_("president of the jury"),
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    bbb_url = models.CharField(
 | 
			
		||||
        max_length=255,
 | 
			
		||||
        blank=True,
 | 
			
		||||
@@ -573,6 +582,11 @@ class Pool(models.Model):
 | 
			
		||||
    def get_absolute_url(self):
 | 
			
		||||
        return reverse_lazy("participation:pool_detail", args=(self.pk,))
 | 
			
		||||
 | 
			
		||||
    def validate_constraints(self, exclude=None):
 | 
			
		||||
        if self.jury_president not in self.juries.all():
 | 
			
		||||
            raise ValidationError({'jury_president': _("The president of the jury must be part of the jury.")})
 | 
			
		||||
        return super().validate_constraints()
 | 
			
		||||
 | 
			
		||||
    def __str__(self):
 | 
			
		||||
        return _("Pool of day {round} for tournament {tournament} with teams {teams}")\
 | 
			
		||||
            .format(round=self.round,
 | 
			
		||||
 
 | 
			
		||||
@@ -4,23 +4,53 @@
 | 
			
		||||
{% load i18n %}
 | 
			
		||||
 | 
			
		||||
{% block content %}
 | 
			
		||||
    <div class="alert alert-info">
 | 
			
		||||
        <p>
 | 
			
		||||
            {% blocktrans trimmed %}
 | 
			
		||||
            On this page, you can manage the juries of the pool. You can add a new jury by entering the email address
 | 
			
		||||
            of the jury. If the jury is not registered, the account will be created automatically. If the jury already
 | 
			
		||||
            exists, its account will be autocompleted and directly linked to the pool.
 | 
			
		||||
            {% endblocktrans %}
 | 
			
		||||
        </p>
 | 
			
		||||
    
 | 
			
		||||
        <p>
 | 
			
		||||
            {% blocktrans trimmed %}
 | 
			
		||||
            On this page, you can also define the president of the jury, who will have the right to see all solutions
 | 
			
		||||
            and if necessary define the notes of other jury members.
 | 
			
		||||
            {% endblocktrans %}
 | 
			
		||||
        </p>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <hr>
 | 
			
		||||
 | 
			
		||||
    {% for jury in pool.juries.all %}
 | 
			
		||||
        <div class="row my-3">
 | 
			
		||||
            <div class="col-md-5">
 | 
			
		||||
        <div class="row my-3 px-0">
 | 
			
		||||
            <div class="col-md-5 px-1">
 | 
			
		||||
                <input type="email" class="form-control" value="{{ jury.user.email }}" disabled>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="col-md-3">
 | 
			
		||||
            <div class="col-md-3 px-1">
 | 
			
		||||
                <input type="text" class="form-control" value="{{ jury.user.first_name }}" disabled>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="col-md-3">
 | 
			
		||||
            <div class="col-md-3 px-1">
 | 
			
		||||
                <input type="text" class="form-control" value="{{ jury.user.last_name }}" disabled>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="col-md-1">
 | 
			
		||||
                <a href="{% url 'participation:pool_remove_jury' pk=pool.pk  jury_id=jury.id %}" class="btn btn-danger">
 | 
			
		||||
                    Retirer
 | 
			
		||||
                </a>
 | 
			
		||||
            <div class="col-md-1 px-1">
 | 
			
		||||
                <div class="btn-group-vertical btn-group-sm">
 | 
			
		||||
                    {% if jury == pool.jury_president %}
 | 
			
		||||
                        <button class="btn btn-success">
 | 
			
		||||
                            <i class="fas fa-crown"></i> {% trans "PoJ" %}
 | 
			
		||||
                        </button>
 | 
			
		||||
                    {% else %}
 | 
			
		||||
                        <a href="{% url 'participation:pool_preside' pk=pool.pk jury_id=jury.id %}"
 | 
			
		||||
                                class="btn btn-warning">
 | 
			
		||||
                            <i class="fas fa-crown"></i> {% trans "Preside" %}
 | 
			
		||||
                        </a>
 | 
			
		||||
                    {% endif %}
 | 
			
		||||
                    <a href="{% url 'participation:pool_remove_jury' pk=pool.pk jury_id=jury.id %}"
 | 
			
		||||
                            class="btn btn-danger">
 | 
			
		||||
                        <i class="fas fa-trash"></i> {% trans "Remove" %}
 | 
			
		||||
                    </a>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
    {% endfor %}
 | 
			
		||||
 
 | 
			
		||||
@@ -7,10 +7,10 @@ from django.views.generic import TemplateView
 | 
			
		||||
from .views import CreateTeamView, FinalNotationSheetTemplateView, JoinTeamView, MyParticipationDetailView, \
 | 
			
		||||
    MyTeamDetailView, NoteUpdateView, ParticipationDetailView, PassageCreateView, PassageDetailView, \
 | 
			
		||||
    PassageUpdateView, PoolCreateView, PoolDetailView, PoolDownloadView, PoolJuryView, PoolNotesTemplateView, \
 | 
			
		||||
    PoolRemoveJuryView, PoolUpdateTeamsView, PoolUpdateView, PoolUploadNotesView, ScaleNotationSheetTemplateView, \
 | 
			
		||||
    SolutionUploadView, SynthesisUploadView, TeamAuthorizationsView, TeamDetailView, TeamLeaveView, TeamListView, \
 | 
			
		||||
    TeamUpdateView, TeamUploadMotivationLetterView, TournamentCreateView, TournamentDetailView, \
 | 
			
		||||
    TournamentExportCSVView, TournamentListView, TournamentPaymentsView, TournamentUpdateView
 | 
			
		||||
    PoolPresideJuryView, PoolRemoveJuryView, PoolUpdateTeamsView, PoolUpdateView, PoolUploadNotesView, \
 | 
			
		||||
    ScaleNotationSheetTemplateView, SolutionUploadView, SynthesisUploadView, TeamAuthorizationsView, TeamDetailView, \
 | 
			
		||||
    TeamLeaveView, TeamListView, TeamUpdateView, TeamUploadMotivationLetterView, TournamentCreateView, \
 | 
			
		||||
    TournamentDetailView, TournamentExportCSVView, TournamentListView, TournamentPaymentsView, TournamentUpdateView
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
app_name = "participation"
 | 
			
		||||
@@ -45,6 +45,7 @@ urlpatterns = [
 | 
			
		||||
    path("pools/<int:pk>/update-teams/", PoolUpdateTeamsView.as_view(), name="pool_update_teams"),
 | 
			
		||||
    path("pools/<int:pk>/jury/", PoolJuryView.as_view(), name="pool_jury"),
 | 
			
		||||
    path("pools/<int:pk>/jury/remove/<int:jury_id>/", PoolRemoveJuryView.as_view(), name="pool_remove_jury"),
 | 
			
		||||
    path("pools/<int:pk>/jury/preside/<int:jury_id>/", PoolPresideJuryView.as_view(), name="pool_preside"),
 | 
			
		||||
    path("pools/<int:pk>/upload-notes/", PoolUploadNotesView.as_view(), name="pool_upload_notes"),
 | 
			
		||||
    path("pools/<int:pk>/upload-notes/template/", PoolNotesTemplateView.as_view(), name="pool_notes_template"),
 | 
			
		||||
    path("pools/passages/add/<int:pk>/", PassageCreateView.as_view(), name="passage_create"),
 | 
			
		||||
 
 | 
			
		||||
@@ -885,6 +885,29 @@ class PoolRemoveJuryView(VolunteerMixin, DetailView):
 | 
			
		||||
        return redirect(reverse_lazy('participation:pool_jury', args=(pool.pk,)))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class PoolPresideJuryView(VolunteerMixin, DetailView):
 | 
			
		||||
    model = Pool
 | 
			
		||||
 | 
			
		||||
    def dispatch(self, request, *args, **kwargs):
 | 
			
		||||
        if not request.user.is_authenticated:
 | 
			
		||||
            return self.handle_no_permission()
 | 
			
		||||
        if request.user.registration.is_admin or request.user.registration.is_volunteer \
 | 
			
		||||
                and self.get_object().tournament in request.user.registration.organized_tournaments.all():
 | 
			
		||||
            return super().dispatch(request, *args, **kwargs)
 | 
			
		||||
        return self.handle_no_permission()
 | 
			
		||||
 | 
			
		||||
    def get(self, request, *args, **kwargs):
 | 
			
		||||
        pool = self.get_object()
 | 
			
		||||
        if not pool.juries.filter(pk=kwargs['jury_id']).exists():
 | 
			
		||||
            raise Http404
 | 
			
		||||
        jury = pool.juries.get(pk=kwargs['jury_id'])
 | 
			
		||||
        pool.jury_president = jury
 | 
			
		||||
        pool.save()
 | 
			
		||||
        messages.success(request, _("The jury {name} has been successfully promoted president!")
 | 
			
		||||
                         .format(name=f"{jury.user.first_name} {jury.user.last_name}"))
 | 
			
		||||
        return redirect(reverse_lazy('participation:pool_jury', args=(pool.pk,)))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class PoolUploadNotesView(VolunteerMixin, FormView, DetailView):
 | 
			
		||||
    model = Pool
 | 
			
		||||
    form_class = UploadNotesForm
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user