bientôt a alpha

This commit is contained in:
Ambulance Clerc
2023-09-09 19:20:08 +02:00
parent cea1bac6a9
commit e099b9e8da
20 changed files with 681 additions and 282 deletions

View File

@@ -3,24 +3,43 @@ from studenteval.models import cl_Student_eval
from django.urls import reverse
from django.utils.html import format_html
from . import views
from rangefilter.filters import *
from django.core.exceptions import PermissionDenied
def is_member(user, group):
return user.groups.filter(name=group).exists()
class _cl_Student_eval_admin(admin.ModelAdmin):
request = None
list_display = ('ID','action_buttons','sStudent', "get_ref_of_eval", "nEval_Type", "nEval_Mode", "sAuthor", 'get_mirrored')
list_display = ('ID','sStudent', "get_ref_of_eval", "nEval_Type", "nEval_Mode", "sAuthor", 'get_mirrored', 'action_buttons')
def action_buttons(self, obj):
action1_url = '/student_eval/show_pdf/{}/'.format(obj.uuid)
action1_url = f"/student_eval/show_pdf/{obj.uuid}/?dtDate__range__gte={self.request.GET.get('dtDate__range__gte')}&dtDate__range__lte={self.request.GET.get('dtDate__range__lte')}"
return format_html('<a href="{}">Voir PDF</a>', action1_url)
action_buttons.short_description = 'Voir la fiche PDF'
def get_queryset(self, request):
self.request = request
return super(_cl_Student_eval_admin, self).get_queryset(request)
search_fields = ['sStudent', 'sRef']
list_filter = ['sStudent',"sAuthor", "nEval_Type", "nEval_Mode"]
list_filter = ['sStudent',"sAuthor", "nEval_Type", "nEval_Mode", ('dtDate', DateRangeFilter)]
def get_form(self, request, obj=None, **kwargs):
user_obj = request.user
author_id = obj.Author.id if obj.Author is not None else 0
student_id = obj.Student.id if obj.Student is not None else 0
if not user_obj.id == author_id and not user_obj.id == student_id and not is_member(user_obj, "FI-Encadrants"):
raise PermissionDenied
return super().get_form(request, obj, **kwargs)
#fields = ["Vehicle", "nType",'sTitle', "sDesc","dtStart", "dtEnd", "Author"]

10
studenteval/filters.py Normal file
View File

@@ -0,0 +1,10 @@
import django_filters
from studenteval.models import cl_Student_eval
class cl_Student_eval_Filter(django_filters.FilterSet):
class Meta:
model = cl_Student_eval
fields = {
'Student' : ['exact']
}

View File

@@ -0,0 +1,48 @@
# Generated by Django 4.0 on 2023-08-11 17:22
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
import uuid
class Migration(migrations.Migration):
initial = True
dependencies = [
('auth', '0012_alter_user_first_name_max_length'),
]
operations = [
migrations.CreateModel(
name='cl_Student_eval',
fields=[
('uuid', models.UUIDField(default=uuid.UUID('619562fd-9ca4-45be-8504-c136ddc0864f'), editable=False, primary_key=True, serialize=False)),
('sAuthor', models.CharField(max_length=120, verbose_name='Auteur')),
('sAuthor_2e', models.CharField(max_length=120, verbose_name='Second auteur')),
('sStudent', models.CharField(max_length=120, verbose_name="Nom de l'étudiant/stagiaire")),
('nEval_Type', models.CharField(choices=[('1', 'Intervention'), ('2', 'Journée')], default=1, max_length=1, verbose_name='Type de suivi')),
('dtDate', models.DateField(default=django.utils.timezone.now, verbose_name='Date')),
('sRef', models.CharField(max_length=120, verbose_name='N° de référence / FIP')),
('nEval_Mode', models.CharField(choices=[('1', 'Auto-évaluation'), ('2', 'Ecadrant')], default=1, max_length=1, verbose_name='Mode de suivi ')),
('sDesc_neg', models.TextField(verbose_name='Points à améliorer')),
('sDesc_pos', models.TextField(verbose_name='Points positifs')),
('sDesc_global', models.TextField(verbose_name="Avis global sur l'intervention/journée/exercice")),
('nInter_Nature', models.CharField(choices=[('1', 'Trauma'), ('2', 'non-Trauma')], default=1, max_length=1, verbose_name='Nature')),
('nInter_Priority', models.CharField(choices=[('1', 'P1'), ('2', 'P2'), ('3', 'P3'), ('4', 'S1'), ('5', 'S2'), ('6', 'S3'), ('7', 'Exercice')], default=1, max_length=1, verbose_name='Priorité')),
('nInter_Complexity', models.CharField(choices=[('1', 'Stable / Simple'), ('2', 'Stable / Complexe'), ('3', 'Instable / Simple'), ('4', 'Instable / Complexe')], default=1, max_length=1, verbose_name='Nature de complexité')),
('sInter_Desc', models.TextField(verbose_name='Description courte')),
('nStudent_Roles', models.CharField(choices=[('1', 'Leader'), ('2', 'Équipier'), ('3', '3e position (observateur')], default=1, max_length=1, verbose_name="Rôle de l'étudiant/stagiaire")),
('dtUpdated', models.DateTimeField(auto_now=True, verbose_name='date updated')),
('dtCreated', models.DateTimeField(auto_now_add=True, verbose_name='date published')),
('Author', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='eval_author', to='auth.user', verbose_name='Auteur')),
('Author_2e', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='eval_second_author', to='auth.user', verbose_name='Second auteur')),
('Student', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='auth.user', verbose_name='Nom du stagiaire/étudaint')),
],
options={
'verbose_name': 'Suivi étudiants - stagiaires',
'verbose_name_plural': 'Suivis étudiants - stagiaires',
},
),
]

View File

@@ -0,0 +1,19 @@
# Generated by Django 4.0 on 2023-08-11 17:27
from django.db import migrations, models
import uuid
class Migration(migrations.Migration):
dependencies = [
('studenteval', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='cl_student_eval',
name='uuid',
field=models.UUIDField(default=uuid.UUID('0ec70ee4-a015-42ea-aa8b-cf385010d233'), editable=False, primary_key=True, serialize=False),
),
]

View File

@@ -0,0 +1,31 @@
# Generated by Django 4.0 on 2023-08-11 17:51
from django.db import migrations, models
import django.db.models.deletion
import uuid
class Migration(migrations.Migration):
dependencies = [
('auth', '0012_alter_user_first_name_max_length'),
('studenteval', '0002_alter_cl_student_eval_uuid'),
]
operations = [
migrations.AlterField(
model_name='cl_student_eval',
name='Author_2e',
field=models.ForeignKey(limit_choices_to={'groups__name': 'FI-Encadrants'}, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='eval_second_author', to='auth.user', verbose_name='Second auteur'),
),
migrations.AlterField(
model_name='cl_student_eval',
name='Student',
field=models.ForeignKey(limit_choices_to={'groups__name': 'FI-Étudiants'}, null=True, on_delete=django.db.models.deletion.SET_NULL, to='auth.user', verbose_name='Nom du stagiaire/étudaint'),
),
migrations.AlterField(
model_name='cl_student_eval',
name='uuid',
field=models.UUIDField(default=uuid.UUID('aade911f-b849-4235-be64-85ed63673322'), editable=False, primary_key=True, serialize=False),
),
]

View File

@@ -0,0 +1,39 @@
# Generated by Django 4.0 on 2023-08-11 18:08
from django.db import migrations, models
import django.utils.timezone
import uuid
class Migration(migrations.Migration):
dependencies = [
('studenteval', '0003_alter_cl_student_eval_author_2e_and_more'),
]
operations = [
migrations.RemoveField(
model_name='cl_student_eval',
name='nStudent_Roles',
),
migrations.AddField(
model_name='cl_student_eval',
name='nStudent_Role',
field=models.CharField(choices=[('1', 'Leader'), ('2', 'Équipier'), ('3', '3e position (observateur)')], default=1, max_length=1, verbose_name="Rôle de l'étudiant/stagiaire"),
),
migrations.AlterField(
model_name='cl_student_eval',
name='dtDate',
field=models.DateField(default=django.utils.timezone.now, verbose_name='Date concernée'),
),
migrations.AlterField(
model_name='cl_student_eval',
name='nEval_Mode',
field=models.CharField(choices=[('1', 'Auto-évaluation'), ('2', 'Encadrant')], default=1, max_length=1, verbose_name='Mode de suivi '),
),
migrations.AlterField(
model_name='cl_student_eval',
name='uuid',
field=models.UUIDField(default=uuid.UUID('01f714cc-4405-420e-996c-5d3a0df76250'), editable=False, primary_key=True, serialize=False),
),
]

View File

@@ -0,0 +1,61 @@
# Generated by Django 4.0 on 2023-08-11 18:14
from django.db import migrations, models
import django.db.models.deletion
import uuid
class Migration(migrations.Migration):
dependencies = [
('auth', '0012_alter_user_first_name_max_length'),
('studenteval', '0004_remove_cl_student_eval_nstudent_roles_and_more'),
]
operations = [
migrations.AlterField(
model_name='cl_student_eval',
name='Author_2e',
field=models.ForeignKey(blank=True, limit_choices_to={'groups__name': 'FI-Encadrants'}, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='eval_second_author', to='auth.user', verbose_name='Second auteur'),
),
migrations.AlterField(
model_name='cl_student_eval',
name='nEval_Type',
field=models.CharField(choices=[('1', 'Intervention/Exercice'), ('2', 'Journée')], default=1, max_length=1, verbose_name='Type de suivi'),
),
migrations.AlterField(
model_name='cl_student_eval',
name='nInter_Complexity',
field=models.CharField(blank=True, choices=[('1', 'Stable / Simple'), ('2', 'Stable / Complexe'), ('3', 'Instable / Simple'), ('4', 'Instable / Complexe')], default=1, max_length=1, verbose_name='Nature de complexité'),
),
migrations.AlterField(
model_name='cl_student_eval',
name='nInter_Nature',
field=models.CharField(blank=True, choices=[('1', 'Trauma'), ('2', 'non-Trauma')], default=1, max_length=1, verbose_name='Nature'),
),
migrations.AlterField(
model_name='cl_student_eval',
name='nInter_Priority',
field=models.CharField(blank=True, choices=[('1', 'P1'), ('2', 'P2'), ('3', 'P3'), ('4', 'S1'), ('5', 'S2'), ('6', 'S3'), ('7', 'Exercice')], default=1, max_length=1, verbose_name='Priorité'),
),
migrations.AlterField(
model_name='cl_student_eval',
name='nStudent_Role',
field=models.CharField(blank=True, choices=[('1', 'Leader'), ('2', 'Équipier'), ('3', '3e position (observateur)')], default=1, max_length=1, verbose_name="Rôle de l'étudiant/stagiaire"),
),
migrations.AlterField(
model_name='cl_student_eval',
name='sAuthor_2e',
field=models.CharField(blank=True, max_length=120, verbose_name='Second auteur'),
),
migrations.AlterField(
model_name='cl_student_eval',
name='sInter_Desc',
field=models.TextField(blank=True, verbose_name='Description courte'),
),
migrations.AlterField(
model_name='cl_student_eval',
name='uuid',
field=models.UUIDField(default=uuid.UUID('090d4087-8142-46bd-9af6-9cf3a4530d60'), editable=False, primary_key=True, serialize=False),
),
]

View File

@@ -0,0 +1,24 @@
# Generated by Django 4.0 on 2023-08-11 18:19
from django.db import migrations, models
import uuid
class Migration(migrations.Migration):
dependencies = [
('studenteval', '0005_alter_cl_student_eval_author_2e_and_more'),
]
operations = [
migrations.AlterField(
model_name='cl_student_eval',
name='sRef',
field=models.CharField(blank=True, max_length=120, verbose_name='N° de référence / FIP'),
),
migrations.AlterField(
model_name='cl_student_eval',
name='uuid',
field=models.UUIDField(default=uuid.UUID('d284f62d-691a-4e36-a63a-0accebe949ee'), editable=False, primary_key=True, serialize=False),
),
]

View File

@@ -0,0 +1,25 @@
# Generated by Django 4.0 on 2023-08-11 19:01
from django.db import migrations, models
import studenteval.models
import uuid
class Migration(migrations.Migration):
dependencies = [
('studenteval', '0006_alter_cl_student_eval_sref_and_more'),
]
operations = [
migrations.AddField(
model_name='cl_student_eval',
name='ID',
field=models.IntegerField(default=studenteval.models.increment_ID, editable=False, unique=True, verbose_name='ID du Suivi'),
),
migrations.AlterField(
model_name='cl_student_eval',
name='uuid',
field=models.UUIDField(default=uuid.UUID('bb6f22e7-e78d-492f-a8ec-87a154482db1'), editable=False, primary_key=True, serialize=False),
),
]

View File

@@ -0,0 +1,19 @@
# Generated by Django 4.0 on 2023-08-11 19:02
from django.db import migrations, models
import uuid
class Migration(migrations.Migration):
dependencies = [
('studenteval', '0007_cl_student_eval_id_alter_cl_student_eval_uuid'),
]
operations = [
migrations.AlterField(
model_name='cl_student_eval',
name='uuid',
field=models.UUIDField(default=uuid.UUID('ba52e37d-25c3-44fa-bec8-2af3e6bd5458'), editable=False, primary_key=True, serialize=False),
),
]

View File

@@ -143,6 +143,8 @@ class cl_Student_eval(models.Model):
if sStudent is None:
sStudent = self.sStudent
print(f"get_all_evals_for_student launched ! {sStudent}")
self.a_evals = []
evals = cl_Student_eval.objects.filter(sStudent=sStudent).order_by('sRef')
for eval in evals:
@@ -152,29 +154,42 @@ class cl_Student_eval(models.Model):
#print(self.a_evals)
return self.a_evals
@admin.display(description="Présence d'évaluation mirroir", boolean=True)
@admin.display(description="Mirroir ?", boolean=True)
def get_mirrored(self):
self.get_all_evals_for_student()
self.get_mirror_eval(self.a_evals)
return self.mirrored
def get_eval_type(self):
if isinstance(self.nEval_Type, int):
return EVAL_TYPE[int(self.nEval_Type) - 1][1]
def get_inter_nature(self):
return INTER_NATURE[int(self.nInter_Nature)-1][1]
return "Unknown"
def get_inter_complexity(self):
if isinstance(self.nInter_Nature, int):
return INTER_COMPLEXITY[int(self.nInter_Nature) - 1][1]
return "Unknown"
def get_inter_priority(self):
if isinstance(self.nInter_Priority, int):
return INTER_PRIORITY[int(self.nInter_Priority) - 1][1]
return "Unknown"
def get_eval_mode(self):
if isinstance(self.nEval_Mode, int):
return EVAL_MODE[int(self.nEval_Mode) - 1][1]
return "Unknown"
def get_student_role(self):
if isinstance(self.nStudent_Role, int):
return STUDENT_ROLE[int(self.nStudent_Role) - 1][1]
return "Unknown"
def get_inter_nature(self):
if isinstance(self.nInter_Nature,int):
return INTER_NATURE[int(self.nInter_Nature)-1][1]
return "Uncknow"
@@ -212,6 +227,9 @@ def import_data_csv():
value = line[key]
if key == "dtDate":
value = datetime.strptime(value, "%d.%m.%Y").date()
elif key == "sStudent":
temp_obj = cl_Student_eval(
setattr(new_eval, key,value)
new_eval.save()

View File

@@ -0,0 +1,51 @@
{% load static %}
<!doctype html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<!-- Custom CSS -->
<link rel="stylesheet" href="{% static 'bootstrap.min.css' %}">
<link rel="stylesheet" href="{% static 'style.css' %}">
<link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.16/dist/tailwind.min.css" rel="stylesheet">
<title>Intranet StudentEval</title>
</head>
<body class="bg-gray-100">
<div id="wrap">
<nav class="navbar navbar-expand navbar-dark bg-primary mb-3 ps-3 pe-3">
<a href="" class="navbar-brand">Intranet Ambulance Clerc</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarColor01"
aria-controls="navbarColor01"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="w-100">
<ul class="navbar-nav">
<li class="nav-item">
</li>
<li class="nav-item mr-auto">
<a href="{% url 'admin:index' %}" class="nav-link" target="_blank">Administration intranet</a>
</li>
{% block url_nav %}
{% endblock %}
</ul>
</div>
</nav>
{% block content %}
{% endblock %}
<footer class="mt-2 text-center">© 2023 <a href="https://ambulance-clerc.ch"
target="_blank">Ambulance Clerc</a></footer>
{% block script %}
{% endblock %}
</div>
</body>
</html>

View File

@@ -0,0 +1,8 @@
{% extends 'base.html' %}
{% block content %}
<div class="container w-full%">
{% block cl_content %}
{% endblock %}
</div>
{% endblock %}

View File

@@ -0,0 +1,124 @@
<div class="container mx-auto p-6">
<h1 class="text-2xl font-bold mb-4">{% block title %}Détails de l'évaluation ({{ object.ID }}) étudiant de {{ object.sStudent }}{% endblock %}</h1>
<div class="flex rounded-lg shadow overflow-hidden">
<div class="bg-white rounded-lg shadow overflow-hidden w-1/3 m-3">
<table class="w-full table-auto">
<tbody>
<tr class="border-b">
<th class="py-2 px-1 text-left font-semibold">Date de suivi</th>
<td class="py-2 px-1">{{ object.dtDate }}</td>
<th class="py-2 px-1 text-left font-semibold">Date de d'écriture</th>
<td class="py-2 px-1">{{ object.dtCreated }}</td>
</tr>
<tr class="border-b">
<th class="py-2 px-1 text-left font-semibold">Auteur</th>
<td class="py-2 px-1">{{ object.sAuthor }}</td>
<th class="py-2 px-1 text-left font-semibold">Second auteur</th>
<td class="py-2 px-1">{{ object.sAuthor_2e }}</td>
</tr>
<tr class="border-b">
<th class="py-2 px-1 text-left font-semibold">Type de suivi</th>
<td class="py-2 px-1" colspan="3">{{ object.get_eval_type }}</td>
</tr>
{% if object.nEval_Type == "1" %}
<tr class="border-b">
<th class="py-2 px-1 text-left font-semibold">N° FIP</th>
<td class="py-2 px-1">{{ object.sRef }}</td>
<th class="py-2 px-1 text-left font-semibold">Priorité</th>
<td class="py-2 px-1">{{ object.get_inter_priority }}</td>
</tr>
<tr>
<th class="py-2 px-1 text-left font-semibold">Description</th>
<td class="py-2 px-1" colspan="3">{{ object.sInter_Desc }}</td>
</tr>
<tr class="border-b">
<th class="py-2 px-1 text-left font-semibold">Rôle de l'étudiant</th>
<td class="py-2 px-1">{{ object.get_student_role }}</td>
</tr>
<tr class="border-b">
<th class="py-2 px-1 text-left font-semibold">Nature de l'intervention</th>
<td class="py-2 px-1">{{ object.get_inter_nature }}</td>
</tr>
<tr class="border-b">
<th class="py-2 px-1 text-left font-semibold">Complexité de l'intervention</th>
<td class="py-2 px-1" colspan="2">{{ object.get_inter_complexity }}</td>
</tr>
{% endif %}
</tbody>
</table>
</div>
<div class="bg-white rounded-lg shadow overflow-hidden w-3/4 m-3">
<table class="w-full table-auto border-solid">
<tbody>
<tr>
<th class="py-2 px-4 border-solid border-b border-r">
Éléments positifs (auto-évaluation)
</th>
<th class="py-2 px-4 border-solid border-b border-l">
Éléments positifs (Encadrant)
</th>
</tr>
<tr>
<td class="py-2 px-4 border-solid border-b border-r" >
{{object.o_Auto_eval.sDesc_pos}}
</td>
<td class="py-2 px-4 border-solid border-b border-l" >
{{object.o_Encadrant_eval.sDesc_pos}}
</td>
</tr>
<tr>
<td class="py-2 px-4"></td>
</tr>
<tr>
<th class="py-2 px-4 border-solid border-b border-r">
Éléments à améliorer (auto-évaluation)
</th>
<th class="py-2 px-4 border-solid border-b border-l">
Éléments améliorer (Encadrant)
</th>
</tr>
<tr>
<td class="py-2 px-4 border-solid border-b border-r" >
{{object.o_Auto_eval.sDesc_neg}}
</td>
<td class="py-2 px-4 border-solid border-b border-l" >
{{object.o_Encadrant_eval.sDesc_neg}}
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="bg-white rounded-lg shadow overflow-hidden w-full" style="margin-top:10px;">
<table class="w-full">
<tbody>
<tr class="border-b">
<th class="py-2 px-4 text-left font-semibold">Avis Global</th>
</tr>
<tr class="border-b">
<td class="py-2 px-4">{{ object.o_Encadrant_eval.sDesc_global }}</td>
</tr>
<tr class="border-b">
<th class="py-2 px-4 text-left font-semibold">Avis Global (auto)</th>
</tr>
<tr class="border-b">
<td class="py-2 px-4">{{ object.o_Auto_eval.sDesc_global }}</td>
</tr>
</tbody>
</table>
</div>
</div>

View File

@@ -1,137 +1,12 @@
{% extends 'studenteval/base_studenteval.html' %}
{% block url_nav %}
<li>
<a href="{% url 'studenteval:student_eval_list' object.Student.id %}?dtDate__range__gte={{ dtDate__range__gte }}&dtDate__range__lte={{ dtDate__range__lte }}" class="nav-link" target="_blank">Voir toutes les évaluations</a>
</li>
{% endblock %}
{% block cl_content %}
{% include 'studenteval/cl_student_eval.html' with object=object %}
{% endblock %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Détails de l'évaluation étudiant de {{ object.sStudent }}</title>
<link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.16/dist/tailwind.min.css" rel="stylesheet">
</head>
<body class="bg-gray-100">
<div class="container mx-auto p-6">
<h1 class="text-2xl font-bold mb-4">{% block title %}Détails de l'évaluation ({{ object.ID }}) étudiant de {{ object.sStudent }}{% endblock %}</h1>
<div class="flex rounded-lg shadow overflow-hidden">
<div class="bg-white rounded-lg shadow overflow-hidden w-1/3 m-3">
<table class="w-full table-auto">
<tbody>
<tr class="border-b">
<th class="py-2 px-4 text-left font-semibold">Date de suivi</th>
<td class="py-2 px-4">{{ object.dtDate }}</td>
<th class="py-2 px-4 text-left font-semibold">Date de d'écriture</th>
<td class="py-2 px-4">{{ object.dtCreated }}</td>
</tr>
<tr class="border-b">
<th class="py-2 px-4 text-left font-semibold">Auteur</th>
<td class="py-2 px-4">{{ object.sAuthor }}</td>
<th class="py-2 px-4 text-left font-semibold">Second auteur</th>
<td class="py-2 px-4">{{ object.sAuthor_2e }}</td>
</tr>
<tr class="border-b">
<th class="py-2 px-4 text-left font-semibold">Type de suivi</th>
<td class="py-2 px-4" colspan="3">{{ object.get_eval_type }}</td>
</tr>
{% if object.nEval_Type == "1" %}
<tr class="border-b">
<th class="py-2 px-4 text-left font-semibold">N° FIP</th>
<td class="py-2 px-4">{{ object.sRef }}</td>
<th class="py-2 px-4 text-left font-semibold">Priorité</th>
<td class="py-2 px-4">{{ object.get_inter_priority }}</td>
</tr>
<tr>
<th class="py-2 px-4 text-left font-semibold">Description</th>
<td class="py-2 px-4" colspan="3">{{ object.sInter_Desc }}</td>
</tr>
<tr class="border-b">
<th class="py-2 px-4 text-left font-semibold">Rôle de l'étudiant</th>
<td class="py-2 px-4">{{ object.get_student_role }}</td>
</tr>
<tr class="border-b">
<th class="py-2 px-4 text-left font-semibold">Nature de l'intervention</th>
<td class="py-2 px-4">{{ object.get_inter_nature }}</td>
</tr>
<tr class="border-b">
<th class="py-2 px-4 text-left font-semibold">Complexité de l'intervention</th>
<td class="py-2 px-4" colspan="2">{{ object.get_inter_complexity }}</td>
</tr>
{% endif %}
</tbody>
</table>
</div>
<div class="bg-white rounded-lg shadow overflow-hidden w-3/4 m-3">
<table class="w-full table-auto border-solid">
<tbody>
<tr>
<th class="py-2 px-4 border-solid border-b border-r">
Éléments positifs (auto-évaluation) => {{object.o_Auto_eval.ID}}
</th>
<th class="py-2 px-4 border-solid border-b border-l">
Éléments positifs (Encadrant) => {{object.o_Encadrant_eval.ID}}
</th>
</tr>
<tr>
<td class="py-2 px-4 border-solid border-b border-r" >
{{object.o_Auto_eval.sDesc_pos}}
</td>
<td class="py-2 px-4 border-solid border-b border-l" >
{{object.o_Encadrant_eval.sDesc_pos}}
</td>
</tr>
<tr>
<td class="py-2 px-4"></td>
</tr>
<tr>
<th class="py-2 px-4 border-solid border-b border-r">
Éléments à améliorer (auto-évaluation) => {{object.o_Auto_eval.ID}}
</th>
<th class="py-2 px-4 border-solid border-b border-l">
Éléments améliorer (Encadrant) => {{object.o_Encadrant_eval.ID}}
</th>
</tr>
<tr>
<td class="py-2 px-4 border-solid border-b border-r" >
{{object.o_Auto_eval.sDesc_neg}}
</td>
<td class="py-2 px-4 border-solid border-b border-l" >
{{object.o_Encadrant_eval.sDesc_neg}}
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="bg-white rounded-lg shadow overflow-hidden w-full" style="margin-top:10px;">
<table class="w-full">
<tbody>
<tr class="border-b">
<th class="py-2 px-4 text-left font-semibold">Avis Global</th>
</tr>
<tr class="border-b">
<td class="py-2 px-4">{{ object.o_Encadrant_eval.sDesc_global }}</td>
</tr>
<tr class="border-b">
<th class="py-2 px-4 text-left font-semibold">Avis Global (auto)</th>
</tr>
<tr class="border-b">
<td class="py-2 px-4">{{ object.o_Auto_eval.sDesc_global }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,19 @@
{% extends 'studenteval/base_studenteval.html' %}
{% block title %}Liste des évaluations{% endblock %}
{% block cl_content %}
<div class="row">
<div class="col">
{% if object_list %}
{% for obj in object_list reversed %}
{% include 'studenteval/cl_student_eval.html' with object=obj %}
{% if not forloop.last %}
<hr>{% endif %}
{% endfor %}
{% else %}
<p>There is no post.</p>
{% endif %}
</div>
</div>
{% endblock %}

View File

@@ -9,6 +9,7 @@ app_name = "studenteval"
urlpatterns = [
path('show_pdf/<uuid:pk>/', views.student_eval_detail.as_view(), name='student_eval_detail'),
path('show_pdf_all/<int:Student>/', views.student_eval_list.as_view(), name='student_eval_list'),
#path('peremptions', views.view_peremptions, name='view_peremptions'),

View File

@@ -1,20 +1,83 @@
from django.http import HttpResponse
import requests
from django.contrib.auth.mixins import LoginRequiredMixin
from django.http import HttpResponse, Http404
from django.shortcuts import render
from django.views.generic import ListView, UpdateView, DetailView, FormView, CreateView
from django.core.exceptions import PermissionDenied
from studenteval.models import cl_Student_eval
from studenteval.filters import cl_Student_eval_Filter
def show_pdf(request, uuid):
# Votre logique pour l'action 1 ici
return HttpResponse("Action 1 a été effectuée pour l'objet avec l'ID : {}".format(uuid))
class student_eval_detail(DetailView):
def is_member(user, group):
return user.groups.filter(name=group).exists()
class student_eval_detail(LoginRequiredMixin,DetailView):
model =cl_Student_eval
login_url = ""
def dispatch(self, request, *args, **kwargs):
user_obj = self.request.user
author_id = self.get_object().Author.id if self.get_object().Author is not None else 0
student_id = self.get_object().Student.id if self.get_object().Student is not None else 0
if not user_obj.id == author_id and not user_obj.id == student_id and not is_member(user_obj,"FI-Encadrants"):
raise PermissionDenied
return super().dispatch(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["dtDate__range__gte"] = self.request.GET.get('dtDate__range__gte')
context["dtDate__range__lte"] = self.request.GET.get('dtDate__range__lte')
self.object.get_all_evals_for_student()
self.object.get_mirror_eval(self.object.a_evals)
return context
class student_eval_list(LoginRequiredMixin,ListView):
model = cl_Student_eval
login_url = ""
def get_queryset(self):
nStudent_id = self.kwargs['Student']
return cl_Student_eval.objects.filter(Student=nStudent_id)
def dispatch(self, request, *args, **kwargs):
user_obj = self.request.user
#self.object_list.filter(Student=requests.GET['Student'])
'''
author_id = self.get_object().Author.id if self.get_object().Author is not None else 0
student_id = self.get_object().Student.id if self.get_object().Student is not None else 0
if not user_obj.id == author_id and not user_obj.id == student_id and not is_member(user_obj,"FI-Encadrants"):
raise PermissionDenied
'''
return super().dispatch(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['my_objects'] =[]
print(self.get_queryset())
for object in self.get_queryset():
object.get_all_evals_for_student()
object.get_mirror_eval(object.a_evals)
context['my_objects'].append(object)
return context

View File

@@ -38,10 +38,15 @@
$link.addClass('active');
} else if ($parent_link.length) {
$parent_link.addClass('active');
}
}
};
const $a_active = $('a.nav-link.active');
const $main_li_parent = $a_active.closest('li.nav-item.has-treeview');
const $ul_child = $main_li_parent.children('ul');
$ul_child.show();
$main_li_parent.addClass('menu-is-opening menu-open');
};
$(document).ready(function () {
// Set active status on links
@@ -56,8 +61,7 @@
const $changeListTable = $('#changelist .results table');
if ($changeListTable.length && !$changeListTable.hasClass('table table-striped')) {
$changeListTable.addClass('table table-striped');
}
};
});
})(jQuery);

View File

@@ -1,60 +1,10 @@
{% load i18n static jazzmin admin_urls %}
{% get_current_language as LANGUAGE_CODE %}
{% get_current_language_bidi as LANGUAGE_BIDI %}
{% extends "registration/base.html" %}
{% load i18n jazzmin %}
{% get_jazzmin_settings request as jazzmin_settings %}
{% get_jazzmin_ui_tweaks as jazzmin_ui %}
<!DOCTYPE html>
<html lang="{{ LANGUAGE_CODE|default:"en-us" }}" {% if LANGUAGE_BIDI %}dir="rtl"{% endif %}>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<title>{% block title %}{{ title }} | {% trans 'Log in again' %}{% endblock %}</title>
<!-- Font Awesome Icons -->
<link rel="stylesheet" href="{% static "vendor/fontawesome-free/css/all.min.css" %}">
<!-- Bootstrap and adminLTE -->
<link rel="stylesheet" href="{% static "vendor/adminlte/css/adminlte.min.css" %}">
<!-- Bootswatch theme -->
{% if jazzmin_ui.theme.name != 'default' %}
<link rel="stylesheet" href="{{ jazzmin_ui.theme.src }}" id="jazzmin-theme" />
{% endif %}
{% if jazzmin_ui.dark_mode_theme %}
<link rel="stylesheet" href="{{ jazzmin_ui.dark_mode_theme.src }}" id="jazzmin-dark-mode-theme" media="(prefers-color-scheme: dark)"/>
{% endif %}
<!-- Custom fixes for django -->
<link rel="stylesheet" href="{% static "jazzmin/css/main.css" %}">
{% if jazzmin_settings.custom_css %}
<!-- Custom CSS -->
<link rel="stylesheet" href="{% static jazzmin_settings.custom_css %}">
{% endif %}
<!-- favicons -->
<link rel="shortcut icon" href="{% static jazzmin_settings.site_icon %}" type="image/png">
<link rel="icon" href="{% static jazzmin_settings.site_icon %}" sizes="32x32" type="image/png">
<!-- Google Font: Source Sans Pro -->
<link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,400i,700" rel="stylesheet">
{% block extrastyle %} {% endblock %}
{% block extrahead %} {% endblock %}
</head>
<body class="hold-transition jazzmin-login-page">
<div class="login-box">
<div class="login-logo">
<h1>{{ jazzmin_settings.site_header }}</h1>
</div>
<div class="card">
<div class="card-body">
{% block content %}
<p class="login-box-msg">{{ jazzmin_settings.welcome_sign }}</p>
<form action="{{ app_path }}" method="post">
{% csrf_token %}
@@ -71,19 +21,16 @@
</p>
{% endif %}
{% if form.errors %}
{% if form.username.errors %}
<div class="callout callout-danger">
<p>{{ form.username.label }}: {{ form.username.errors|join:', ' }}</p>
</div>
{% endif %}
{% if form.password.errors %}
<div class="callout callout-danger">
<p>{{ form.password.label }}: {{ form.password.errors|join:', ' }}</p>
</div>
{% endif %}
{% if form.non_field_errors %}
<div class="callout callout-danger">
{% for error in form.non_field_errors %}
@@ -91,7 +38,6 @@
{% endfor %}
</div>
{% endif %}
{% endif %}
<div class="input-group mb-3">
<input type="text" name="username" class="form-control" placeholder="{{ form.username.label }}" required>
@@ -109,27 +55,22 @@
</div>
</div>
</div>
{% url 'admin_password_reset' as password_reset_url %}
{% if password_reset_url %}
<div class="mb-3">
<div class="password-reset-link" style="text-align: center;">
<a href="{{ password_reset_url }}">
{% trans 'Forgotten your password or username?' %}
</a>
</div>
</div>
{% endif %}
<div class="row">
<div class="col-12">
<button type="submit" class="btn {{ jazzmin_ui.button_classes.primary }} btn-block">{% trans "Log in" %}</button>
<button type="submit" class="btn {{ jazzmin_ui.button_classes.primary }} btn-block">
{% trans "Log in" %}
</button>
</div>
</div>
</form>
</div>
</div>
</div>
<!-- jQuery -->
<script src="{% static "admin/js/vendor/jquery/jquery.js" %}"></script>
<!-- Bootstrap 4 -->
<script src="{% static 'vendor/bootstrap/js/bootstrap.min.js' %}"></script>
<!-- AdminLTE App -->
<script src="{% static 'vendor/adminlte/js/adminlte.min.js' %}"></script>
{% if jazzmin_settings.custom_js %}
<script src="{% static jazzmin_settings.custom_js %}"></script>
{% endif %}
</body>
</html>
{% endblock %}