mirror of
				https://gitlab.com/animath/si/plateforme.git
				synced 2025-11-01 00:24:29 +01:00 
			
		
		
		
	Bouton pour rendre les solutions accessibles pour le second tour en 1 clic
This commit is contained in:
		
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -440,6 +440,10 @@ class Tournament(models.Model): | ||||
|             return Participation.objects.filter(final=True) | ||||
|         return self.participation_set | ||||
|  | ||||
|     @property | ||||
|     def organizers_and_presidents(self): | ||||
|         return VolunteerRegistration.objects.filter(Q(admin=True) | Q(organized_tournaments=self) | Q(pools_presided__tournament=self)) | ||||
|  | ||||
|     @property | ||||
|     def solutions(self): | ||||
|         if self.final: | ||||
|   | ||||
| @@ -23,44 +23,80 @@ | ||||
|                     <dd class="col-sm-6">{% if tournament.price %}{{ tournament.price }} €{% else %}{% trans "Free" %}{% endif %}</dd> | ||||
|                 {% endif %} | ||||
|  | ||||
|                 <dt class="col-sm-6 text-sm-end">{% trans 'remote'|capfirst %}</dt> | ||||
|                 <dt class="col-sm-6 text-sm-end">{% trans "remote"|capfirst %}</dt> | ||||
|                 <dd class="col-sm-6">{{ tournament.remote|yesno }}</dd> | ||||
|  | ||||
|                 <dt class="col-sm-6 text-sm-end">{% trans 'dates'|capfirst %}</dt> | ||||
|                 <dt class="col-sm-6 text-sm-end">{% trans "dates"|capfirst %}</dt> | ||||
|                 <dd class="col-sm-6">{% trans "From" %} {{ tournament.date_start }} {% trans "to" %} {{ tournament.date_end }}</dd> | ||||
|  | ||||
|                 <dt class="col-sm-6 text-sm-end">{% trans 'date of registration closing'|capfirst %}</dt> | ||||
|                 <dt class="col-sm-6 text-sm-end">{% trans "date of registration closing"|capfirst %}</dt> | ||||
|                 <dd class="col-sm-6">{{ tournament.inscription_limit }}</dd> | ||||
|  | ||||
|                 <dt class="col-sm-6 text-sm-end">{% trans 'date of maximal solution submission'|capfirst %}</dt> | ||||
|                 <dt class="col-sm-6 text-sm-end">{% trans "date of maximal solution submission"|capfirst %}</dt> | ||||
|                 <dd class="col-sm-6">{{ tournament.solution_limit }}</dd> | ||||
|  | ||||
|                 <dt class="col-sm-6 text-sm-end">{% trans 'date of the random draw'|capfirst %}</dt> | ||||
|                 <dt class="col-sm-6 text-sm-end">{% trans "date of the random draw"|capfirst %}</dt> | ||||
|                 <dd class="col-sm-6">{{ tournament.solutions_draw }}</dd> | ||||
|  | ||||
|                 <dt class="col-sm-6 text-sm-end">{% trans 'date of maximal written reviews submission for the first round'|capfirst %}</dt> | ||||
|                 <dt class="col-sm-6 text-sm-end">{% trans "date of maximal written reviews submission for the first round"|capfirst %}</dt> | ||||
|                 <dd class="col-sm-6">{{ tournament.reviews_first_phase_limit }}</dd> | ||||
|  | ||||
|                 <dt class="col-sm-6 text-sm-end">{% trans 'date of maximal written reviews submission for the second round'|capfirst %}</dt> | ||||
|                 <dt class="col-sm-6 text-sm-end">{% trans "Solutions available for the second round" %}</dt> | ||||
|                 <dd class="col-sm-6"> | ||||
|                     {{ tournament.solutions_available_second_phase|yesno }} | ||||
|                     {% if user.is_authenticated and user.registration in tournament.organizers_and_presidents.all %} | ||||
|                         {% now 'Y-m-d' as today %} | ||||
|                         {% if not tournament.solutions_available_second_phase %} | ||||
|                             {% if today >= tournament.date_first_phase|date:"Y-m-d" %} | ||||
|                                 <a href="{% url 'participation:tournament_publish_solutions' pk=tournament.pk round=2 %}" class="btn btn-sm btn-info"><i class="fas fa-eye"></i> {% trans "Publish" %}</a> | ||||
|                             {% endif %} | ||||
|                         {% else %} | ||||
|                             {% if today <= tournament.date_second_phase|date:"Y-m-d" %} | ||||
|                                 <a href="{% url 'participation:tournament_publish_solutions' pk=tournament.pk round=2 %}?hide" class="btn btn-sm bg-danger"><i class="fas fa-eye-slash"></i> {% trans "Unpublish" %}</a> | ||||
|                             {% endif %} | ||||
|                         {% endif %} | ||||
|                     {% endif %} | ||||
|                 </dd> | ||||
|  | ||||
|                 <dt class="col-sm-6 text-sm-end">{% trans "date of maximal written reviews submission for the second round"|capfirst %}</dt> | ||||
|                 <dd class="col-sm-6">{{ tournament.reviews_second_phase_limit }}</dd> | ||||
|  | ||||
|                 {% if TFJM.APP == "ETEAM" %} | ||||
|                     <dt class="col-sm-6 text-sm-end">{% trans 'date of maximal written reviews submission for the third round'|capfirst %}</dt> | ||||
|                 {% if TFJM.NB_ROUNDS == 3 %} | ||||
|                     <dt class="col-sm-6 text-sm-end">{% trans "Solutions available for the third round" %}</dt> | ||||
|                     <dd class="col-sm-6"> | ||||
|                         {{ tournament.solutions_available_third_phase|yesno }} | ||||
|                         {% if tournament.solutions_available_second_phase and user.is_authenticated and user.registration in tournament.organizers_and_presidents.all %} | ||||
|                             {% now 'Y-m-d' as today %} | ||||
|                             {% if not tournament.solutions_available_third_phase %} | ||||
|                                 {% if today >= tournament.date_second_phase|date:"Y-m-d" %} | ||||
|                                     <a href="{% url 'participation:tournament_publish_solutions' pk=tournament.pk round=3 %}" class="btn btn-sm btn-info"><i class="fas fa-eye"></i> {% trans "Publish" %}</a> | ||||
|                                 {% endif %} | ||||
|                             {% else %} | ||||
|                                 {% if today <= tournament.date_third_phase|date:"Y-m-d" %} | ||||
|                                     <a href="{% url 'participation:tournament_publish_solutions' pk=tournament.pk round=3 %}?hide" class="btn btn-sm bg-danger"><i class="fas fa-eye-slash"></i> {% trans "Unpublish" %}</a> | ||||
|                                 {% endif %} | ||||
|                             {% endif %} | ||||
|                         {% endif %} | ||||
|                     </dd> | ||||
|  | ||||
|                     <dt class="col-sm-6 text-sm-end">{% trans "date of maximal written reviews submission for the third round"|capfirst %}</dt> | ||||
|                     <dd class="col-sm-6">{{ tournament.reviews_third_phase_limit }}</dd> | ||||
|                 {% endif %} | ||||
|  | ||||
|                 <dt class="col-sm-6 text-sm-end">{% trans 'description'|capfirst %}</dt> | ||||
|                 <dt class="col-sm-6 text-sm-end">{% trans "description"|capfirst %}</dt> | ||||
|                 <dd class="col-sm-6">{{ tournament.description }}</dd> | ||||
|  | ||||
|                 {% if TFJM.ML_MANAGEMENT %} | ||||
|                     <dt class="col-sm-6 text-sm-end">{% trans 'To contact organizers' %}</dt> | ||||
|                     <dt class="col-sm-6 text-sm-end">{% trans "To contact organizers" %}</dt> | ||||
|                     <dd class="col-sm-6"><a href="mailto:{{ tournament.organizers_email }}">{{ tournament.organizers_email }}</a></dd> | ||||
|  | ||||
|                     <dt class="col-sm-6 text-sm-end">{% trans 'To contact juries' %}</dt> | ||||
|                     <dd class="col-sm-6"><a href="mailto:{{ tournament.jurys_email }}">{{ tournament.jurys_email }}</a></dd> | ||||
|                     {% if user.is_authenticated and user.registration.is_volunteer %} | ||||
|                         <dt class="col-sm-6 text-sm-end">{% trans "To contact juries" %}</dt> | ||||
|                         <dd class="col-sm-6"><a href="mailto:{{ tournament.jurys_email }}">{{ tournament.jurys_email }}</a></dd> | ||||
|  | ||||
|                     <dt class="col-sm-6 text-sm-end">{% trans 'To contact valid teams' %}</dt> | ||||
|                     <dd class="col-sm-6"><a href="mailto:{{ tournament.teams_email }}">{{ tournament.teams_email }}</a></dd> | ||||
|                         <dt class="col-sm-6 text-sm-end">{% trans "To contact valid teams" %}</dt> | ||||
|                         <dd class="col-sm-6"><a href="mailto:{{ tournament.teams_email }}">{{ tournament.teams_email }}</a></dd> | ||||
|                     {% endif %} | ||||
|                 {% endif %} | ||||
|             </dl> | ||||
|         </div> | ||||
| @@ -199,7 +235,7 @@ | ||||
|                     </div> | ||||
|                 </div> | ||||
|             {% endif %} | ||||
|         </div> | ||||
|             </div> | ||||
|     {% endif %} | ||||
|  | ||||
|     {% if user.registration.is_admin or user.registration in tournament.organizers.all %} | ||||
|   | ||||
| @@ -12,7 +12,7 @@ from .views import CreateTeamView, FinalNotationSheetTemplateView, GSheetNotific | ||||
|     TeamAuthorizationsView, TeamDetailView, TeamLeaveView, TeamListView, TeamUpdateView, \ | ||||
|     TeamUploadMotivationLetterView, TournamentCreateView, TournamentDetailView, TournamentExportCSVView, \ | ||||
|     TournamentHarmonizeNoteView, TournamentHarmonizeView, TournamentListView, TournamentPaymentsView, \ | ||||
|     TournamentPublishNotesView, TournamentUpdateView, WrittenReviewUploadView | ||||
|     TournamentPublishNotesView, TournamentPublishSolutionsView, TournamentUpdateView, WrittenReviewUploadView | ||||
|  | ||||
|  | ||||
| app_name = "participation" | ||||
| @@ -48,6 +48,8 @@ urlpatterns = [ | ||||
|          name="tournament_notation_sheets"), | ||||
|     path("tournament/<int:pk>/notation/notifications/", GSheetNotificationsView.as_view(), | ||||
|          name="tournament_gsheet_notifications"), | ||||
|     path("tournament/<int:pk>/publish-solutions/<int:round>/", TournamentPublishSolutionsView.as_view(), | ||||
|          name="tournament_publish_solutions"), | ||||
|     path("tournament/<int:pk>/publish-notes/<int:round>/", TournamentPublishNotesView.as_view(), | ||||
|          name="tournament_publish_notes"), | ||||
|     path("tournament/<int:pk>/harmonize/<int:round>/", TournamentHarmonizeView.as_view(), | ||||
|   | ||||
| @@ -747,12 +747,12 @@ class TournamentPublishNotesView(VolunteerMixin, SingleObjectMixin, RedirectView | ||||
|             return self.handle_no_permission() | ||||
|         tournament = self.get_object() | ||||
|         reg = request.user.registration | ||||
|         if not reg.is_admin and (not reg.is_volunteer or tournament not in reg.organized_tournaments.all()): | ||||
|         if not reg.is_volunteer or reg not in tournament.organizers_and_presidents.all(): | ||||
|             return self.handle_no_permission() | ||||
|         return super().dispatch(request, *args, **kwargs) | ||||
|  | ||||
|     def get(self, request, *args, **kwargs): | ||||
|         if int(kwargs["round"]) not in (1, 2): | ||||
|         if int(kwargs["round"]) not in range(1, settings.NB_ROUNDS): | ||||
|             raise Http404 | ||||
|  | ||||
|         tournament = Tournament.objects.get(pk=kwargs["pk"]) | ||||
| @@ -767,6 +767,45 @@ class TournamentPublishNotesView(VolunteerMixin, SingleObjectMixin, RedirectView | ||||
|         return reverse_lazy("participation:tournament_detail", args=(kwargs['pk'],)) | ||||
|  | ||||
|  | ||||
| class TournamentPublishSolutionsView(VolunteerMixin, SingleObjectMixin, RedirectView): | ||||
|     """ | ||||
|     On rend les solutions du tour suivant accessibles aux équipes. | ||||
|     """ | ||||
|     model = Tournament | ||||
|  | ||||
|     def dispatch(self, request, *args, **kwargs): | ||||
|         """ | ||||
|         Les admins, orgas et PJ peuvent rendre les solutions accessibles. | ||||
|         """ | ||||
|         if not request.user.is_authenticated: | ||||
|             return self.handle_no_permission() | ||||
|         tournament = self.get_object() | ||||
|         reg = request.user.registration | ||||
|         if not reg.is_volunteer or reg not in tournament.organizers_and_presidents.all(): | ||||
|             return self.handle_no_permission() | ||||
|         return super().dispatch(request, *args, **kwargs) | ||||
|  | ||||
|     def get(self, request, *args, **kwargs): | ||||
|         if int(kwargs["round"]) not in range(2, settings.NB_ROUNDS + 1): | ||||
|             raise Http404 | ||||
|  | ||||
|         tournament = Tournament.objects.get(pk=kwargs["pk"]) | ||||
|         publish_solutions = 'hide' not in request.GET | ||||
|         if int(kwargs['round']) == 2: | ||||
|             tournament.solutions_available_second_phase = publish_solutions | ||||
|         elif int(kwargs['round']) == 3: | ||||
|             tournament.solutions_available_third_phase = publish_solutions | ||||
|         tournament.save() | ||||
|         if 'hide' not in request.GET: | ||||
|             messages.success(request, _("Solutions are now available to teams!")) | ||||
|         else: | ||||
|             messages.warning(request, _("Solutions are not available to teams anymore.")) | ||||
|         return super().get(request, *args, **kwargs) | ||||
|  | ||||
|     def get_redirect_url(self, *args, **kwargs): | ||||
|         return reverse_lazy("participation:tournament_detail", args=(kwargs['pk'],)) | ||||
|  | ||||
|  | ||||
| class TournamentHarmonizeView(VolunteerMixin, DetailView): | ||||
|     """ | ||||
|     Harmonize the notes of a tournament. | ||||
| @@ -779,7 +818,7 @@ class TournamentHarmonizeView(VolunteerMixin, DetailView): | ||||
|             return self.handle_no_permission() | ||||
|         tournament = self.get_object() | ||||
|         reg = request.user.registration | ||||
|         if not reg.is_admin and (not reg.is_volunteer or tournament not in reg.organized_tournaments.all()): | ||||
|         if not reg.is_volunteer or reg not in tournament.organizers_and_presidents.all(): | ||||
|             return self.handle_no_permission() | ||||
|         if self.kwargs['round'] not in range(1, settings.NB_ROUNDS + 1): | ||||
|             raise Http404 | ||||
| @@ -812,7 +851,7 @@ class TournamentHarmonizeNoteView(VolunteerMixin, DetailView): | ||||
|             return self.handle_no_permission() | ||||
|         tournament = self.get_object() | ||||
|         reg = request.user.registration | ||||
|         if not reg.is_admin and (not reg.is_volunteer or tournament not in reg.organized_tournaments.all()): | ||||
|         if not reg.is_volunteer or reg not in tournament.organizers_and_presidents.all(): | ||||
|             return self.handle_no_permission() | ||||
|         if self.kwargs['round'] not in range(1, settings.NB_ROUNDS + 1) \ | ||||
|                 or self.kwargs['action'] not in ('add', 'remove') \ | ||||
| @@ -852,7 +891,7 @@ class SelectTeamFinalView(VolunteerMixin, DetailView): | ||||
|             return self.handle_no_permission() | ||||
|         tournament = self.get_object() | ||||
|         reg = request.user.registration | ||||
|         if not reg.is_admin and (not reg.is_volunteer or tournament not in reg.organized_tournaments.all()): | ||||
|         if not reg.is_volunteer or reg not in tournament.organizers_and_presidents.all(): | ||||
|             return self.handle_no_permission() | ||||
|         participation_qs = tournament.participations.filter(pk=self.kwargs["participation_id"]) | ||||
|         if not participation_qs.exists(): | ||||
| @@ -1003,17 +1042,14 @@ class SolutionsDownloadView(VolunteerMixin, View): | ||||
|                 return super().dispatch(request, *args, **kwargs) | ||||
|         elif 'tournament_id' in kwargs: | ||||
|             tournament = Tournament.objects.get(pk=kwargs["tournament_id"]) | ||||
|             if reg.is_volunteer \ | ||||
|                     and (tournament in reg.organized_tournaments.all() | ||||
|                          or reg.pools_presided.filter(tournament=tournament).exists()): | ||||
|             if reg.is_volunteer and reg in tournament.organizers_and_presidents.all(): | ||||
|                 return super().dispatch(request, *args, **kwargs) | ||||
|         else: | ||||
|             pool = Pool.objects.get(pk=kwargs["pool_id"]) | ||||
|             tournament = pool.tournament | ||||
|             if reg.is_volunteer \ | ||||
|                     and (reg in tournament.organizers.all() | ||||
|                          or reg in pool.juries.all() | ||||
|                          or reg.pools_presided.filter(tournament=tournament).exists()): | ||||
|                     and (reg in tournament.organizers_and_presidents.all() | ||||
|                          or reg in pool.juries.all()): | ||||
|                 return super().dispatch(request, *args, **kwargs) | ||||
|  | ||||
|         return self.handle_no_permission() | ||||
| @@ -2001,7 +2037,7 @@ class PassageDetailView(LoginRequiredMixin, DetailView): | ||||
|         reg = request.user.registration | ||||
|         passage = self.get_object() | ||||
|         if reg.is_admin or reg.is_volunteer \ | ||||
|                 and (self.get_object().pool.tournament in reg.organized_tournaments.all() | ||||
|                 and (reg in self.get_object().pool.tournament.organizers_and_presidents.all() | ||||
|                      or reg in passage.pool.juries.all() | ||||
|                      or reg.pools_presided.filter(tournament=passage.pool.tournament).exists()) \ | ||||
|                 or reg.participates and reg.team \ | ||||
|   | ||||
| @@ -23,7 +23,7 @@ | ||||
|         </div> | ||||
|  | ||||
|         <div id="sidebar-card" class="collapse d-lg-block"> | ||||
|             <div class="card-body"> | ||||
|             <div class="card-body px-2 py-1"> | ||||
|                 {% for information in user.registration.important_informations %} | ||||
|                     <div class="card my-2"> | ||||
|                         <div class="card-header bg-dark-subtle"> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user