# Copyright (C) 2020 by Animath # SPDX-License-Identifier: GPL-3.0-or-later import re from bootstrap_datepicker_plus import DatePickerInput, DateTimePickerInput from django import forms from django.core.exceptions import ValidationError from django.utils import formats from django.utils.translation import gettext_lazy as _ from .models import Note, Participation, Passage, Pool, Solution, Synthesis, Team, Tournament class TeamForm(forms.ModelForm): """ Form to create a team, with the name and the trigram,... """ def clean_trigram(self): trigram = self.cleaned_data["trigram"].upper() if not re.match("[A-Z]{3}", trigram): raise ValidationError(_("The trigram must be composed of three uppercase letters.")) return trigram class Meta: model = Team fields = ('name', 'trigram',) class JoinTeamForm(forms.ModelForm): """ Form to join a team by the access code. """ def clean_access_code(self): access_code = self.cleaned_data["access_code"] if not Team.objects.filter(access_code=access_code).exists(): raise ValidationError(_("No team was found with this access code.")) return access_code def clean(self): cleaned_data = super().clean() if "access_code" in cleaned_data: team = Team.objects.get(access_code=cleaned_data["access_code"]) self.instance = team return cleaned_data class Meta: model = Team fields = ('access_code',) class ParticipationForm(forms.ModelForm): """ Form to update the problem of a team participation. """ class Meta: model = Participation fields = ('tournament',) class RequestValidationForm(forms.Form): """ Form to ask about validation. """ _form_type = forms.CharField( initial="RequestValidationForm", widget=forms.HiddenInput(), ) engagement = forms.BooleanField( label=_("I engage myself to participate to the whole TFJM²."), required=True, ) class ValidateParticipationForm(forms.Form): """ Form to let administrators to accept or refuse a team. """ _form_type = forms.CharField( initial="ValidateParticipationForm", widget=forms.HiddenInput(), ) message = forms.CharField( label=_("Message to address to the team:"), widget=forms.Textarea(), ) class TournamentForm(forms.ModelForm): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.fields["date_start"].widget = DatePickerInput( format=formats.get_format_lazy(format_type="DATE_INPUT_FORMATS", use_l10n=True)[0]) self.fields["date_end"].widget = DatePickerInput( format=formats.get_format_lazy(format_type="DATE_INPUT_FORMATS", use_l10n=True)[0]) self.fields["inscription_limit"].widget = DateTimePickerInput( format=formats.get_format_lazy(format_type="DATETIME_INPUT_FORMATS", use_l10n=True)[0]) self.fields["solution_limit"].widget = DateTimePickerInput( format=formats.get_format_lazy(format_type="DATETIME_INPUT_FORMATS", use_l10n=True)[0]) self.fields["solutions_draw"].widget = DateTimePickerInput( format=formats.get_format_lazy(format_type="DATETIME_INPUT_FORMATS", use_l10n=True)[0]) self.fields["syntheses_first_phase_limit"].widget = DateTimePickerInput( format=formats.get_format_lazy(format_type="DATETIME_INPUT_FORMATS", use_l10n=True)[0]) self.fields["solutions_available_second_phase"].widget = DateTimePickerInput( format=formats.get_format_lazy(format_type="DATETIME_INPUT_FORMATS", use_l10n=True)[0]) self.fields["syntheses_second_phase_limit"].widget = DateTimePickerInput( format=formats.get_format_lazy(format_type="DATETIME_INPUT_FORMATS", use_l10n=True)[0]) class Meta: model = Tournament fields = '__all__' class SolutionForm(forms.ModelForm): def save(self, commit=True): """ Don't save a solution with this way. Use a view instead """ class Meta: model = Solution fields = ('problem', 'file',) class PoolForm(forms.ModelForm): class Meta: model = Pool fields = ('tournament', 'round', 'juries',) widgets = { "juries": forms.CheckboxSelectMultiple, } class PoolTeamsForm(forms.ModelForm): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.fields["participations"].queryset = self.instance.tournament.participations.all() class Meta: model = Pool fields = ('participations',) widgets = { "participations": forms.CheckboxSelectMultiple, } class PassageForm(forms.ModelForm): def clean(self): cleaned_data = super().clean() if "defender" in cleaned_data and "opponent" in cleaned_data and "reporter" in cleaned_data \ and len({cleaned_data["defender"], cleaned_data["opponent"], cleaned_data["reporter"]}) < 3: self.add_error(None, _("The defender, the opponent and the reporter must be different.")) if "defender" in self.cleaned_data and "solution_number" in self.cleaned_data \ and not Solution.objects.filter(participation=cleaned_data["defender"], problem=cleaned_data["solution_number"]).exists(): self.add_error("solution_number", _("This defender did not work on this problem.")) return cleaned_data class Meta: model = Passage fields = ('solution_number', 'place', 'defender', 'opponent', 'reporter',) class SynthesisForm(forms.ModelForm): def save(self, commit=True): """ Don't save a synthesis with this way. Use a view instead """ class Meta: model = Synthesis fields = ('type', 'file',) class NoteForm(forms.ModelForm): class Meta: model = Note fields = ('defender_writing', 'defender_oral', 'opponent_writing', 'opponent_oral', 'reporter_writing', 'reporter_oral', )