from channels.layers import get_channel_layer from asgiref.sync import async_to_sync from django.shortcuts import render, redirect from django.contrib.auth.decorators import login_required from courses.models import Course, Arrivee from coureurs.models import Coureur from django.utils import timezone from courses.templatetags.temps_format import seconds_to_hms from .forms import ScanForm @login_required def scan_view(request): from django.shortcuts import get_object_or_404 courses = Course.objects.filter(depart__isnull=False, fin__isnull=True) result = None error = None course = None # Traitement AJAX POST if request.method == 'POST' and request.headers.get('x-requested-with') == 'XMLHttpRequest': course_id = request.POST.get('course_id') qrcode = request.POST.get('qrcode') if not course_id or not qrcode: error = "Paramètres manquants." elif qrcode.count(';') != 1: error = "Format QR code invalide." else: nom, classe = qrcode.split(';') course = get_object_or_404(Course, id=course_id) if not course.depart: error = "La course n'a pas démarré." else: coureur, _ = Coureur.objects.get_or_create(nom=nom.strip(), classe=classe.strip()) if Arrivee.objects.filter(course=course, coureur=coureur).exists(): error = "Ce coureur a déjà été scanné." else: temps = timezone.now() - course.depart rang = Arrivee.objects.filter(course=course).count() + 1 Arrivee.objects.create(course=course, coureur=coureur, temps=temps, rang=rang) result = { 'nom': coureur.nom, 'classe': coureur.classe, 'rang': rang, 'temps': str(seconds_to_hms(temps)) } # Broadcast websocket channel_layer = get_channel_layer() async_to_sync(channel_layer.group_send)( f'course_{course.id}', { 'type': 'send_arrivee', 'data': result } ) # Retourne juste le fragment HTML pour scanResult if result: return render(request, 'scan_result.html', {'result': result}) else: return render(request, 'scan_result.html', {'error': error}) # Affichage classique GET else: course_id = request.GET.get('course_id') if course_id: course = get_object_or_404(Course, id=course_id) return render(request, 'scan.html', { 'courses': courses, 'result': result, 'error': error, 'course': course })