from datetime import date, datetime from django.shortcuts import render, get_object_or_404 from django.contrib.auth.decorators import login_required from django.views.decorators.http import require_http_methods from django.http import HttpResponse, HttpResponseRedirect from django.db.models import Q from django.urls import reverse from django.conf import settings from django.contrib.auth import get_user_model from django.contrib.contenttypes.models import ContentType from django.core.mail import send_mail import pendulum from jarvis.core.models import Email from jarvis.people.models import Gymnast from jarvis.people.views import gymnast_listing from jarvis.objective.models import Skill from jarvis.tools.date_week_transition import from_date_to_week_number from .models import ( Plan, Note, Point, Chrono, LearnedSkill, GymnastHasRoutine, SeasonInformation, NumberOfRoutineDone, ) from .forms import ( PlanForm, NoteForm, ScoreForm, LearnedSkillForm, SeasonInformationForm, NumberOfRoutineDoneForm, ) from .email_vars import MAIL_HEADER, MAIL_FOOTER User = get_user_model() @login_required @require_http_methods(["GET"]) def note_listing(request, gymnast_id=None): """ Récupère les notes des gymnastes autorisé(e)s Args: gymnast_id (int) identifiant d'un gymnaste """ gymnast = None if gymnast_id and ( request.user.is_superuser or ( request.session.has_key("available_gymnast") and gymnast_id in request.session["available_gymnast"] ) ): note_list = Note.objects.filter(gymnast=gymnast_id) gymnast = Gymnast.objects.get(pk=gymnast_id) else: if request.user.is_superuser: note_list = Note.objects.all() else: note_list = Note.objects.filter( gymnast__in=request.session["available_gymnast"] ) context = {"note_list": note_list, "gymnast": gymnast} return render(request, "notes/list.html", context) @login_required @require_http_methods(["GET"]) def note_details(request, note_id): """ Récupère toutes les informations d'un note et vérifie si le demandeur peut avoir accès à la note. S'il ne peut pas il est redirigé vers le listing des notes. Args: note_id (int) identifiant d'une note """ note = get_object_or_404(Note, pk=note_id) if not request.user.is_superuser and ( request.session.has_key("available_gymnast") and note.gymnast.id not in request.session["available_gymnast"] ): return note_listing(request) return render(request, "notes/details.html", {"note": note}) @login_required @require_http_methods(["GET", "POST"]) def note_create_or_update(request, note_id=None, gymnast_id=None): """Création ou modification d'une note Args: note_id (int) identifiant d'une note gymnast_id (int) identifiant d'un gymnaste TODO: pq ne puis-je pas récuperer l'idantifiant du coach via le form ? """ coach = User.objects.get(pk=request.user.id) if note_id: note = get_object_or_404(Note, pk=note_id) if not request.user.is_superuser and ( request.session.has_key("available_gymnast") and note.gymnast.id not in request.session["available_gymnast"] ): return note_listing(request) data = { "coach": coach.id, "gymnast": note.gymnast.id, "gymnast_related": str(note.gymnast), } else: note = None today = pendulum.now().date() season, week_number = from_date_to_week_number(today) data = { "coach": coach.id, "title": f"Note of the week {week_number} ({season})", } if gymnast_id is not None: gymnast = get_object_or_404(Gymnast, pk=gymnast_id) data["gymnast"] = gymnast_id data["gymnast_related"] = str(gymnast) if request.method == "POST": form = NoteForm(request.POST, instance=note) if form.is_valid(): new_note = form.save() if ( (new_note.gymnast.user.email or new_note.gymnast.email_trainer) and ((not note_id) or (note_id and note.status == 0)) and new_note.status == 1 ): url = request.build_absolute_uri( reverse("gymnast_details_tab", args=(new_note.gymnast.id, "event")) ) receivers = [ new_note.gymnast.user.email, new_note.gymnast.email_trainer, ] title = f"{new_note.gymnast} : Nouvelle note" body = f"""
Bonjour,
Une nouvelle note vous a été envoyée. Vous pouvez la consulter en cliquant ici.
""" send_mail( title, "Une nouvelle note vous a été envoyée", settings.EMAIL_HOST_USER, receivers, fail_silently=False, html_message=body + MAIL_FOOTER, ) return HttpResponseRedirect( reverse("gymnast_details_tab", args=(new_note.gymnast.id, "event")) ) return render(request, "notes/create.html", {"form": form}) last_note = ( Note.objects.filter(gymnast=gymnast_id, status=1).order_by("-date").first() ) if last_note: data["informations"] = last_note.informations form = NoteForm(instance=note, initial=data) context = {"form": form, "note_id": note_id} return render(request, "notes/create.html", context) @login_required @require_http_methods(["POST"]) def gymnast_learn_skill(request): """ Lie un gymnast à une figure. """ # utiliser un FORM pour cette fonction. gymnast_id = request.POST.get("gymnast_id", None) skill_id = request.POST.get("skill_id", None) learning_step = request.POST.get("learning_step", 0) if gymnast_id and skill_id: gymnast = get_object_or_404(Gymnast, pk=gymnast_id) skill = Skill.objects.get(pk=skill_id) learned_skill = LearnedSkill( gymnast=gymnast, skill=skill, learning_step=learning_step, date=datetime.now(), ) learned_skill.save() return HttpResponse(status=200) if gymnast_id: print("Error : can not link Gymnast and skill. Missing skill_id.") else: print("Error : can not link Gymnast and skill. Missing gymnast_id.") return HttpResponse(status=500) @login_required @require_http_methods(["GET", "POST"]) def learnedskill_create_or_update(request, gymnast_id=None): """ Formulaire de creation et modification d'un lien skill/gymnaste. Args: gymnast_id (int) identifiant d'un gymnaste """ if gymnast_id: if not request.user.is_superuser and ( request.session.has_key("available_gymnast") and gymnast_id not in request.session["available_gymnast"] ): return gymnast_listing(request) gymnast = get_object_or_404(Gymnast, pk=gymnast_id) data = { "gymnast": gymnast.id, "gymnast_related": str(gymnast), } else: data = None if request.method == "POST": form = LearnedSkillForm(request.POST) if form.is_valid(): learned_skill = form.save() # notification receivers = [] functionality = ContentType.objects.get(model="learnedskill") for notification in gymnast.notifications.filter( functionality=functionality ): receivers.append(notification.user.email) title = f"{learned_skill.gymnast} : Nouveau skill appris" html_message = f"""Bonjour,
{learned_skill.gymnast} a appris {learned_skill.skill} ({learned_skill.learning_step}).
""" Email.objects.create( receivers=receivers, title=title, body=html_message, ) send_mail( title, f"{learned_skill.gymnast} a appris une nouvelle figure ({date})", settings.EMAIL_HOST_USER, receivers, fail_silently=False, html_message=html_message + MAIL_FOOTER, ) return HttpResponseRedirect( reverse("gymnast_details", args=(form.cleaned_data["gymnast"].id,)) ) return render(request, "learnedskills/create.html", {"form": form}) form = LearnedSkillForm(initial=data) context = {"form": form, "gymnast_id": gymnast_id} return render(request, "learnedskills/create.html", context) @login_required @require_http_methods(["GET", "POST"]) def score_create_or_update(request, score_id=None, gymnast_id=None): """ Formulaire de création d'un nouveau score. Args: score_id (int) identifiant d'un score gymnast_id (int) identifiant d'un gymnaste """ if score_id: score = get_object_or_404(Point, pk=score_id) if not request.user.is_superuser and ( request.session.has_key("available_gymnast") and score.gymnast.id not in request.session["available_gymnast"] ): return score_listing(request) data = { "gymnast_related": str(score.gymnast), "event_related": str(score.event), } else: score = None data = None if gymnast_id is not None: gymnast = get_object_or_404(Gymnast, pk=gymnast_id) data = {"gymnast": gymnast_id, "gymnast_related": str(gymnast)} if request.method == "POST": form = ScoreForm(request.POST, instance=score) if form.is_valid(): score = form.save() # notification receivers = [] functionality = ContentType.objects.get(model="point") for notification in score.gymnast.notifications.filter( functionality=functionality ): receivers.append(notification.user.email) title = f"{score.gymnast} : Nouveau score enregistré" html_message = f"""Bonjour,
Un nouveau score a été enregistré pour {score.gymnast} :
{score.event.name} à {score.event.place.address} - {score.event.place.postal} {score.event.place.city}
{score.routine_type} : {score.total} points
Bonjour,
Nouvelle série comptabilisée pour {routine_done.gymnast}.
""" Email.objects.create(receivers=receivers, title=title, body=body) send_mail( title, f"Nouvelle série comptabilisée pour {routine_done.gymnast}", settings.EMAIL_HOST_USER, receivers, fail_silently=False, html_message=body + MAIL_FOOTER, ) return HttpResponseRedirect( reverse( "gymnast_details_tab", args=(form.cleaned_data["gymnast"].id, "routine"), ) ) return render(request, "routinedone/create.html", {"form": form}) form = NumberOfRoutineDoneForm(instance=routinedone, initial=data) context = {"form": form, "routinedone_id": routinedone_id} return render(request, "routinedone/create.html", context) @login_required @require_http_methods(["GET", "POST"]) def plan_create_or_update(request, plan_id=None, gymnast_id=None, skill_id=None): """Création d'un plan. Args: plan_id (int) identifiant d'un plan (classeBonjour,
Nouvel objectif fixé pour {plan.gymnast} : {plan.educative} ({plan.learning_step}) pour le {date.strftime('%d %B %Y')} au plus tard.
""" Email.objects.create(receivers=receivers, title=title, body=body) send_mail( title, f"Nouvel objectif fixé pour {plan.gymnast}", settings.EMAIL_HOST_USER, receivers, fail_silently=False, html_message=body + MAIL_FOOTER, ) return HttpResponseRedirect( reverse("gymnast_details", args=(form.cleaned_data["gymnast"].id,)) ) return render(request, "plan/create.html", {"form": form}) form = PlanForm(instance=plan, initial=data) context = {"form": form, "plan_id": plan_id} return render(request, "plan/create.html", context) @login_required @require_http_methods(["GET", "POST"]) def season_information_create_or_update( request, season_information_id=None, gymnast_id=None ): """Création d'un record de la class SeasonInformation. Args: season_information_id (int): identifiant d'un plan (classeBonjour,
Une nouvelle information de saison enregistrée pour {season_information.gymnast}.
""" Email.objects.create(receivers=receivers, title=title, body=body) send_mail( title, f"Une nouvelle information de saison enregistrée pour {season_information.gymnast}", settings.EMAIL_HOST_USER, receivers, fail_silently=False, html_message=body + MAIL_FOOTER, ) return HttpResponseRedirect( reverse( "gymnast_details", args=(form.cleaned_data["gymnast"].id,), ) ) return render(request, "seasoninformations/create.html", {"form": form}) form = SeasonInformationForm(instance=season_information, initial=data) context = {"form": form, "season_information_id": season_information_id} return render(request, "seasoninformations/create.html", context) @login_required @require_http_methods(["GET"]) def season_information_listing(request, gymnast_id=None): """Liste toutes les informations de saison pour un gymnaste. Args: gymnast_id (int) identifiant d'un gymnaste """ if gymnast_id and ( request.user.is_superuser or ( request.session.has_key("available_gymnast") and gymnast_id in request.session["available_gymnast"] ) ): gymnast = get_object_or_404(Gymnast, pk=gymnast_id) season_information_list = SeasonInformation.objects.filter(gymnast=gymnast_id) else: if request.user.is_superuser: season_information_list = SeasonInformation.objects.all() else: season_information_list = SeasonInformation.objects.filter( gymnast__in=request.session["available_gymnast"] ) context = {"season_information_list": season_information_list, "gymnast": gymnast} return render(request, "seasoninformations/list.html", context)