# -*- coding: UTF-8 -* """Notes, décisions de jury, évènements scolaires """ import sqlalchemy as sa from app import db from app import models from app.scodoc import safehtml import app.scodoc.sco_utils as scu class BulAppreciations(models.ScoDocModel): """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 _sco_dept_relations = ("Identite",) # accès au dept_id @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