khana/src/location/views.py

302 lines
9.4 KiB
Python

# coding=UTF-8
from django.db.models import Q, Count
from django.shortcuts import render, get_object_or_404
from django.template import RequestContext
from django.utils.html import format_html
from django.contrib.auth import authenticate, login as auth_login, logout as auth_logout
from django.http import HttpResponse, HttpResponseRedirect
from django.contrib.auth.decorators import login_required
from django.views.decorators.http import require_http_methods
from datetime import datetime, timedelta, date
from functools import reduce
import operator
import simplejson
from planning.models import (
Event,
Unavailability,
Course,
Subgroup,
Training,
) # planning model
from people.models import Gymnast, Accident # people model
from .models import (
Club,
Place,
Country,
)
from .forms import PlaceForm
from objective.models import Skill, Routine # objective model
def __diffTime(end, start):
"""
Prend deux `datetime.time` en paramètre et calcul la différence entre les deux.
"""
startdate = datetime(2000, 1, 1, start.hour, start.minute)
enddate = datetime(2000, 1, 1, end.hour, end.minute)
return enddate - startdate
@login_required
@require_http_methods(["GET"])
def place_lookup(request):
"""
Récupère la liste des lieux à la volée suivant des caractères de recherche entrés.
"""
pattern = request.GET.get("pattern", 0)
if pattern is not None and len(pattern) >= 3:
results = Place.objects.filter(
Q(name__icontains=pattern) | Q(city__icontains=pattern)
)
place_list = [{"ID": x.id, "Label": str(x)} for x in results]
json = simplejson.dumps(place_list)
return HttpResponse(json, content_type="application/json")
@login_required
@require_http_methods(["GET"])
def country_lookup(request):
"""
Récupère la liste des pays à la volée suivant des caractères de recherche entrés.
"""
pattern = request.GET.get("pattern", 0)
if pattern is not None and len(pattern) >= 3:
results = Country.objects.filter(
Q(nameus__icontains=pattern)
| Q(namefr__icontains=pattern)
| Q(nationality__icontains=pattern)
)
country_list = [{"id": x.id, "Label": str(x)} for x in results]
json = simplejson.dumps(country_list)
return HttpResponse(json, content_type="application/json")
@login_required
@require_http_methods(["GET"])
def place_listing(request):
"""
Liste tous les lieux connus
"""
place_list = Place.objects.all()
context = {"place_list": place_list}
return render(request, "place_list.html", context)
@login_required
@require_http_methods(["GET", "POST"])
def place_create_or_update(request, placeid=None):
"""
Formulaire de création d'un nouveau lieu.
"""
if placeid:
place = get_object_or_404(Place, pk=placeid)
data = {"country_related": place.country}
else:
place = None
data = {}
if request.method == "POST":
form = PlaceForm(request.POST, instance=place)
if form.is_valid():
place = form.save()
return HttpResponseRedirect("/place/" + str(place.id) + "/")
else:
form = PlaceForm(instance=place, initial=data)
context = {"form": form, "placeid": placeid}
return render(request, "place_create.html", context)
@login_required
@require_http_methods(["GET"])
def place_details(request, placeid):
"""
Récupère toutes les informations d'un lieu.
"""
place = get_object_or_404(Place, pk=placeid)
context = {"place": place}
return render(request, "place_details.html", context)
@login_required
def chooseStatistics(request):
"""
Renvoie la liste des clubs et des saisons pour que l'utilisateur choisisse quelles statistiques il veut voir.
"""
year = int(request.GET.get("year", date.today().year))
clubid = request.GET.get("clubid", None)
years_list = set(course.datebegin.year for course in Course.objects.all())
club_list = Club.objects.all().order_by("name")
context = {}
if year and clubid:
context = club_statistics(request, (int(clubid),))
context["selectedClubid"] = clubid
context["selectedYear"] = year
context["yearsList"] = years_list
context["clubList"] = club_list
return render(request, "club_statistics.html", context)
@login_required
def club_statistics(request, clubid):
"""
Renvoie les statistiques d'un club pour une saison choisie.
.. todo:: tenir compte de la saison.
"""
courses = Course.objects.filter(club__in=clubid).order_by(
"iso_day_number", "hour_begin"
)
totalHours = 0
totalCourses = 0
totalHoursByWeek = 0
totalHoursPaid = 0
gymnastsDict = {}
gymnasts = []
courseList = []
for course in courses:
nbtrainer = course.trainers.count()
list_of_gymnasts = Gymnast.objects.filter(to_gym__in=course.to_subgroup.all())
gymnasts.extend(list_of_gymnasts)
nbgymnast = len(list_of_gymnasts)
# gymnasts = set(gymnasts.extend(Gymnast.objects.filter(to_gym__in=course.to_subgroup.all())))
nbhour = __diffTime(course.hour_end, course.hour_begin) # timedelta
totalHoursByWeek += nbhour.seconds
counted = course.get_total_occurence()
# select tous les unavailables liés au cours
unavailabilities = Unavailability.objects.filter(course=course)
for unavailable in unavailabilities:
counted -= unavailable.get_total_occurence()
totalCourses += counted
totalTimeForCourse = nbhour * counted # timedelta
totalHourForCourse = (totalTimeForCourse.days * 24) + (
totalTimeForCourse.seconds / 3600
)
totalHours += totalHourForCourse
totalHoursPaidForCourse = totalHourForCourse * nbtrainer
totalHoursPaid += totalHoursPaidForCourse
# tmp = int(nbhour.seconds/3600)
# hour = "%d:%02d" % (tmp, (nbhour.seconds - (tmp * 3600)) / 60)
hour = nbhour.seconds / 3600
courseList.append(
(
course,
nbtrainer,
nbgymnast,
hour,
counted,
totalHourForCourse,
totalHoursPaidForCourse,
)
)
for gymnast in list_of_gymnasts:
# print(gymnast)
if gymnast.id not in gymnastsDict:
gymnastsDict[gymnast.id] = {
"gymnast": gymnast,
"nbcoursebyweek": 0,
"nbhourbyweek": timedelta(),
"nbtraining": 0,
"nbattendance": 0,
"nbabsence": 0,
"nbhourtraining": 0,
"nbhourattendance": timedelta(),
"percentageattendance": 0,
"nbhourabsence": 0,
"percentageabsence": 0,
}
attendanceList = Training.objects.filter(course=course, gymnast=gymnast)
nbattendance = len(attendanceList)
# print(str(gymnast) + ' : ' + str(nbattendance) + ' for ' + str(course) )
gymnastsDict[gymnast.id]["nbcoursebyweek"] += 1
gymnastsDict[gymnast.id]["nbhourbyweek"] += nbhour # timedelta
gymnastsDict[gymnast.id]["nbtraining"] += counted
gymnastsDict[gymnast.id]["nbattendance"] += nbattendance
gymnastsDict[gymnast.id]["nbhourtraining"] += totalHourForCourse
gymnastsDict[gymnast.id]["nbhourattendance"] += (
nbhour * nbattendance
) # timedelta
# print(gymnastsDict[gymnast.id])
# tous les cours ont été traités
totalHoursByWeek = totalHoursByWeek / 3600
gymnasts = set(gymnasts)
# print(gymnasts)
for gymnast in gymnasts:
tmp = int(gymnastsDict[gymnast.id]["nbhourbyweek"].seconds / 3600)
gymnastsDict[gymnast.id]["nbhourbyweek"] = "%d:%02d" % (
tmp,
(gymnastsDict[gymnast.id]["nbhourbyweek"].seconds - (tmp * 3600)) / 60,
)
gymnastsDict[gymnast.id]["nbabsence"] = (
gymnastsDict[gymnast.id]["nbtraining"]
- gymnastsDict[gymnast.id]["nbattendance"]
)
# tmp = (gymnastsDict[gymnast.id]['nbhourattendance'].days * 24) + (gymnastsDict[gymnast.id]['nbhourattendance'].seconds/3600)
gymnastsDict[gymnast.id]["nbhourattendance"] = (
gymnastsDict[gymnast.id]["nbhourattendance"].days * 24
) + (gymnastsDict[gymnast.id]["nbhourattendance"].seconds / 3600)
gymnastsDict[gymnast.id]["nbhourabsence"] = (
gymnastsDict[gymnast.id]["nbhourtraining"]
- gymnastsDict[gymnast.id]["nbhourattendance"]
)
gymnastsDict[gymnast.id]["percentageattendance"] = int(
(
gymnastsDict[gymnast.id]["nbhourattendance"]
/ gymnastsDict[gymnast.id]["nbhourtraining"]
)
* 100
)
gymnastsDict[gymnast.id]["percentageabsence"] = int(
(
gymnastsDict[gymnast.id]["nbhourabsence"]
/ gymnastsDict[gymnast.id]["nbhourtraining"]
)
* 100
)
context = {
"courses": courseList,
"gymnasts": gymnastsDict,
"totalHoursByWeek": totalHoursByWeek,
"totalCourses": totalCourses,
"totalHours": totalHours,
"totalHoursPaid": totalHoursPaid,
}
return context