@ -9,7 +9,7 @@ from django.http import HttpResponse, JsonResponse
@@ -9,7 +9,7 @@ from django.http import HttpResponse, JsonResponse
from django . shortcuts import render , redirect , get_object_or_404
from django . contrib . auth . decorators import login_required
from django . utils import timezone
from django . views . decorators . http import require_GET
from django . views . decorators . http import require_GET , require_POST
# Third party
from reportlab . pdfgen import canvas
@ -23,21 +23,12 @@ from asgiref.sync import async_to_sync
@@ -23,21 +23,12 @@ from asgiref.sync import async_to_sync
# Local
from . models import Course , Arrivee , Coureur
from . forms import CourseForm , ScanForm , DossardForm
from main . templatetags . temps_format import *
# =====================================
# Fonctions utilitaires
# =====================================
def seconds_to_hms ( delta : timedelta ) - > str :
""" Convertit une durée timedelta en chaîne formatée HhMMmSSs """
if delta is None :
return ' '
total = int ( delta . total_seconds ( ) )
hours = total / / 3600
minutes = ( total % 3600 ) / / 60
seconds = total % 60
return f " { hours } h { minutes : 02d } m { seconds : 02d } s "
@login_required
@require_GET
def coureur_autocomplete ( request ) :
@ -86,6 +77,17 @@ def main_view(request):
@@ -86,6 +77,17 @@ def main_view(request):
' now ' : timezone . localdate ( )
} )
@login_required
@require_POST
def delete_course ( request , course_id ) :
""" Supprime une course appartenant à l ' utilisateur (AJAX). """
try :
course = Course . objects . get ( id = course_id , owner = request . user )
course . delete ( )
return JsonResponse ( { ' success ' : True } )
except Course . DoesNotExist :
return JsonResponse ( { ' success ' : False , ' error ' : " Course introuvable ou non autorisée. " } )
# =====================================
# Vues d'export
# =====================================
@ -193,8 +195,11 @@ def course_detail_view(request, course_id):
@@ -193,8 +195,11 @@ def course_detail_view(request, course_id):
is_finished = True
return redirect ( ' course_detail ' , course_id = course . id )
# Formatage de la date pour affichage JJ/MM/AAAA
from main . templatetags . temps_format import format_date
date_str = format_date ( course . date )
return render ( request , ' course_detail.html ' , {
' title ' : ' Course : ' + course . nom + " ( " + str ( course . date ) + " ) " ,
' title ' : f ' Course : { course . nom } ( { date_str } ) ' ,
' course ' : course ,
' arrivees ' : arrivees ,
' is_started ' : is_started ,
@ -231,12 +236,13 @@ def scan_view(request):
@@ -231,12 +236,13 @@ def scan_view(request):
temps = timezone . now ( ) - course . depart
rang = Arrivee . objects . filter ( course = course ) . count ( ) + 1
Arrivee . objects . create ( course = course , coureur = coureur , temps = temps , rang = rang )
temps = seconds_to_hms ( temps )
result = {
' nom ' : coureur . nom ,
' prenom ' : coureur . prenom ,
' classe ' : coureur . classe ,
' rang ' : rang ,
' temps ' : str ( seconds_to_hms ( temps ) )
' temps ' : temps
}
channel_layer = get_channel_layer ( )
async_to_sync ( channel_layer . group_send ) (
@ -257,8 +263,10 @@ def scan_view(request):
@@ -257,8 +263,10 @@ def scan_view(request):
if course_id :
course = get_object_or_404 ( Course , id = course_id , owner = request . user )
# Formatage de la date pour affichage JJ/MM/AAAA
date_str = format_date ( course . date ) if course else ' '
return render ( request , ' scan.html ' , {
' title ' : ' Scan course : ' + ( course . nom + " ( " + str ( course . date ) + " ) " if course else ' ' ) ,
' title ' : f ' Scan course : { course . nom } ( { date_str } ) ' if course else ' ' ,
' courses ' : courses ,
' result ' : result ,
' error ' : error ,