ScoDoc-PE/app/models/notes.py

137 lines
4.3 KiB
Python

# -*- coding: UTF-8 -*
"""Notes, décisions de jury, évènements scolaires
"""
import sqlalchemy as sa
from app import db
from app.scodoc import safehtml
import app.scodoc.sco_utils as scu
class BulAppreciations(db.Model):
"""Appréciations sur bulletins"""
__tablename__ = "notes_appreciations"
id = db.Column(db.Integer, primary_key=True)
date = db.Column(db.DateTime(timezone=True), server_default=db.func.now())
etudid = db.Column(
db.Integer,
db.ForeignKey("identite.id", ondelete="CASCADE"),
index=True,
)
formsemestre_id = db.Column(
db.Integer,
db.ForeignKey("notes_formsemestre.id"),
)
author = db.Column(db.Text) # le pseudo (user_name), sans contrainte
comment = db.Column(db.Text) # texte libre
@classmethod
def get_appreciations_list(
cls, formsemestre_id: int, etudid: int
) -> list["BulAppreciations"]:
"Liste des appréciations pour cet étudiant dans ce semestre"
return (
BulAppreciations.query.filter_by(
etudid=etudid, formsemestre_id=formsemestre_id
)
.order_by(BulAppreciations.date)
.all()
)
@classmethod
def summarize(cls, appreciations: list["BulAppreciations"]) -> list[str]:
"Liste de chaines résumant une liste d'appréciations, pour bulletins"
return [
f"{x.date.strftime('%d/%m/%Y') if x.date else ''}: {x.comment or ''}"
for x in appreciations
]
def comment_safe(self) -> str:
"Le comment, safe pour inclusion dans HTML (None devient '')"
return safehtml.html_to_safe_html(self.comment or "")
class NotesNotes(db.Model):
"""Une note"""
__tablename__ = "notes_notes"
__table_args__ = (db.UniqueConstraint("etudid", "evaluation_id"),)
id = db.Column(db.Integer, primary_key=True)
etudid = db.Column(
db.Integer,
db.ForeignKey("identite.id", ondelete="CASCADE"),
)
evaluation_id = db.Column(
db.Integer, db.ForeignKey("notes_evaluation.id"), index=True
)
value = db.Column(db.Float)
# infos sur saisie de cette note:
comment = db.Column(db.Text) # texte libre
date = db.Column(db.DateTime(timezone=True), server_default=db.func.now())
uid = db.Column(db.Integer, db.ForeignKey("user.id"))
def to_dict(self) -> dict:
"dict"
d = dict(self.__dict__)
d.pop("_sa_instance_state", None)
return d
def __repr__(self):
"pour debug"
from app.models.evaluations import Evaluation
return f"""<{self.__class__.__name__} {self.id} etudid={self.etudid} v={self.value} {self.date.isoformat()
} {db.session.get(Evaluation, self.evaluation_id) if self.evaluation_id else "X" }>"""
class NotesNotesLog(db.Model):
"""Historique des modifs sur notes (anciennes entrees de notes_notes)"""
__tablename__ = "notes_notes_log"
id = db.Column(db.Integer, primary_key=True)
etudid = db.Column(
db.Integer,
db.ForeignKey("identite.id", ondelete="CASCADE"),
)
evaluation_id = db.Column(
db.Integer,
# db.ForeignKey("notes_evaluation.id"),
index=True,
)
value = db.Column(db.Float)
# infos sur saisie de cette note:
comment = db.Column(db.Text) # texte libre
date = db.Column(db.DateTime(timezone=True), server_default=db.func.now())
uid = db.Column(db.Integer, db.ForeignKey("user.id"))
def etud_has_notes_attente(etudid, formsemestre_id):
"""Vrai si cet etudiant a au moins une note en attente dans ce semestre.
(ne compte que les notes en attente dans des évaluations avec coef. non nul).
"""
cursor = db.session.execute(
sa.text(
"""SELECT COUNT(*)
FROM notes_notes n, notes_evaluation e, notes_moduleimpl m,
notes_moduleimpl_inscription i
WHERE n.etudid = :etudid
and n.value = :code_attente
and n.evaluation_id = e.id
and e.moduleimpl_id = m.id
and m.formsemestre_id = :formsemestre_id
and e.coefficient != 0
and m.id = i.moduleimpl_id
and i.etudid = :etudid
"""
),
{
"formsemestre_id": formsemestre_id,
"etudid": etudid,
"code_attente": scu.NOTES_ATTENTE,
},
)
return cursor.fetchone()[0] > 0