Big update on report generation
This commit is contained in:
parent
402c26a00d
commit
8250139908
|
@ -161,3 +161,12 @@ DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
|
|||
# https://warehouse.python.org/project/whitenoise/
|
||||
|
||||
STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage"
|
||||
|
||||
SITE_TITLE = env("SITE_TITLE", default=None)
|
||||
CLUB_NAME = env("CLUB_NAME", default=None)
|
||||
ADDRESS = env("ADDRESS", default=None)
|
||||
CITY = env("CITY", default=None)
|
||||
ZIP = env("ZIP", default=None)
|
||||
HEAD_COACH = env("HEAD_COACH", default=None)
|
||||
MOBILE_PHONE = env("MOBILE_PHONE", default=None)
|
||||
HEAD_COACH_EMAIL = env("HEAD_COACH_EMAIL", default=None)
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
{% load static %}
|
||||
{% load menuitems %}
|
||||
{% load has_group %}
|
||||
{% load is_user_equal_to_gymnast %}
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
@ -18,364 +15,253 @@
|
|||
<link rel="apple-touch-icon" sizes="76x76" href="{% static "img/apple-icon.png" %}">
|
||||
<link rel="icon" type="image/png" href="{% static "img/favicon.png" %}">
|
||||
|
||||
<title>• Ultron - {{ gymnast.first_name }} {{ gymnast.last_name }} •</title>
|
||||
<title>{{ gymnast.first_name }} {{ gymnast.last_name }}</title>
|
||||
|
||||
<!-- Fonts and icons -->
|
||||
<link href="https://fonts.googleapis.com/css?family=Poppins:200,300,400,600,700,800" rel="stylesheet" />
|
||||
<!-- Font Awesome Pro -->
|
||||
<link href="{% static "css/gymnast_report.css" %}" rel="stylesheet" />
|
||||
<link href="{% static "css/font_awesome_all_5.15.3.css" %}" rel="stylesheet" />
|
||||
|
||||
<!-- Full Calendar Plugin, full documentation here: https://github.com/fullcalendar/fullcalendar -->
|
||||
<link href="{% static "js/plugins/fullcalendar/main.min.css" %}" rel="stylesheet" />
|
||||
|
||||
<!-- JQuery UI CSS -->
|
||||
<link href="{% static "js/plugins/jqueryui/jquery-ui.theme.min.css" %}" rel="stylesheet" />
|
||||
<link href="{% static "js/plugins/jqueryui/jquery-ui.min.css" %}" rel="stylesheet" />
|
||||
|
||||
<!-- Nucleo Icons -->
|
||||
<link href="{% static "css/nucleo-icons.css" %}" rel="stylesheet" />
|
||||
|
||||
<!-- CSS Files -->
|
||||
<link href="{% static "css/black-dashboard.css" %}" rel="stylesheet" />
|
||||
|
||||
<!-- Maps by mapbox -->
|
||||
<script src='https://api.mapbox.com/mapbox.js/v3.2.0/mapbox.js'></script>
|
||||
<link href='https://api.mapbox.com/mapbox.js/v3.2.0/mapbox.css' rel='stylesheet' />
|
||||
|
||||
<!-- Core JS Files -->
|
||||
<script src="{% static "js/core/jquery-3.6.0.min.js" %}"></script>
|
||||
<script src="{% static "js/core/popper.min.js" %}"></script>
|
||||
<script src="{% static "js/core/bootstrap.min.js" %}"></script>
|
||||
|
||||
<!-- Chart JS -->
|
||||
<script src="{% static "js/plugins/moment_2.29.1.min.js" %}"></script>
|
||||
<script src="{% static "js/plugins/moment_locale_en-gb.js" %}"></script>
|
||||
<script src="{% static "js/plugins/chartjs_2.9.4.min.js" %}"></script>
|
||||
|
||||
<!-- FullCalendar CSS -->
|
||||
<!-- <link href="{% static "js/plugins/fullcalendar/main.css" %}" rel="stylesheet" /> -->
|
||||
|
||||
<link href="{% static "css/black-dashboard_report.css" %}" rel="stylesheet" />
|
||||
</head>
|
||||
|
||||
<body class="sidebar-mini white-content">
|
||||
<div class="content">
|
||||
<div class="row">
|
||||
<div class="col-12 col-sm-4 col-md-4 col-lg-4">
|
||||
<div class="card mb-4">
|
||||
<div class="card-body">
|
||||
<a href="{% url 'gymnast_report_preview' gymnast.id %}">Rapport</a>
|
||||
|
||||
<h4 class="title">{{ gymnast.first_name }} {{ gymnast.last_name }}</h4>
|
||||
{{ gymnast.club.name }}<br />
|
||||
<b>{{ gymnast.trainings_by_week }} training/week</b> for <b>{{ gymnast.hours_by_week }} hours/week</b><br />
|
||||
|
||||
{% if height_weight %}
|
||||
<b>{{ height_weight.0.height }}cm - {{ height_weight.0.weight }}kg</b> ({{ height_weight.0.date | date:"d-m-Y" }})<br />
|
||||
{% endif %}
|
||||
|
||||
<br />
|
||||
{% if user_is_trainer and gymnast.informations %}
|
||||
<p>{{ gymnast.informations }}</p>
|
||||
<br />
|
||||
{% endif %}
|
||||
|
||||
<h4>Personnal bests :</h4>
|
||||
<li>
|
||||
<b>10 |</b> : <b>{{ best_straightjump.0.tof }}</b> ({{ best_straightjump.0.date | date:"d-m-Y" }})
|
||||
</li>
|
||||
<li>
|
||||
<b>R1</b> : <b>{{ best_tof_routine_1.0.tof }}</b> ({{ best_tof_routine_1.0.date | date:"d-m-Y" }})
|
||||
</li>
|
||||
<li>
|
||||
<b>R2</b> : <b>{{ best_tof_routine_2.0.tof }}</b> ({{ best_tof_routine_2.0.date | date:"d-m-Y" }})
|
||||
</li>
|
||||
<li>
|
||||
<b>Routine</b> : {% if best_routine %}<b>{{ best_routine.0.tof }}</b> ({{ best_routine.0.date | date:"d-m-Y" }}){% else %} (no information){% endif %}
|
||||
</li>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-sm-4 col-md-4 col-lg-4">
|
||||
(doughnut)
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-sm-4 col-md-4 card mb-4">
|
||||
(stat par level/rank)
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-3 col-sm-1 col-md-1 col-lg-1 col-xl-1">
|
||||
<ul class="nav nav-pills nav-pills-primary nav-pills-icons flex-column">
|
||||
|
||||
<li class="nav-item">
|
||||
<a class="nav-link get-info{% if tab is None or tab == 'level' %} active{% endif %}" data-toggle="tab" href="#skill" data-ref="#skill" data-url="skill/" id="display_skill">
|
||||
<i class="tim-icons icon-sound-wave"></i> <!-- Level -->
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class="nav-item">
|
||||
<a class="nav-link get-info{% if tab == 'routine' %} active{% endif %}" data-toggle="tab" href="#routine" data-ref="#routine" data-url="routine/" id="display_routines">
|
||||
<i class="tim-icons icon-components"></i> <!-- Routines -->
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class="nav-item">
|
||||
<a class="nav-link get-info{% if tab == 'scores' %} active{% endif %}" data-toggle="tab" href="#scores" data-ref="#scores" data-url="scores_chrono/" id="display_scores_chrono">
|
||||
<i class="fal fa-crosshairs"></i> <!-- Scores -->
|
||||
</a>
|
||||
</li>
|
||||
{% if user_is_trainer or request.user|is_user_equal_to_gymnast:gymnast.id %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link get-info{% if tab == 'physiological' %} active{% endif %}" data-toggle="tab" href="#physiological" data-ref="#physiological" data-url="physiological/" id="display_physiological">
|
||||
<i class="fal fa-stethoscope"></i> <!-- Physical -->
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link get-info{% if tab == 'event' %} active{% endif %}" data-toggle="tab" href="#event" data-ref="#event" data-url="event/" id="display_event">
|
||||
<i class="fal fa-calendar-day"></i> <!-- Events -->
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-12 col-sm-11 col-md-11 col-lg-11 pr-0">
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane{% if tab is None or tab == 'skill' %} active{% endif %}" id="skill"></div>
|
||||
|
||||
<div class="tab-pane{% if tab == 'routine' %} active{% endif %}" id="routine"></div>
|
||||
|
||||
<div class="tab-pane{% if tab == 'scores' %} active{% endif %}" id="scores"></div>
|
||||
|
||||
{% if user_is_trainer or request.user|is_user_equal_to_gymnast:gymnast.id %}
|
||||
<div class="tab-pane{% if tab == 'physiological' %} active{% endif %}" id="physiological"></div>
|
||||
{% endif %}
|
||||
|
||||
<div class="tab-pane{% if tab == 'event' %} active{% endif %}" id="event"></div>
|
||||
|
||||
<!-- TODO : message d'erreur si TAB non géré. -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<header class="white-content">
|
||||
<div class="row">
|
||||
<div id="header-left" class="col-7 text-12">
|
||||
{{ SITE_TITLE }} - {{ CLUB_NAME }}<br />
|
||||
{{ ADDRESS }} - {{ ZIP }} {{ CITY }}<br />
|
||||
Season {{ season }} - week {{ week_number }}
|
||||
</div>
|
||||
<div id="header-right" class="col-5 text-right text-12">
|
||||
Head Coach : {{ HEAD_COACH }}<br />
|
||||
{{ HEAD_COACH_EMAIL }}<br />
|
||||
{{ today | date:"j F Y" }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="{% static "js/plugins/perfect-scrollbar.jquery_1.4.0.min.js" %}"></script>
|
||||
|
||||
<!-- Plugin for Switches, full documentation here: http://www.jque.re/plugins/version3/bootstrap.switch/ -->
|
||||
<script src="{% static "js/plugins/bootstrap-switch_3.3.4.js" %}"></script>
|
||||
<!-- Plugin for Sweet Alert -->
|
||||
<script src="{% static "js/plugins/sweetalert2.min.js" %}"></script>
|
||||
<!-- Plugin for Sorting Tables -->
|
||||
<script src="{% static "js/plugins/jquery.tablesorter_2.0.5b.js" %}"></script>
|
||||
<!-- Forms Validations Plugin -->
|
||||
<script src="{% static "js/plugins/jquery.validate_1.17.0.min.js" %}"></script>
|
||||
<!-- Plugin for the Wizard, full documentation here: https://github.com/VinceG/twitter-bootstrap-wizard -->
|
||||
<script src="{% static "js/plugins/jquery.bootstrap-wizard_1.4.2.js" %}"></script>
|
||||
<!-- Plugin for Select, full documentation here: http://silviomoreto.github.io/bootstrap-select -->
|
||||
<script src="{% static "js/plugins/bootstrap-selectpicker_1.12.4.js" %}"></script>
|
||||
<!-- Plugin for the DateTimePicker, full documentation here: https://eonasdan.github.io/bootstrap-datetimepicker/ -->
|
||||
<script src="{% static "js/plugins/bootstrap-datetimepicker_4.17.47.js" %}"></script>
|
||||
<!-- DataTables.net Plugin, full documentation here: https://datatables.net/ -->
|
||||
<script src="{% static "js/plugins/jquery.dataTables_1.10.18.min.js" %}"></script>
|
||||
<!-- Plugin for Tags, full documentation here: https://github.com/bootstrap-tagsinput/bootstrap-tagsinputs -->
|
||||
<script src="{% static "js/plugins/bootstrap-tagsinput_0.8.0.js" %}"></script>
|
||||
<!-- Plugin for Fileupload, full documentation here: http://www.jasny.net/bootstrap/javascript/#fileinput -->
|
||||
<script src="{% static "js/plugins/jasny-bootstrap_3.1.3.min.js" %}"></script>
|
||||
<!-- Full Calendar Plugin, full documentation here: https://github.com/fullcalendar/fullcalendar -->
|
||||
<script src="{% static "js/plugins/fullcalendar/main.js" %}"></script>
|
||||
<!-- Vector Map plugin, full documentation here: http://jvectormap.com/documentation/ -->
|
||||
<script src="{% static "js/plugins/jquery-jvectormap_2.0.4.js" %}"></script>
|
||||
<!-- Plugin for the Sliders, full documentation here: http://refreshless.com/nouislider/ -->
|
||||
<script src="{% static "js/plugins/nouislider_11.1.0.min.js" %}"></script>
|
||||
<!-- Notifications Plugin -->
|
||||
<script src="{% static "js/plugins/bootstrap-notify_3.1.5.js" %}"></script>
|
||||
<!-- Control Center for Black Dashboard: parallax effects, scripts for the example pages etc -->
|
||||
<!-- <script src="{% static "js/black-dashboard.min.js" %}"></script> -->
|
||||
<script src="{% static "js/black-dashboard.js" %}"></script>
|
||||
<!-- Jquery UI for autocomplete, etc. -->
|
||||
<script src="{% static "js/plugins/jqueryui/jquery-ui.min.js" %}"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
$().ready(function() {
|
||||
$sidebar = $('.sidebar');
|
||||
$navbar = $('.navbar');
|
||||
$main_panel = $('.main-panel');
|
||||
$full_page = $('.full-page');
|
||||
$sidebar_responsive = $('body > .navbar-collapse');
|
||||
|
||||
// {% if request.session.is_sidebar_minified %}sidebar_mini_active = true;
|
||||
// {% else %}sidebar_mini_active = false;
|
||||
// {% endif %}
|
||||
|
||||
// {% if request.session.template == 0 %}white_color = false;
|
||||
// {% else %}white_color = true;
|
||||
// {% endif %}
|
||||
white_color = true;
|
||||
|
||||
window_width = $(window).width();
|
||||
fixed_plugin_open = $('.sidebar .sidebar-wrapper .nav li.active a p').html();
|
||||
|
||||
// {% if request.session.sidebar == 1 %}color = 'blue';
|
||||
// {% elif request.session.sidebar == 2 %}color = 'green';
|
||||
// {% elif request.session.sidebar == 3 %}color = 'orange';
|
||||
// {% elif request.session.sidebar == 4 %}color = 'red';
|
||||
// {% else %}color = 'purple'
|
||||
// {% endif %}
|
||||
// $sidebar.attr('data', color);
|
||||
// $main_panel.attr('data', color);
|
||||
// $full_page.attr('filter-color', color);
|
||||
// $sidebar_responsive.attr('data', color);
|
||||
|
||||
$('.fixed-plugin a').click(function(event) {
|
||||
if ($(this).hasClass('switch-trigger')) {
|
||||
if (event.stopPropagation) {
|
||||
event.stopPropagation();
|
||||
} else if (window.event) {
|
||||
window.event.cancelBubble = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$('.fixed-plugin .background-color span').click(function() {
|
||||
$(this).siblings().removeClass('active');
|
||||
$(this).addClass('active');
|
||||
|
||||
var new_color = $(this).data('color');
|
||||
|
||||
if ($sidebar.length != 0)
|
||||
$sidebar.attr('data', new_color);
|
||||
|
||||
if ($main_panel.length != 0)
|
||||
$main_panel.attr('data', new_color);
|
||||
|
||||
if ($full_page.length != 0)
|
||||
$full_page.attr('filter-color', new_color);
|
||||
|
||||
if ($sidebar_responsive.length != 0)
|
||||
$sidebar_responsive.attr('data', new_color);
|
||||
});
|
||||
|
||||
// $('.switch-sidebar-mini input').on("switchChange.bootstrapSwitch", function() {
|
||||
// var $btn = $(this);
|
||||
|
||||
// if (sidebar_mini_active == true) {
|
||||
// $('body').removeClass('sidebar-mini');
|
||||
// sidebar_mini_active = false;
|
||||
// blackDashboard.showSidebarMessage('Sidebar mini deactivated...');
|
||||
// } else {
|
||||
// $('body').addClass('sidebar-mini');
|
||||
// sidebar_mini_active = true;
|
||||
// blackDashboard.showSidebarMessage('Sidebar mini activated...');
|
||||
// }
|
||||
|
||||
// // we simulate the window Resize so the charts will get updated in realtime.
|
||||
// var simulateWindowResize = setInterval(function() {
|
||||
// window.dispatchEvent(new Event('resize'));
|
||||
// }, 180);
|
||||
|
||||
// // we stop the simulation of Window Resize after the animations are completed
|
||||
// setTimeout(function() {
|
||||
// clearInterval(simulateWindowResize);
|
||||
// }, 1000);
|
||||
// });
|
||||
|
||||
// $('.switch-change-color input').on("switchChange.bootstrapSwitch", function() {
|
||||
// var $btn = $(this);
|
||||
|
||||
// if (white_color == true) {
|
||||
// $('body').addClass('change-background');
|
||||
// setTimeout(function() {
|
||||
// $('body').removeClass('change-background');
|
||||
// $('body').removeClass('white-content');
|
||||
// }, 900);
|
||||
// white_color = true; // false
|
||||
// } else {
|
||||
// $('body').addClass('change-background');
|
||||
// setTimeout(function() {
|
||||
// $('body').removeClass('change-background');
|
||||
// $('body').addClass('white-content');
|
||||
// }, 900);
|
||||
// white_color = true;
|
||||
// }
|
||||
// });
|
||||
|
||||
// $('.light-badge').click(function() {
|
||||
// $('body').addClass('white-content');
|
||||
// });
|
||||
|
||||
// $('.dark-badge').click(function() {
|
||||
// $('body').removeClass('white-content');
|
||||
// });
|
||||
|
||||
// $('#inlineFormInputGroup').focus();
|
||||
// $('#search-button').click(function(){
|
||||
// alert('Clicked !');
|
||||
// $('#inlineFormInputGroup').focus();
|
||||
// });
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
$(document).ready(function() {
|
||||
var default_url = "{% url 'gymnast_details' gymnast.id %}";
|
||||
var tab_div = '';
|
||||
|
||||
{% if tab is None or tab == 'skill' %}
|
||||
tab_url = default_url + 'skill/';
|
||||
tab_div = '#skill';
|
||||
{% elif tab == 'routine' %}
|
||||
tab_url = default_url + 'routine/';
|
||||
tab_div = '#routine';
|
||||
{% elif tab == 'scores' %}
|
||||
tab_url = default_url + 'scores_chrono/';
|
||||
tab_div = '#scores';
|
||||
{% elif tab == 'physiological' %}
|
||||
tab_url = default_url + 'physiological/';
|
||||
tab_div = '#physiological'
|
||||
{% elif tab == 'event' %}
|
||||
tab_url = default_url + 'event/';
|
||||
tab_div = '#event';
|
||||
</header>
|
||||
<br />
|
||||
<body class="white-content">
|
||||
<div class="row">
|
||||
<div class="col-2">
|
||||
<img src="{% static 'img/default-avatar.png' %}" class="profil_img" />
|
||||
</div>
|
||||
<div class="col-6 pl-0">
|
||||
<h3 class="title">{{ gymnast.first_name }} {{ gymnast.last_name }}</h3>
|
||||
{{ gymnast.age }} years - {{ gymnast.get_orientation_display }} twisting<br />
|
||||
{% if gymnast.informations %}
|
||||
{{ gymnast.to_markdown | safe }}
|
||||
{% endif %}
|
||||
|
||||
$.ajax({
|
||||
url: tab_url,
|
||||
dataType: "html",
|
||||
success: function(data) {
|
||||
$(tab_div).replaceWith($(tab_div).html(data));
|
||||
},
|
||||
error: function (exception) {
|
||||
console.log(exception);
|
||||
}
|
||||
});
|
||||
|
||||
$('.get-info').click(function(){
|
||||
$.ajax({
|
||||
url: default_url + $(this).data("url"),
|
||||
dataType: "html",
|
||||
context: $(this),
|
||||
success: function(data) {
|
||||
$($(this).data("ref")).replaceWith($($(this).data("ref")).html(data));
|
||||
},
|
||||
error: function (exception) {
|
||||
console.log(exception);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<link href="{% static "css/ultron.css" %}" rel="stylesheet" />
|
||||
|
||||
</div>
|
||||
<div class="col-4">
|
||||
{% if last_mindstate or last_height_weigth or mindstate_analyse or height_analyse or weight_analyse %}
|
||||
<h4>Physiological</h4>
|
||||
<table class="table">
|
||||
<tr>
|
||||
<td class="pt-0 pb-0">Mind state</td>
|
||||
<td class="pt-0 pb-0">{{ last_mindstate.score }}</td>
|
||||
<td class="pt-0 pb-0">{{ mindstate_analyse }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="pt-0 pb-0">Height</td>
|
||||
<td class="pt-0 pb-0">{{ last_height_weigth.height }}</td>
|
||||
<td class="pt-0 pb-0">{{ height_analyse }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="pt-0 pb-0">Weight</td>
|
||||
<td class="pt-0 pb-0">{{ last_height_weigth.weight }}</td>
|
||||
<td class="pt-0 pb-0">{{ weight_analyse }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<br />
|
||||
<div class="row">
|
||||
<div class="col-8 row">
|
||||
<div class="col-8">
|
||||
<h4 class="mb-1">Best ToF</h4>
|
||||
{% if best_tof_straightjump or best_tof_routine_1 or best_tof_routine_2 %}
|
||||
<table class="table">
|
||||
<thead>
|
||||
<th class="pt-0 pb-0"></th>
|
||||
<th class="pt-0 pb-0 text-center">Chrono</th>
|
||||
<th class="pt-0 pb-0 text-center">ToF</th>
|
||||
<th class="pt-0 pb-0"></th>
|
||||
</thead>
|
||||
{% if best_tof_straightjump %}
|
||||
<tr>
|
||||
<td class="pt-0 pb-0"><b>ToF |</b></td>
|
||||
<td class="pt-0 pb-0 text-right">{{ best_tof_straightjump.score }}</td>
|
||||
<td class="pt-0 pb-0 text-right">{{ best_tof_straightjump.tof }}</td>
|
||||
<td class="pt-0 pb-0 text-right">{{ best_tof_straightjump.date|date:"j M Y" }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% if best_tof_routine_1 %}
|
||||
<tr>
|
||||
<td class="pt-0 pb-0"><b>Routine 1</b></td>
|
||||
<td class="pt-0 pb-0 text-right">{{ best_tof_routine_1.score }}</td>
|
||||
<td class="pt-0 pb-0 text-right">{{ best_tof_routine_1.tof }}</td>
|
||||
<td class="pt-0 pb-0 text-right">{{ best_tof_routine_1.date|date:"j M Y" }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% if best_tof_routine_2 %}
|
||||
<tr>
|
||||
<td class="pt-0 pb-0"><b>Routine 2</b></td>
|
||||
<td class="pt-0 pb-0 text-right">{{ best_tof_routine_2.score }}</td>
|
||||
<td class="pt-0 pb-0 text-right">{{ best_tof_routine_2.tof }}</td>
|
||||
<td class="pt-0 pb-0 text-right">{{ best_tof_routine_2.date|date:"j M Y" }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
</table>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="col-10">
|
||||
<br />
|
||||
<h4 class="mb-1">Best Scores</h4>
|
||||
{% if best_point_routine_1 or best_point_routine_2 %}
|
||||
<table class="table">
|
||||
<thead>
|
||||
<th class="pt-0 pb-0"></th>
|
||||
<th class="pt-0 pb-0 text-center">Exe.</th>
|
||||
<th class="pt-0 pb-0 text-center">Diff.</th>
|
||||
<th class="pt-0 pb-0 text-center">HD</th>
|
||||
<th class="pt-0 pb-0 text-center">ToF</th>
|
||||
<th class="pt-0 pb-0 text-center">Total</th>
|
||||
<th class="pt-0 pb-0"></th>
|
||||
</thead>
|
||||
{% if best_point_routine_1 %}
|
||||
<tr>
|
||||
<td class="pt-0 pb-0"><b>Routine 1</b></td>
|
||||
<td class="pt-0 pb-0 text-right">{{ best_point_routine_1.point_execution }}</td>
|
||||
<td class="pt-0 pb-0 text-right">{{ best_point_routine_1.point_difficulty }}</td>
|
||||
<td class="pt-0 pb-0 text-right">{{ best_point_routine_1.point_horizontal_displacement }}</td>
|
||||
<td class="pt-0 pb-0 text-right">{{ best_point_routine_1.point_time_of_flight }}</td>
|
||||
<td class="pt-0 pb-0 text-right">{{ best_point_routine_1.total }}</td>
|
||||
<td class="pt-0 pb-0 text-right">{{ best_point_routine_1.event.date_begin|date:"j M Y" }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% if best_point_routine_2 %}
|
||||
<tr>
|
||||
<td class="pt-0 pb-0"><b>Routine 2</b></td>
|
||||
<td class="pt-0 pb-0 text-right">{{ best_point_routine_2.point_execution }}</td>
|
||||
<td class="pt-0 pb-0 text-right">{{ best_point_routine_2.point_difficulty }}</td>
|
||||
<td class="pt-0 pb-0 text-right">{{ best_point_routine_2.point_horizontal_displacement }}</td>
|
||||
<td class="pt-0 pb-0 text-right">{{ best_point_routine_2.point_time_of_flight }}</td>
|
||||
<td class="pt-0 pb-0 text-right">{{ best_point_routine_2.total }}</td>
|
||||
<td class="pt-0 pb-0 text-right">{{ best_point_routine_2.event.date_begin|date:"j M Y" }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
</table>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-4 row">
|
||||
{% if routine_1 or routine_2 %}
|
||||
<div class="col-12">
|
||||
<h4 class="mb-1">Routines</h4>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
{% if routine_1 %}
|
||||
<table class="table">
|
||||
{% for routine_skill in routine_1.routine.skill_links.all %}
|
||||
<tr>
|
||||
<td class="pt-1 pb-0">{{ routine_skill.skill.notation }}</td>
|
||||
<td class="pt-1 pb-0">{{ routine_skill.skill.difficulty }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
<tr>
|
||||
<td class="pt-1 pb-0"></td>
|
||||
<td class="pt-1 pb-0"><b>{{ routine_1.routine.difficulty }}</b></td>
|
||||
</tr>
|
||||
</table>
|
||||
{% else %}
|
||||
No compulsary routine defined.
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="col-6">
|
||||
{% if routine_2 %}
|
||||
<table class="table">
|
||||
{% for routine_skill in routine_2.routine.skill_links.all %}
|
||||
<tr>
|
||||
<td class="pt-1 pb-0">{{ routine_skill.skill.notation }}</td>
|
||||
<td class="pt-1 pb-0">{{ routine_skill.skill.difficulty }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
<tr>
|
||||
<td class="pt-1 pb-0"></td>
|
||||
<td class="pt-1 pb-0"><b>{{ routine_2.routine.difficulty }}</b></td>
|
||||
</tr>
|
||||
</table>
|
||||
{% else %}
|
||||
No volontary routine defined.
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<br />
|
||||
<div class="row" id="learned_skill_and_plan">
|
||||
<div class="col-6">
|
||||
<h4 class="mb-1">Last learned skills</h4>
|
||||
<table class="table">
|
||||
{% for learned_skill in learned_skills %}
|
||||
<tr>
|
||||
<td class="pt-1 pb-0">{{ learned_skill.skill.short_label }}</td>
|
||||
<td class="pt-1 pb-0">({{ learned_skill.get_learning_step_display }})</td>
|
||||
<td class="pt-1 pb-0">{{ learned_skill.skill.notation }}</td>
|
||||
<td class="pt-1 pb-0">{{ learned_skill.date|date:"j M Y" }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
</div>
|
||||
<div class="col-5">
|
||||
<h4>Next skills to learn</h4>
|
||||
{% if plan_list %}
|
||||
<table class="table">
|
||||
{% for plan in plan_list %}
|
||||
<tr>
|
||||
<td class="pt-1 pb-0">{{ plan.educative.short_label }}</td>
|
||||
<td class="pt-1 pb-0">()</td>
|
||||
<td class="pt-1 pb-0">{{ plan.skill.notation }}</td>
|
||||
<td class="pt-1 pb-0">{{ plan.date | date:"j M Y" }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% else %}
|
||||
No objective defined.
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<br />
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<h4 class="mb-1">Next Events</h4>
|
||||
{% if next_event_list %}
|
||||
<table class="table">
|
||||
{% for event in next_event_list %}
|
||||
<tr>
|
||||
<td class="pt-1 pb-0">{{ event.date_begin | date:"j M Y" }}</td>
|
||||
<td class="pt-1 pb-0">in {{ event.number_of_week_from_today }} week(s)</td>
|
||||
<td class="pt-1 pb-0">{{ event.name }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<br />
|
||||
<div class="row" id="note">
|
||||
<div class="col-12">
|
||||
<h4 class="mb-1">Notes</h4>
|
||||
{% if notes %}
|
||||
{% for note in notes %}
|
||||
{{ note.to_markdown | safe }}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
No note this week.
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<h4 class=""><i class="icon-primary fal fa-laugh-wink"></i> Hi {{ user.username }} !</h4>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
Welcome to Ultron v0.71 <span class="text-muted">(last update : 13-11-2022)</span><br />
|
||||
Welcome to Ultron v0.72 <span class="text-muted">(last update : 19-11-2022)</span><br />
|
||||
This application is here to help coaches to manage the gymnasts (evolution, evaluation, routines, scores, …).
|
||||
This tool is not perfect so feel free to make improvement proposals, bug reports, … by sending me an <a href="mailto:gregory@flyingacrobaticstrampoline.be">email</a>.<br />
|
||||
<br />
|
||||
|
|
|
@ -566,3 +566,219 @@ def gymnast_display_skill(request, gymnast_id):
|
|||
name="trainer"
|
||||
).exists() # TODO: utiliser les {{ perms }}
|
||||
return render(request, "people/gymnasts/tab_skill.html", context)
|
||||
|
||||
|
||||
def analyse_score(value, value_list):
|
||||
"""Analyse une value (value) par rapport à la moyenne de value_list et à la dernière
|
||||
valeur de value_list
|
||||
|
||||
Args:
|
||||
value float valeur
|
||||
value_list array<float> liste de valeurs
|
||||
|
||||
Returns:
|
||||
string
|
||||
|
||||
Examples:
|
||||
"""
|
||||
res = ""
|
||||
mean_value = mean(value_list)
|
||||
|
||||
if value > value_list[-1]:
|
||||
res += "+"
|
||||
elif value < value_list[-1]:
|
||||
res += "-"
|
||||
else:
|
||||
res += "="
|
||||
|
||||
if value > mean_value:
|
||||
res = "+" + res
|
||||
elif value < mean_value:
|
||||
res = "-" + res
|
||||
else:
|
||||
res = "=" + res
|
||||
|
||||
return res
|
||||
|
||||
|
||||
@login_required
|
||||
@require_http_methods(["GET"])
|
||||
def generate_report(request, gymnast_id):
|
||||
gymnast = get_object_or_404(Gymnast, pk=gymnast_id)
|
||||
today = pendulum.now().date()
|
||||
season, week_number = from_date_to_week_number(today)
|
||||
# season = Season()
|
||||
|
||||
#
|
||||
# PHYSIOLOGICAL INFORMATIONS
|
||||
#
|
||||
mindstate_queryset = MindState.objects.filter(gymnast=gymnast).order_by("-date")
|
||||
last_mindstate = mindstate_queryset.first()
|
||||
lasts_mindstate = list(mindstate_queryset.values_list("score", flat=True)[1:6])
|
||||
|
||||
have_physiological = False
|
||||
if lasts_mindstate:
|
||||
mindstate_analyse = analyse_score(last_mindstate.score, lasts_mindstate)
|
||||
|
||||
height_weight_queryset = HeightWeight.objects.filter(gymnast=gymnast).order_by(
|
||||
"-date"
|
||||
)
|
||||
last_height_weigth = height_weight_queryset.first()
|
||||
lasts_height = list(height_weight_queryset.values_list("height", flat=True)[1:6])
|
||||
lasts_weight = list(height_weight_queryset.values_list("weight", flat=True)[1:6])
|
||||
|
||||
if lasts_height:
|
||||
height_analyse = analyse_score(last_height_weigth.height, lasts_height)
|
||||
|
||||
if lasts_weight:
|
||||
weight_analyse = analyse_score(last_height_weigth.weight, lasts_weight)
|
||||
|
||||
#
|
||||
# BEST TOF
|
||||
#
|
||||
best_tof_straightjump = (
|
||||
Chrono.objects.filter(gymnast=gymnast)
|
||||
.filter(chrono_type=0)
|
||||
.order_by("-score")
|
||||
.first()
|
||||
)
|
||||
best_tof_routine_1 = (
|
||||
Chrono.objects.filter(gymnast=gymnast)
|
||||
.filter(chrono_type=1)
|
||||
.order_by("-score")
|
||||
.first()
|
||||
)
|
||||
best_tof_routine_2 = (
|
||||
Chrono.objects.filter(gymnast=gymnast)
|
||||
.filter(chrono_type=2)
|
||||
.order_by("-score")
|
||||
.first()
|
||||
)
|
||||
|
||||
#
|
||||
# BEST SCORES
|
||||
#
|
||||
best_point_routine_1 = (
|
||||
Point.objects.filter(gymnast=gymnast)
|
||||
.filter(routine_type=1)
|
||||
.order_by("-total")
|
||||
.first()
|
||||
)
|
||||
best_point_routine_2 = (
|
||||
Point.objects.filter(gymnast=gymnast)
|
||||
.filter(routine_type=2)
|
||||
.order_by("-total")
|
||||
.first()
|
||||
)
|
||||
|
||||
#
|
||||
# ROUTINES
|
||||
#
|
||||
routine_1 = (
|
||||
gymnast.has_routine.filter(routine_type=1)
|
||||
.filter(date_begin__lte=today)
|
||||
.filter(Q(date_end__gte=today) | Q(date_end__isnull=True))
|
||||
.first()
|
||||
)
|
||||
routine_2 = (
|
||||
gymnast.has_routine.filter(routine_type=2)
|
||||
.filter(date_begin__lte=today)
|
||||
.filter(Q(date_end__gte=today) | Q(date_end__isnull=True))
|
||||
.first()
|
||||
)
|
||||
# print(routine_2)
|
||||
|
||||
#
|
||||
# LAST LEARNED SKILLS
|
||||
#
|
||||
learned_skills = (
|
||||
LearnedSkill.objects.filter(gymnast=gymnast.id)
|
||||
.annotate(skill_notation=F("skill__notation"))
|
||||
.order_by("skill_notation", "-date")
|
||||
.distinct("skill_notation")[:6]
|
||||
)
|
||||
|
||||
#
|
||||
# PLANNED SKILLS
|
||||
#
|
||||
plan_list = (
|
||||
Plan.objects.filter(gymnast=gymnast, educative__in=(Skill.objects.all()))
|
||||
.filter(Q(is_done=False) | Q(date__gte=date.today()))
|
||||
.order_by("educative", "-date")
|
||||
.distinct()[:6]
|
||||
)
|
||||
|
||||
#
|
||||
# NEXT EVENTS
|
||||
#
|
||||
next_event_list = Event.objects.filter(
|
||||
gymnasts=gymnast.id, date_begin__gte=today
|
||||
).order_by("date_begin")[:5]
|
||||
|
||||
#
|
||||
# NOTES
|
||||
#
|
||||
begin_of_the_week = today
|
||||
if today.weekday() != 0:
|
||||
begin_of_the_week -= timedelta(today.weekday())
|
||||
|
||||
notes = (
|
||||
gymnast.remarks.filter(date__gte=begin_of_the_week)
|
||||
.filter(status=1)
|
||||
.order_by("date")
|
||||
)
|
||||
|
||||
context = {
|
||||
"SITE_TITLE": settings.SITE_TITLE,
|
||||
"CLUB_NAME": settings.CLUB_NAME,
|
||||
"ADDRESS": settings.ADDRESS,
|
||||
"CITY": settings.CITY,
|
||||
"ZIP": settings.ZIP,
|
||||
"HEAD_COACH": settings.HEAD_COACH,
|
||||
"MOBILE_PHONE": settings.MOBILE_PHONE,
|
||||
"HEAD_COACH_EMAIL": settings.HEAD_COACH_EMAIL,
|
||||
"week_number": week_number,
|
||||
"gymnast": gymnast,
|
||||
"today": today,
|
||||
"season": season,
|
||||
"last_mindstate": last_mindstate,
|
||||
"mindstate_analyse": mindstate_analyse,
|
||||
"last_height_weigth": last_height_weigth,
|
||||
"height_analyse": height_analyse,
|
||||
"weight_analyse": weight_analyse,
|
||||
"best_tof_straightjump": best_tof_straightjump,
|
||||
"best_tof_routine_1": best_tof_routine_1,
|
||||
"best_tof_routine_2": best_tof_routine_2,
|
||||
"best_point_routine_1": best_point_routine_1,
|
||||
"best_point_routine_2": best_point_routine_2,
|
||||
"routine_1": routine_1,
|
||||
"routine_2": routine_2,
|
||||
"LEARNING_STEP_CHOICES": LEARNING_STEP_CHOICES,
|
||||
"learned_skills": learned_skills,
|
||||
"plan_list": plan_list,
|
||||
"next_event_list": next_event_list,
|
||||
"notes": notes,
|
||||
}
|
||||
|
||||
# return render(request, "people/gymnasts/report.html", context)
|
||||
|
||||
response = HttpResponse(content_type="application/pdf")
|
||||
response[
|
||||
"Content-Disposition"
|
||||
] = "inline; filename={lastname}-{firstname}-report.pdf".format(
|
||||
lastname=gymnast.last_name,
|
||||
firstname=gymnast.first_name,
|
||||
)
|
||||
|
||||
html = render_to_string("people/gymnasts/report.html", context)
|
||||
|
||||
# font_config = FontConfiguration()
|
||||
HTML(string=html).write_pdf(
|
||||
response,
|
||||
stylesheets=[
|
||||
CSS(settings.STATICFILES_DIRS[0] + "/css/gymnast_report.css"),
|
||||
CSS(settings.STATICFILES_DIRS[0] + "/css/black-dashboard_report.css"),
|
||||
CSS(settings.STATICFILES_DIRS[0] + "/css/font_awesome_all_5.15.3.css"),
|
||||
],
|
||||
) # , font_config=font_config)
|
||||
return response
|
||||
|
|
Loading…
Reference in New Issue