Améliore formsemestre_list_saisies_notes

This commit is contained in:
Emmanuel Viennet 2024-11-08 00:15:39 +01:00
parent 07423e08b6
commit 6cd28853bc
8 changed files with 153 additions and 40 deletions

View File

@ -141,7 +141,7 @@ class Assiduite(ScoDocModel):
}""" }"""
def __repr__(self) -> str: def __repr__(self) -> str:
return f"<Assiduite {self.id}: {self.__str__()}>" return f"<Assiduite {self.id}: {self.etudiant.nom}: {self.__str__()}>"
@classmethod @classmethod
def create_assiduite( def create_assiduite(

View File

@ -127,6 +127,12 @@ class Identite(models.ScoDocModel):
cascade="all, delete-orphan", cascade="all, delete-orphan",
lazy="dynamic", lazy="dynamic",
) )
notes_log = db.relationship(
"NotesNotesLog",
backref="etudiant",
cascade="all, delete-orphan",
lazy="dynamic",
)
# Relations avec les assiduites et les justificatifs # Relations avec les assiduites et les justificatifs
assiduites = db.relationship( assiduites = db.relationship(
"Assiduite", back_populates="etudiant", lazy="dynamic", cascade="all, delete" "Assiduite", back_populates="etudiant", lazy="dynamic", cascade="all, delete"

View File

@ -64,6 +64,13 @@ class Evaluation(models.ScoDocModel):
cascade="all, delete-orphan", cascade="all, delete-orphan",
lazy="dynamic", lazy="dynamic",
) )
notes_log = db.relationship(
"NotesNotesLog",
backref="evaluation",
cascade="all, delete-orphan",
lazy="dynamic",
primaryjoin="Evaluation.id == foreign(NotesNotesLog.evaluation_id)",
)
ues = db.relationship("UniteEns", secondary="evaluation_ue_poids", viewonly=True) ues = db.relationship("UniteEns", secondary="evaluation_ue_poids", viewonly=True)
_sco_dept_relations = ("ModuleImpl", "FormSemestre") # accès au dept_id _sco_dept_relations = ("ModuleImpl", "FormSemestre") # accès au dept_id

View File

@ -499,11 +499,7 @@ class GenTable:
H.append(caption) H.append(caption)
if self.base_url: if self.base_url:
H.append('<span class="gt_export_icons">') H.append('<span class="gt_export_icons">')
if self.xls_link: H.append(self.xls_export_button())
H.append(
f""" <a href="{add_query_param(self.base_url, "fmt", "xls")
}">{scu.ICON_XLS}</a>"""
)
if self.xls_link and self.pdf_link: if self.xls_link and self.pdf_link:
H.append("&nbsp;") H.append("&nbsp;")
if self.pdf_link: if self.pdf_link:
@ -517,6 +513,15 @@ class GenTable:
H.append(self.html_next_section) H.append(self.html_next_section)
return "\n".join(H) return "\n".join(H)
def xls_export_button(self) -> str:
"markup pour export excel"
return (
f""" <a href="{add_query_param(self.base_url, "fmt", "xls")
}">{scu.ICON_XLS}</a>"""
if self.xls_link
else ""
)
def excel(self, wb=None): def excel(self, wb=None):
"""Simple Excel representation of the table""" """Simple Excel representation of the table"""
if wb is None: if wb is None:

View File

@ -46,9 +46,11 @@ Opérations:
""" """
import datetime import datetime
from flask import g, request, url_for from flask import g, render_template, request, url_for
from app.models import Evaluation, FormSemestre from app import db
from app.auth.models import User
from app.models import Evaluation, FormSemestre, ModuleImpl, NotesNotes, NotesNotesLog
from app.scodoc.intervals import intervalmap from app.scodoc.intervals import intervalmap
import app.scodoc.sco_utils as scu import app.scodoc.sco_utils as scu
import app.scodoc.notesdb as ndb import app.scodoc.notesdb as ndb
@ -178,36 +180,67 @@ def evaluation_list_operations(evaluation_id: int):
return tab.make_page() return tab.make_page()
def formsemestre_list_saisies_notes(formsemestre_id, fmt="html"): def formsemestre_list_saisies_notes(formsemestre_id, only_modifs=False, fmt="html"):
"""Table listant toutes les opérations de saisies de notes, dans toutes """Table listant toutes les opérations de saisies de notes, dans toutes
les évaluations du semestre. les évaluations du semestre.
""" """
formsemestre: FormSemestre = FormSemestre.get_or_404(formsemestre_id) formsemestre: FormSemestre = FormSemestre.get_formsemestre(formsemestre_id)
rows = ndb.SimpleDictFetch( only_modifs = scu.to_bool(only_modifs)
"""SELECT i.nom, i.prenom, code_nip, n.*, mod.titre, e.description, e.date_debut, model = NotesNotesLog if only_modifs else NotesNotes
u.user_name, e.id as evaluation_id notes_query = (
FROM notes_notes n, notes_evaluation e, notes_moduleimpl mi, db.session.query(model)
notes_modules mod, identite i, "user" u .join(Evaluation, Evaluation.id == model.evaluation_id)
WHERE mi.id = e.moduleimpl_id .join(ModuleImpl)
and mi.module_id = mod.id .filter_by(formsemestre_id=formsemestre.id)
and e.id = n.evaluation_id .order_by(model.date.desc())
and i.id = n.etudid
and u.id = n.uid
and mi.formsemestre_id = %(formsemestre_id)s
ORDER BY date desc
""",
{"formsemestre_id": formsemestre_id},
) )
# Formate les notes # Formate les notes
keep_numeric = fmt in scu.FORMATS_NUMERIQUES keep_numeric = fmt in scu.FORMATS_NUMERIQUES
for row in rows: rows = []
row["value"] = scu.fmt_note(row["value"], keep_numeric=keep_numeric) for note in notes_query:
row["date_evaluation"] = ( ens = User.get_user(note.uid)
row["date_debut"].strftime("%d/%m/%Y %H:%M") if row["date_debut"] else "" evaluation = note.evaluation
) rows.append(
row["_date_evaluation_order"] = ( {
row["date_debut"].isoformat() if row["date_debut"] else "" "date": note.date.strftime(scu.DATEATIME_FMT),
"_date_order": note.date.isoformat(),
"code_nip": note.etudiant.code_nip,
"nom": note.etudiant.nom_disp(),
"prenom": note.etudiant.prenom_str,
"date_evaluation": (
evaluation.date_debut.strftime(scu.DATEATIME_FMT)
if evaluation and note.evaluation.date_debut
else ""
),
"_date_evaluation_order": (
note.evaluation.date_debut.isoformat()
if evaluation and note.evaluation.date_debut
else ""
),
"value": scu.fmt_note(note.value, keep_numeric=keep_numeric),
"module": (
(
note.evaluation.moduleimpl.module.code
or note.evaluation.moduleimpl.module.titre
)
if evaluation
else ""
),
"evaluation": note.evaluation.description if evaluation else "",
"_evaluation_target": (
url_for(
"notes.evaluation_listenotes",
scodoc_dept=g.scodoc_dept,
evaluation_id=note.evaluation_id,
)
if evaluation
else ""
),
"user_name": ens.user_name if ens else "",
}
) )
columns_ids = ( columns_ids = (
"date", "date",
"code_nip", "code_nip",
@ -215,9 +248,8 @@ def formsemestre_list_saisies_notes(formsemestre_id, fmt="html"):
"prenom", "prenom",
"value", "value",
"user_name", "user_name",
"titre", "module",
"evaluation_id", "evaluation",
"description",
"date_evaluation", "date_evaluation",
"comment", "comment",
) )
@ -230,11 +262,11 @@ def formsemestre_list_saisies_notes(formsemestre_id, fmt="html"):
"comment": "Remarque", "comment": "Remarque",
"user_name": "Enseignant", "user_name": "Enseignant",
"evaluation_id": "evaluation_id", "evaluation_id": "evaluation_id",
"titre": "Module", "module": "Module",
"description": "Evaluation", "evaluation": "Evaluation",
"date_evaluation": "Date éval.", "date_evaluation": "Date éval.",
} }
tab = GenTable( table = GenTable(
titles=titles, titles=titles,
columns_ids=columns_ids, columns_ids=columns_ids,
rows=rows, rows=rows,
@ -244,11 +276,25 @@ def formsemestre_list_saisies_notes(formsemestre_id, fmt="html"):
html_sortable=True, html_sortable=True,
caption=f"Saisies de notes dans {formsemestre.titre_annee()}", caption=f"Saisies de notes dans {formsemestre.titre_annee()}",
preferences=sco_preferences.SemPreferences(formsemestre_id), preferences=sco_preferences.SemPreferences(formsemestre_id),
base_url="%s?formsemestre_id=%s" % (request.base_url, formsemestre_id), base_url=f"""{request.base_url}?formsemestre_id={
formsemestre_id}&only_modifs={int(only_modifs)}""",
origin=f"Généré par {sco_version.SCONAME} le " + scu.timedate_human_repr() + "", origin=f"Généré par {sco_version.SCONAME} le " + scu.timedate_human_repr() + "",
table_id="formsemestre_list_saisies_notes", table_id="formsemestre_list_saisies_notes",
filename=(
f"modifs_notes_S{formsemestre.semestre_id}"
if only_modifs
else f"saisies_notes_S{formsemestre.semestre_id}"
),
) )
return tab.make_page(fmt=fmt) if fmt == "html":
return render_template(
"formsemestre/list_saisies_notes.j2",
table=table,
title="Opérations de saisies de notes",
only_modifs=only_modifs,
formsemestre_id=formsemestre.id,
)
return table.make_page(fmt=fmt, page_title="Opérations de saisies de notes")
def get_note_history(evaluation_id, etudid, fmt=""): def get_note_history(evaluation_id, etudid, fmt=""):

View File

@ -0,0 +1,48 @@
{% extends "sco_page.j2" %}
{% block styles %}
{{super()}}
<style>
.export_xls_but {
margin-left: 32px;
}
</style>
{% endblock %}
{% block app_content %}
<h2 class="formsemestre">{{title_h2}}</h2>
<div>{{table.get_nb_rows()}}
{% if only_modifs %}modifications{% else %}saisies{% endif %}
de notes dans ce semestre.
</div>
<form id="filter-form">
<label>
<input type="checkbox" id="only-modifs-checkbox" name="only_modifs" value="1"
{% if only_modifs %}checked{% endif %}>
Lister uniquement les modifications
</label>
<span class="export_xls_but">{{table.xls_export_button()|safe}} excel</span>
</form>
{{table.html()|safe}}
{% endblock %}
{% block scripts %}
{{super()}}
<script>
document.getElementById('only-modifs-checkbox').addEventListener('change', function() {
var form = document.getElementById('filter-form');
var onlyModifs = this.checked ? '1' : '0';
var url = new URL(window.location.href);
url.searchParams.set('formsemestre_id', {{formsemestre_id}});
url.searchParams.set('only_modifs', onlyModifs);
window.location.href = url.toString();
});
</script>
{% endblock %}

View File

@ -3,7 +3,7 @@
"Infos sur version ScoDoc" "Infos sur version ScoDoc"
SCOVERSION = "9.7.39" SCOVERSION = "9.7.40"
SCONAME = "ScoDoc" SCONAME = "ScoDoc"

View File

@ -94,6 +94,7 @@ def test_permissions(api_headers):
"/ScoDoc/api/justificatif/1/list", # demande AbsJustifView "/ScoDoc/api/justificatif/1/list", # demande AbsJustifView
"/ScoDoc/api/justificatif/1/justifies", # demande ScoJustifChange "/ScoDoc/api/justificatif/1/justifies", # demande ScoJustifChange
"/ScoDoc/api/justificatif/1/export", # demande AbsChange "/ScoDoc/api/justificatif/1/export", # demande AbsChange
"/ScoDoc/api/operations/user/", # demande superamin ou user lui même
] ]
): ):
# On passe ces routes spéciales # On passe ces routes spéciales