forked from ScoDoc/ScoDoc
Première version des modèles ScoDoc7 en SQLAlchemy
This commit is contained in:
parent
383fdb0e53
commit
dad6fdd63c
@ -1,7 +0,0 @@
|
||||
# -*- coding: UTF-8 -*
|
||||
|
||||
"""ScoDoc8 models
|
||||
"""
|
||||
|
||||
# None, at this point
|
||||
# see auth.models for user/role related models
|
57
app/models/__init__.py
Normal file
57
app/models/__init__.py
Normal file
@ -0,0 +1,57 @@
|
||||
# -*- coding: UTF-8 -*
|
||||
|
||||
"""Modèles base de données ScoDoc
|
||||
XXX version préliminaire ScoDoc8 #sco8 sans département
|
||||
"""
|
||||
|
||||
CODE_STR_LEN = 16 # chaine pour les codes
|
||||
SHORT_STR_LEN = 32 # courtes chaine, eg acronymes
|
||||
APO_CODE_STR_LEN = 16 # nb de car max d'un code Apogée
|
||||
|
||||
from app.models.absences import Absence, AbsenceNotification, BilletAbsence
|
||||
from app.models.entreprises import (
|
||||
Entreprise,
|
||||
EntrepriseCorrespondant,
|
||||
EntrepriseContact,
|
||||
)
|
||||
from app.models.etudiants import (
|
||||
Identite,
|
||||
Adresse,
|
||||
Admission,
|
||||
ItemSuivi,
|
||||
ItemSuiviTag,
|
||||
EtudAnnotation,
|
||||
)
|
||||
from app.models.events import Scolog, ScolarNews
|
||||
from app.models.formations import (
|
||||
NotesFormation,
|
||||
NotesUE,
|
||||
NotesMatiere,
|
||||
NotesModule,
|
||||
NotesTag,
|
||||
)
|
||||
from app.models.formsemestre import (
|
||||
FormSemestre,
|
||||
NotesFormsemestreEtape,
|
||||
FormModalite,
|
||||
NotesFormsemestreUECoef,
|
||||
NotesFormsemestreUEComputationExpr,
|
||||
NotesFormsemestreCustomMenu,
|
||||
NotesFormsemestreInscription,
|
||||
NotesModuleImpl,
|
||||
notes_modules_enseignants,
|
||||
NotesModuleImplInscription,
|
||||
NotesEvaluation,
|
||||
NotesSemSet,
|
||||
notes_semset_formsemestre,
|
||||
)
|
||||
from app.models.groups import Partition, GroupDescr, group_membership
|
||||
from app.models.notes import (
|
||||
ScolarEvent,
|
||||
ScolarFormsemestreValidation,
|
||||
ScolarAutorisationInscription,
|
||||
NotesAppreciations,
|
||||
NotesNotes,
|
||||
NotesNotesLog,
|
||||
)
|
||||
from app.models.preferences import ScoPreferences
|
75
app/models/absences.py
Normal file
75
app/models/absences.py
Normal file
@ -0,0 +1,75 @@
|
||||
# -*- coding: UTF-8 -*
|
||||
|
||||
"""Gestion des absences
|
||||
"""
|
||||
|
||||
from app import db
|
||||
from app.models import APO_CODE_STR_LEN
|
||||
from app.models import SHORT_STR_LEN
|
||||
from app.models import CODE_STR_LEN
|
||||
|
||||
|
||||
class Absence(db.Model):
|
||||
"""une absence (sur une demi-journée)"""
|
||||
|
||||
__tablename__ = "absences"
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
etudid = db.Column(db.Integer, db.ForeignKey("identite.id"), index=True)
|
||||
jour = db.Column(db.Date)
|
||||
estabs = db.Column(db.Boolean())
|
||||
estjust = db.Column(db.Boolean())
|
||||
matin = db.Column(db.Boolean())
|
||||
# motif de l'absence:
|
||||
description = db.Column(db.Text())
|
||||
entry_date = db.Column(db.DateTime(timezone=True), server_default=db.func.now())
|
||||
# moduleimpid concerne (optionnel):
|
||||
moduleimpl_id = db.Column(
|
||||
db.Integer,
|
||||
db.ForeignKey("notes_moduleimpl.id"),
|
||||
)
|
||||
# XXX TODO: contrainte ajoutée: vérifier suppression du module
|
||||
# (mettre à NULL sans supprimer)
|
||||
|
||||
|
||||
class AbsenceNotification(db.Model):
|
||||
"""Notification d'absence émise"""
|
||||
|
||||
__tablename__ = "absences_notifications"
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
etudid = db.Column(
|
||||
db.Integer,
|
||||
db.ForeignKey("identite.id"),
|
||||
)
|
||||
notification_date = db.Column(
|
||||
db.DateTime(timezone=True), server_default=db.func.now()
|
||||
)
|
||||
email = db.Column(db.Text())
|
||||
nbabs = db.Column(db.Integer)
|
||||
nbabsjust = db.Column(db.Integer)
|
||||
formsemestre_id = db.Column(
|
||||
db.Integer,
|
||||
db.ForeignKey("notes_formsemestre.id"),
|
||||
)
|
||||
|
||||
|
||||
class BilletAbsence(db.Model):
|
||||
"""Billet d'absence (signalement par l'étudiant)"""
|
||||
|
||||
__tablename__ = "billet_absence"
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
etudid = db.Column(
|
||||
db.Integer,
|
||||
db.ForeignKey("identite.id"),
|
||||
index=True,
|
||||
)
|
||||
abs_begin = db.Column(db.DateTime(timezone=True))
|
||||
abs_end = db.Column(db.DateTime(timezone=True))
|
||||
# raison de l'absence:
|
||||
description = db.Column(db.Text())
|
||||
# False: new, True: processed
|
||||
etat = db.Column(db.Boolean(), default=False)
|
||||
entry_date = db.Column(db.DateTime(timezone=True), server_default=db.func.now())
|
||||
# true si l'absence _pourrait_ etre justifiée
|
||||
justified = db.Column(db.Boolean(), default=False)
|
69
app/models/entreprises.py
Normal file
69
app/models/entreprises.py
Normal file
@ -0,0 +1,69 @@
|
||||
# -*- coding: UTF-8 -*
|
||||
|
||||
"""Gestion des absences
|
||||
"""
|
||||
|
||||
from app import db
|
||||
from app.models import APO_CODE_STR_LEN
|
||||
from app.models import SHORT_STR_LEN
|
||||
from app.models import CODE_STR_LEN
|
||||
|
||||
|
||||
class Entreprise(db.Model):
|
||||
"""une entreprise"""
|
||||
|
||||
__tablename__ = "entreprises"
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
entreprise_id = db.synonym("id")
|
||||
|
||||
nom = db.Column(db.Text)
|
||||
adresse = db.Column(db.Text)
|
||||
ville = db.Column(db.Text)
|
||||
codepostal = db.Column(db.Text)
|
||||
pays = db.Column(db.Text)
|
||||
contact_origine = db.Column(db.Text)
|
||||
secteur = db.Column(db.Text)
|
||||
note = db.Column(db.Text)
|
||||
privee = db.Column(db.Text)
|
||||
localisation = db.Column(db.Text)
|
||||
# -1 inconnue, 0, 25, 50, 75, 100:
|
||||
qualite_relation = db.Column(db.Integer)
|
||||
plus10salaries = db.Column(db.Boolean())
|
||||
date_creation = db.Column(db.DateTime(timezone=True), server_default=db.func.now())
|
||||
|
||||
|
||||
class EntrepriseCorrespondant(db.Model):
|
||||
"""Personne contact en entreprise"""
|
||||
|
||||
__tablename__ = "entreprise_correspondant"
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
entreprise_corresp_id = db.synonym("id")
|
||||
entreprise_id = db.Column(db.Integer, db.ForeignKey("entreprises.id"))
|
||||
nom = db.Column(db.Text)
|
||||
prenom = db.Column(db.Text)
|
||||
civilite = db.Column(db.Text)
|
||||
fonction = db.Column(db.Text)
|
||||
phone1 = db.Column(db.Text)
|
||||
phone2 = db.Column(db.Text)
|
||||
mobile = db.Column(db.Text)
|
||||
mail1 = db.Column(db.Text)
|
||||
mail2 = db.Column(db.Text)
|
||||
fax = db.Column(db.Text)
|
||||
note = db.Column(db.Text)
|
||||
|
||||
|
||||
class EntrepriseContact(db.Model):
|
||||
"""Evènement (contact) avec une entreprise"""
|
||||
|
||||
__tablename__ = "entreprise_contact"
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
entreprise_contact_id = db.synonym("id")
|
||||
date = db.Column(db.DateTime(timezone=True))
|
||||
type_contact = db.Column(db.Text)
|
||||
entreprise_id = db.Column(db.Integer, db.ForeignKey("entreprises.id"))
|
||||
entreprise_corresp_id = db.Column(
|
||||
db.Integer, db.ForeignKey("entreprise_correspondant.id")
|
||||
)
|
||||
etudid = db.Column(db.Integer) # sans contrainte pour garder logs après suppression
|
||||
description = db.Column(db.Text)
|
||||
enseignant = db.Column(db.Text)
|
153
app/models/etudiants.py
Normal file
153
app/models/etudiants.py
Normal file
@ -0,0 +1,153 @@
|
||||
# -*- coding: UTF-8 -*
|
||||
|
||||
"""Définition d'un étudiant
|
||||
et données rattachées (adresses, annotations, ...)
|
||||
"""
|
||||
|
||||
from app import db
|
||||
from app.models import APO_CODE_STR_LEN
|
||||
from app.models import SHORT_STR_LEN
|
||||
from app.models import CODE_STR_LEN
|
||||
|
||||
|
||||
class Identite(db.Model):
|
||||
"""étudiant"""
|
||||
|
||||
__tablename__ = "identite"
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
etudid = db.synonym("id")
|
||||
|
||||
nom = db.Column(db.Text())
|
||||
prenom = db.Column(db.Text())
|
||||
nom_usuel = db.Column(db.Text())
|
||||
# optionnel (si present, affiché à la place du nom)
|
||||
civilite = db.Column(db.String(1), nullable=False)
|
||||
__table_args__ = (db.CheckConstraint("civilite IN ('M', 'F', 'X')"),)
|
||||
|
||||
date_naissance = db.Column(db.Date)
|
||||
lieu_naissance = db.Column(db.Text())
|
||||
dept_naissance = db.Column(db.Text())
|
||||
nationalite = db.Column(db.Text())
|
||||
statut = db.Column(db.Text())
|
||||
boursier = db.Column(db.Boolean()) # True si boursier ('O' en ScoDoc7)
|
||||
photo_filename = db.Column(db.Text())
|
||||
code_nip = db.Column(db.String(CODE_STR_LEN), unique=True)
|
||||
code_ine = db.Column(db.String(CODE_STR_LEN), unique=True)
|
||||
|
||||
|
||||
class Adresse(db.Model):
|
||||
"""Adresse d'un étudiant
|
||||
(le modèle permet plusieurs adresses, mais l'UI n'en gère qu'une seule)
|
||||
"""
|
||||
|
||||
__tablename__ = "adresse"
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
adresse_id = db.synonym("id")
|
||||
etudid = db.Column(
|
||||
db.Integer,
|
||||
db.ForeignKey("identite.id"),
|
||||
)
|
||||
email = db.Column(db.Text()) # mail institutionnel
|
||||
emailperso = db.Column(db.Text) # email personnel (exterieur)
|
||||
domicile = db.Column(db.Text)
|
||||
codepostaldomicile = db.Column(db.Text)
|
||||
villedomicile = db.Column(db.Text)
|
||||
paysdomicile = db.Column(db.Text)
|
||||
telephone = db.Column(db.Text)
|
||||
telephonemobile = db.Column(db.Text)
|
||||
fax = db.Column(db.Text)
|
||||
typeadresse = db.Column(db.Text, default="domicile", nullable=False)
|
||||
description = db.Column(db.Text)
|
||||
|
||||
|
||||
class Admission(db.Model):
|
||||
"""Informations liées à l'admission d'un étudiant"""
|
||||
|
||||
__tablename__ = "admissions"
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
adm_id = db.synonym("id")
|
||||
etudid = db.Column(
|
||||
db.Integer,
|
||||
db.ForeignKey("identite.id"),
|
||||
)
|
||||
# Anciens champs de ScoDoc7, à revoir pour être plus générique et souple
|
||||
# notamment dans le cadre du bac 2021
|
||||
# de plus, certaines informations liées à APB ne sont plus disponibles
|
||||
# avec Parcoursup
|
||||
annee = db.Column(db.Integer)
|
||||
bac = db.Column(db.Text)
|
||||
specialite = db.Column(db.Text)
|
||||
annee_bac = db.Column(db.Integer)
|
||||
math = db.Column(db.Text)
|
||||
physique = db.Column(db.Float)
|
||||
anglais = db.Column(db.Float)
|
||||
francais = db.Column(db.Float)
|
||||
# Rang dans les voeux du candidat (inconnu avec APB et PS)
|
||||
rang = db.Column(db.Integer)
|
||||
# Qualité et décision du jury d'admission (ou de l'examinateur)
|
||||
qualite = db.Column(db.Float)
|
||||
rapporteur = db.Column(db.Text)
|
||||
decision = db.Column(db.Text)
|
||||
score = db.Column(db.Float)
|
||||
commentaire = db.Column(db.Text)
|
||||
# Lycée d'origine:
|
||||
nomlycee = db.Column(db.Text)
|
||||
villelycee = db.Column(db.Text)
|
||||
codepostallycee = db.Column(db.Text)
|
||||
codelycee = db.Column(db.Text)
|
||||
# 'APB', 'APC-PC', 'CEF', 'Direct', '?' (autre)
|
||||
type_admission = db.Column(db.Text)
|
||||
# était boursier dans le cycle precedent (lycee) ?
|
||||
boursier_prec = db.Column(db.Boolean())
|
||||
# classement par le jury d'admission (1 à N),
|
||||
# global (pas celui d'APB si il y a des groupes)
|
||||
classement = db.Column(db.Integer)
|
||||
# code du groupe APB
|
||||
apb_groupe = db.Column(db.Text)
|
||||
# classement (1..Ngr) par le jury dans le groupe APB
|
||||
apb_classement_gr = db.Column(db.Integer)
|
||||
|
||||
|
||||
# Suivi scolarité / débouchés
|
||||
class ItemSuivi(db.Model):
|
||||
__tablename__ = "itemsuivi"
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
itemsuivi_id = db.synonym("id")
|
||||
etudid = db.Column(
|
||||
db.Integer,
|
||||
db.ForeignKey("identite.id"),
|
||||
)
|
||||
item_date = db.Column(db.DateTime(timezone=True), server_default=db.func.now())
|
||||
situation = db.Column(db.Text)
|
||||
|
||||
|
||||
class ItemSuiviTag(db.Model):
|
||||
__tablename__ = "itemsuivi_tags"
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
tag_id = db.synonym("id")
|
||||
title = db.Column(db.String(SHORT_STR_LEN), nullable=False, unique=True)
|
||||
|
||||
|
||||
# Association tag <-> module
|
||||
itemsuivi_tags_assoc = db.Table(
|
||||
"itemsuivi_tags_assoc",
|
||||
db.Column("tag_id", db.Integer, db.ForeignKey("itemsuivi_tags.id")),
|
||||
db.Column("itemsuivi_id", db.Integer, db.ForeignKey("itemsuivi.id")),
|
||||
)
|
||||
# ON DELETE CASCADE ?
|
||||
|
||||
|
||||
class EtudAnnotation(db.Model):
|
||||
"""Annotation sur un étudiant"""
|
||||
|
||||
__tablename__ = "etud_annotations"
|
||||
|
||||
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) # sans contrainte pour garder logs après suppression
|
||||
authenticated_user = db.Column(db.Text)
|
||||
comment = db.Column(db.Text)
|
35
app/models/events.py
Normal file
35
app/models/events.py
Normal file
@ -0,0 +1,35 @@
|
||||
# -*- coding: UTF-8 -*
|
||||
|
||||
"""Evenements et logs divers
|
||||
"""
|
||||
|
||||
from app import db
|
||||
from app.models import APO_CODE_STR_LEN
|
||||
from app.models import SHORT_STR_LEN
|
||||
from app.models import CODE_STR_LEN
|
||||
|
||||
|
||||
class Scolog(db.Model):
|
||||
"""Log des actions (journal modif etudiants)"""
|
||||
|
||||
__tablename__ = "scolog"
|
||||
|
||||
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) # sans contrainte pour garder logs après suppression
|
||||
authenticated_user = db.Column(db.Text) # login, sans contrainte
|
||||
# zope_remote_addr suppressed
|
||||
|
||||
|
||||
class ScolarNews(db.Model):
|
||||
"""Nouvelles pour page d'accueil"""
|
||||
|
||||
__tablename__ = "scolar_news"
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
date = db.Column(db.DateTime(timezone=True), server_default=db.func.now())
|
||||
authenticated_user = db.Column(db.Text) # login, sans contrainte
|
||||
# type in 'INSCR', 'NOTES', 'FORM', 'SEM', 'MISC'
|
||||
type = db.Column(db.String(SHORT_STR_LEN))
|
||||
object = db.Column(db.Integer) # moduleimpl_id, formation_id, formsemestre_id
|
||||
text = db.Column(db.Text)
|
||||
url = db.Column(db.Text)
|
117
app/models/formations.py
Normal file
117
app/models/formations.py
Normal file
@ -0,0 +1,117 @@
|
||||
"""ScoDoc8 models : Formations (hors BUT)
|
||||
"""
|
||||
from typing import Any
|
||||
|
||||
from app import db
|
||||
from app.models import APO_CODE_STR_LEN
|
||||
from app.models import SHORT_STR_LEN
|
||||
|
||||
|
||||
class NotesFormation(db.Model):
|
||||
"""Programme pédagogique d'une formation"""
|
||||
|
||||
__tablename__ = "notes_formations"
|
||||
__table_args__ = (db.UniqueConstraint("acronyme", "titre", "version"),)
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
formation_id = db.synonym("id")
|
||||
acronyme = db.Column(db.String(SHORT_STR_LEN), nullable=False)
|
||||
titre = db.Column(db.Text(), nullable=False)
|
||||
version = db.Column(db.Integer, default=1)
|
||||
formation_code = db.Column(db.String(SHORT_STR_LEN), nullable=False)
|
||||
type_parcours = db.Column(db.Integer, default=0)
|
||||
code_specialite = db.Column(db.String(SHORT_STR_LEN))
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(NotesFormation, self).__init__(**kwargs)
|
||||
if self.formation_code is None:
|
||||
# génère formation_code à la création
|
||||
self.formation_code = f"FCOD{self.id:03d}"
|
||||
|
||||
|
||||
class NotesUE(db.Model):
|
||||
"""Unité d'Enseignement"""
|
||||
|
||||
__tablename__ = "notes_ue"
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
ue_id = db.synonym("id")
|
||||
formation_id = db.Column(db.Integer, db.ForeignKey("notes_formations.id"))
|
||||
acronyme = db.Column(db.String(SHORT_STR_LEN), nullable=False)
|
||||
numero = db.Column(db.Integer) # ordre de présentation
|
||||
titre = db.Column(db.Text())
|
||||
# Type d'UE: 0 normal ("fondamentale"), 1 "sport", 2 "projet et stage (LP)",
|
||||
# 4 "élective"
|
||||
type = db.Column(db.Integer, default=0)
|
||||
ue_code = db.Column(db.String(SHORT_STR_LEN), nullable=False)
|
||||
ects = db.Column(db.Float) # nombre de credits ECTS
|
||||
is_external = db.Column(db.Boolean(), nullable=False, default=False)
|
||||
# id de l'element pedagogique Apogee correspondant:
|
||||
code_apogee = db.Column(db.String(APO_CODE_STR_LEN))
|
||||
# coef UE, utilise seulement si l'option use_ue_coefs est activée:
|
||||
coefficient = db.Column(db.Float)
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(NotesUE, self).__init__(**kwargs)
|
||||
if self.ue_code is None:
|
||||
# génère code à la création
|
||||
self.ue_code = f"UCOD{self.ue_id:03d}"
|
||||
|
||||
|
||||
class NotesMatiere(db.Model):
|
||||
"""Matières: regroupe les modules d'une UE
|
||||
La matière a peu d'utilité en dehors de la présentation des modules
|
||||
d'une UE.
|
||||
"""
|
||||
|
||||
__tablename__ = "notes_matieres"
|
||||
__table_args__ = (db.UniqueConstraint("ue_id", "titre"),)
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
matiere_id = db.synonym("id")
|
||||
ue_id = db.Column(db.Integer, db.ForeignKey("notes_ue.id"))
|
||||
titre = db.Column(db.Text())
|
||||
numero = db.Column(db.Integer) # ordre de présentation
|
||||
|
||||
|
||||
class NotesModule(db.Model):
|
||||
"""Module"""
|
||||
|
||||
__tablename__ = "notes_modules"
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
module_id = db.synonym("id")
|
||||
titre = db.Column(db.Text())
|
||||
abbrev = db.Column(db.Text()) # nom court
|
||||
code = db.Column(db.String(SHORT_STR_LEN), nullable=False)
|
||||
heures_cours = db.Column(db.Float)
|
||||
heures_td = db.Column(db.Float)
|
||||
heures_tp = db.Column(db.Float)
|
||||
coefficient = db.Column(db.Float) # coef PPN
|
||||
ue_id = db.Column(db.Integer, db.ForeignKey("notes_ue.id"))
|
||||
formation_id = db.Column(db.Integer, db.ForeignKey("notes_formations.id"))
|
||||
matiere_id = db.Column(db.Integer, db.ForeignKey("notes_matieres.id"))
|
||||
# pas un id mais le numéro du semestre: 1, 2, ...
|
||||
semestre_id = db.Column(db.Integer, nullable=False, default=1)
|
||||
numero = db.Column(db.Integer) # ordre de présentation
|
||||
# id de l'element pedagogique Apogee correspondant:
|
||||
code_apogee = db.Column(db.String(APO_CODE_STR_LEN))
|
||||
module_type = db.Column(db.Integer) # NULL ou 0:defaut, 1: malus (NOTES_MALUS)
|
||||
|
||||
|
||||
class NotesTag(db.Model):
|
||||
"""Tag sur un module"""
|
||||
|
||||
__tablename__ = "notes_tags"
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
tag_id = db.synonym("id")
|
||||
title = db.Column(db.String(SHORT_STR_LEN), nullable=False, unique=True)
|
||||
|
||||
|
||||
# Association tag <-> module
|
||||
notes_modules_tags = db.Table(
|
||||
"notes_modules_tags",
|
||||
db.Column("tag_id", db.Integer, db.ForeignKey("notes_tags.id")),
|
||||
db.Column("module_id", db.Integer, db.ForeignKey("notes_modules.id")),
|
||||
)
|
284
app/models/formsemestre.py
Normal file
284
app/models/formsemestre.py
Normal file
@ -0,0 +1,284 @@
|
||||
# -*- coding: UTF-8 -*
|
||||
|
||||
"""ScoDoc8 models
|
||||
"""
|
||||
from typing import Any
|
||||
|
||||
from app import db
|
||||
from app.models import APO_CODE_STR_LEN
|
||||
from app.models import SHORT_STR_LEN
|
||||
from app.models import CODE_STR_LEN
|
||||
|
||||
|
||||
class FormSemestre(db.Model):
|
||||
"""Mise en oeuvre d'un semestre de formation
|
||||
was notes_formsemestre
|
||||
"""
|
||||
|
||||
__tablename__ = "notes_formsemestre"
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
formsemestre_id = db.synonym("id")
|
||||
formation_id = db.Column(db.Integer, db.ForeignKey("notes_formations.id"))
|
||||
semestre_id = db.Column(db.Integer, nullable=False, default=1)
|
||||
titre = db.Column(db.Text())
|
||||
date_debut = db.Column(db.Date())
|
||||
date_fin = db.Column(db.Date())
|
||||
etat = db.Column(db.Boolean(), nullable=False, default=True) # False si verrouillé
|
||||
modalite = db.Column(db.String(16), db.ForeignKey("form_modalite.modalite"))
|
||||
# gestion compensation sem DUT:
|
||||
gestion_compensation = db.Column(db.Boolean(), nullable=False, default=False)
|
||||
# ne publie pas le bulletin XML:
|
||||
bul_hide_xml = db.Column(db.Boolean(), nullable=False, default=False)
|
||||
# semestres decales (pour gestion jurys):
|
||||
gestion_semestrielle = db.Column(db.Boolean(), nullable=False, default=False)
|
||||
# couleur fond bulletins HTML:
|
||||
bul_bgcolor = db.Column(db.String(SHORT_STR_LEN), default="white")
|
||||
# autorise resp. a modifier semestre:
|
||||
resp_can_edit = db.Column(db.Boolean(), nullable=False, default=False)
|
||||
# autorise resp. a modifier slt les enseignants:
|
||||
resp_can_change_ens = db.Column(db.Boolean(), nullable=False, default=True)
|
||||
# autorise les ens a creer des evals:
|
||||
ens_can_edit_eval = db.Column(db.Boolean(), nullable=False, default=False)
|
||||
# code element semestre Apogee, eg VRTW1 ou V2INCS4,V2INLS4
|
||||
elt_sem_apo = db.Column(db.String(APO_CODE_STR_LEN))
|
||||
# code element annee Apogee, eg VRT1A ou V2INLA,V2INCA
|
||||
elt_annee_apo = db.Column(db.String(APO_CODE_STR_LEN))
|
||||
|
||||
etapes = db.relationship(
|
||||
"NotesFormsemestreEtape", cascade="all,delete", backref="notes_formsemestre"
|
||||
)
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(FormSemestre, self).__init__(**kwargs)
|
||||
if self.modalite is None:
|
||||
self.modalite = FormModalite.DEFAULT_MODALITE
|
||||
|
||||
|
||||
# Association id des utilisateurs responsables (aka directeurs des etudes) du semestre
|
||||
notes_formsemestre_responsables = db.Table(
|
||||
"notes_formsemestre_responsables",
|
||||
db.Column(
|
||||
"formsemestre_id",
|
||||
db.Integer,
|
||||
db.ForeignKey("notes_formsemestre.id"),
|
||||
),
|
||||
db.Column("responsable_id", db.Integer, db.ForeignKey("user.id")),
|
||||
)
|
||||
|
||||
|
||||
class NotesFormsemestreEtape(db.Model):
|
||||
"""Étape Apogée associées au semestre"""
|
||||
|
||||
__tablename__ = "notes_formsemestre_etapes"
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
formsemestre_id = db.Column(
|
||||
db.Integer,
|
||||
db.ForeignKey("notes_formsemestre.id"),
|
||||
)
|
||||
etape_apo = db.Column(db.String(APO_CODE_STR_LEN))
|
||||
|
||||
|
||||
class FormModalite(db.Model):
|
||||
"""Modalités de formation, utilisées pour la présentation
|
||||
(grouper les semestres, générer des codes, etc.)
|
||||
"""
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
modalite = db.Column(db.String(16), unique=True, index=True) # code
|
||||
titre = db.Column(db.Text()) # texte explicatif
|
||||
# numero = ordre de presentation)
|
||||
numero = db.Column(db.Integer)
|
||||
|
||||
DEFAULT_MODALITE = "FI"
|
||||
|
||||
@staticmethod
|
||||
def insert_modalites():
|
||||
"""Create default modalities"""
|
||||
numero = 0
|
||||
for (code, titre) in (
|
||||
(FormModalite.DEFAULT_MODALITE, "Formation Initiale"),
|
||||
("FAP", "Apprentissage"),
|
||||
("FC", "Formation Continue"),
|
||||
("DEC", "Formation Décalées"),
|
||||
("LIC", "Licence"),
|
||||
("CPRO", "Contrats de Professionnalisation"),
|
||||
("DIST", "À distance"),
|
||||
("ETR", "À l'étranger"),
|
||||
("EXT", "Extérieur"),
|
||||
("OTHER", "Autres formations"),
|
||||
):
|
||||
modalite = FormModalite.query.filter_by(modalite=code).first()
|
||||
if modalite is None:
|
||||
modalite = FormModalite(modalite=code, titre=titre, numero=numero)
|
||||
db.session.add(modalite)
|
||||
numero += 1
|
||||
db.session.commit()
|
||||
|
||||
|
||||
class NotesFormsemestreUECoef(db.Model):
|
||||
"""Coef des UE capitalisees arrivant dans ce semestre"""
|
||||
|
||||
__tablename__ = "notes_formsemestre_uecoef"
|
||||
__table_args__ = (db.UniqueConstraint("formsemestre_id", "ue_id"),)
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
formsemestre_uecoef_id = db.synonym("id")
|
||||
formsemestre_id = db.Column(
|
||||
db.Integer,
|
||||
db.ForeignKey("notes_formsemestre.id"),
|
||||
)
|
||||
ue_id = db.Column(
|
||||
db.Integer,
|
||||
db.ForeignKey("notes_ue.id"),
|
||||
)
|
||||
coefficient = db.Column(db.Float, nullable=False)
|
||||
|
||||
|
||||
class NotesFormsemestreUEComputationExpr(db.Model):
|
||||
"""Formules utilisateurs pour calcul moyenne UE"""
|
||||
|
||||
__tablename__ = "notes_formsemestre_ue_computation_expr"
|
||||
__table_args__ = (db.UniqueConstraint("formsemestre_id", "ue_id"),)
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
notes_formsemestre_ue_computation_expr_id = db.synonym("id")
|
||||
formsemestre_id = db.Column(
|
||||
db.Integer,
|
||||
db.ForeignKey("notes_formsemestre.id"),
|
||||
)
|
||||
ue_id = db.Column(
|
||||
db.Integer,
|
||||
db.ForeignKey("notes_ue.id"),
|
||||
)
|
||||
# formule de calcul moyenne
|
||||
computation_expr = db.Column(db.Text())
|
||||
|
||||
|
||||
class NotesFormsemestreCustomMenu(db.Model):
|
||||
"""Menu custom associe au semestre"""
|
||||
|
||||
__tablename__ = "notes_formsemestre_custommenu"
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
custommenu_id = db.synonym("id")
|
||||
formsemestre_id = db.Column(
|
||||
db.Integer,
|
||||
db.ForeignKey("notes_formsemestre.id"),
|
||||
)
|
||||
title = db.Column(db.Text())
|
||||
url = db.Column(db.Text())
|
||||
idx = db.Column(db.Integer, default=0) # rang dans le menu
|
||||
|
||||
|
||||
class NotesFormsemestreInscription(db.Model):
|
||||
"""Inscription à un semestre de formation"""
|
||||
|
||||
__tablename__ = "notes_formsemestre_inscription"
|
||||
__table_args__ = (db.UniqueConstraint("formsemestre_id", "etudid"),)
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
formsemestre_inscription_id = db.synonym("id")
|
||||
|
||||
etudid = db.Column(db.Integer, db.ForeignKey("identite.id"))
|
||||
formsemestre_id = db.Column(
|
||||
db.Integer,
|
||||
db.ForeignKey("notes_formsemestre.id"),
|
||||
)
|
||||
# I inscrit, D demission en cours de semestre, DEF si "defaillant"
|
||||
etat = db.Column(db.String(CODE_STR_LEN))
|
||||
# etape apogee d'inscription (experimental 2020)
|
||||
etape = db.Column(db.String(APO_CODE_STR_LEN))
|
||||
|
||||
|
||||
class NotesModuleImpl(db.Model):
|
||||
"""Mise en oeuvre d'un module pour une annee/semestre"""
|
||||
|
||||
__tablename__ = "notes_moduleimpl"
|
||||
__table_args__ = (db.UniqueConstraint("formsemestre_id", "module_id"),)
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
moduleimpl_id = db.synonym("id")
|
||||
module_id = db.Column(
|
||||
db.Integer,
|
||||
db.ForeignKey("notes_modules.id"),
|
||||
)
|
||||
formsemestre_id = db.Column(
|
||||
db.Integer,
|
||||
db.ForeignKey("notes_formsemestre.id"),
|
||||
)
|
||||
responsable_id = db.Column("responsable_id", db.Integer, db.ForeignKey("user.id"))
|
||||
# formule de calcul moyenne:
|
||||
computation_expr = db.Column(db.Text())
|
||||
|
||||
|
||||
# Enseignants (chargés de TD ou TP) d'un moduleimpl
|
||||
notes_modules_enseignants = db.Table(
|
||||
"notes_modules_enseignants",
|
||||
db.Column(
|
||||
"moduleimpl_id",
|
||||
db.Integer,
|
||||
db.ForeignKey("notes_moduleimpl.id"),
|
||||
),
|
||||
db.Column("ens_id", db.Integer, db.ForeignKey("user.id")),
|
||||
)
|
||||
# XXX il manque probablement une relation pour gérer cela
|
||||
|
||||
|
||||
class NotesModuleImplInscription(db.Model):
|
||||
"""Inscription à un module (etudiants,moduleimpl)"""
|
||||
|
||||
__tablename__ = "notes_moduleimpl_inscription"
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
moduleimpl_inscription_id = db.synonym("id")
|
||||
db.Column(
|
||||
"moduleimpl_id",
|
||||
db.Integer,
|
||||
db.ForeignKey("notes_moduleimpl.moduleimpl_id"),
|
||||
)
|
||||
etudid = db.Column(db.Integer, db.ForeignKey("identite.id"))
|
||||
|
||||
|
||||
class NotesEvaluation(db.Model):
|
||||
"""Evaluation (contrôle, examen, ...)"""
|
||||
|
||||
__tablename__ = "notes_evaluation"
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
evaluation_id = db.synonym("id")
|
||||
jour = db.Column(db.Date)
|
||||
heure_debut = db.Column(db.Time)
|
||||
heure_fin = db.Column(db.Time)
|
||||
description = db.Column(db.Text)
|
||||
note_max = db.Column(db.Float)
|
||||
coefficient = db.Column(db.Float)
|
||||
visibulletin = db.Column(db.Boolean, nullable=False, default=True)
|
||||
publish_incomplete = db.Column(db.Boolean, nullable=False, default=False)
|
||||
# type d'evaluation: False normale, True rattrapage:
|
||||
evaluation_type = db.Column(db.Boolean, nullable=False, default=False)
|
||||
# ordre de presentation (par défaut, le plus petit numero
|
||||
# est la plus ancienne eval):
|
||||
numero = db.Column(db.Integer)
|
||||
|
||||
|
||||
class NotesSemSet(db.Model):
|
||||
"""semsets: ensemble de formsemestres pour exports Apogée"""
|
||||
|
||||
__tablename__ = "notes_semset"
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
semset_id = db.synonym("id")
|
||||
title = db.Column(db.Text)
|
||||
annee_scolaire = db.Column(db.Integer, nullable=True, default=None)
|
||||
# periode: 0 (année), 1 (Simpair), 2 (Spair)
|
||||
sem_id = db.Column(db.Integer, nullable=True, default=None)
|
||||
|
||||
|
||||
# Association:
|
||||
notes_semset_formsemestre = db.Table(
|
||||
"notes_semset_formsemestre",
|
||||
db.Column("formsemestre_id", db.Integer, db.ForeignKey("notes_formsemestre.id")),
|
||||
db.Column("semset_id", db.Integer, db.ForeignKey("notes_semset.id")),
|
||||
db.UniqueConstraint("formsemestre_id", "semset_id"),
|
||||
)
|
60
app/models/groups.py
Normal file
60
app/models/groups.py
Normal file
@ -0,0 +1,60 @@
|
||||
# -*- coding: UTF-8 -*
|
||||
|
||||
"""Groups & partitions
|
||||
"""
|
||||
from typing import Any
|
||||
|
||||
from app import db
|
||||
from app.models import APO_CODE_STR_LEN
|
||||
from app.models import SHORT_STR_LEN
|
||||
from app.models import CODE_STR_LEN
|
||||
|
||||
|
||||
class Partition(db.Model):
|
||||
"""Partition: découpage d'une promotion en groupes"""
|
||||
|
||||
__table_args__ = (db.UniqueConstraint("formsemestre_id", "partition_name"),)
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
partition_id = db.synonym("id")
|
||||
formsemestre_id = db.Column(
|
||||
db.Integer,
|
||||
db.ForeignKey("notes_formsemestre.id"),
|
||||
)
|
||||
# "TD", "TP", ... (NULL for 'all')
|
||||
partition_name = db.Column(db.String(SHORT_STR_LEN))
|
||||
# numero = ordre de presentation)
|
||||
numero = db.Column(db.Integer)
|
||||
bul_show_rank = db.Column(db.Boolean(), nullable=False, default=False)
|
||||
show_in_lists = db.Column(db.Boolean(), nullable=False, default=True)
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(Partition, self).__init__(**kwargs)
|
||||
if self.numero is None:
|
||||
# génère numero à la création
|
||||
last_partition = Partition.query.order_by(Partition.numero.desc()).first()
|
||||
if last_partition:
|
||||
self.numero = last_partition.numero + 1
|
||||
else:
|
||||
self.numero = 1
|
||||
|
||||
|
||||
class GroupDescr(db.Model):
|
||||
"""Description d'un groupe d'une partition"""
|
||||
|
||||
__tablename__ = "group_descr"
|
||||
__table_args__ = (db.UniqueConstraint("partition_id", "group_name"),)
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
group_id = db.synonym("id")
|
||||
partition_id = db.Column(db.Integer, db.ForeignKey("partition.id"))
|
||||
# "A", "C2", ... (NULL for 'all'):
|
||||
group_name = db.Column(db.String(SHORT_STR_LEN))
|
||||
|
||||
|
||||
group_membership = db.Table(
|
||||
"group_membership",
|
||||
db.Column("etudid", db.Integer, db.ForeignKey("identite.id")),
|
||||
db.Column("group_id", db.Integer, db.ForeignKey("group_descr.id")),
|
||||
db.UniqueConstraint("etudid", "group_id"),
|
||||
)
|
160
app/models/notes.py
Normal file
160
app/models/notes.py
Normal file
@ -0,0 +1,160 @@
|
||||
# -*- coding: UTF-8 -*
|
||||
|
||||
"""Notes, décisions de jury, évènements scolaires
|
||||
"""
|
||||
|
||||
from app import db
|
||||
from app.models import APO_CODE_STR_LEN
|
||||
from app.models import SHORT_STR_LEN
|
||||
from app.models import CODE_STR_LEN
|
||||
|
||||
|
||||
class ScolarEvent(db.Model):
|
||||
"""Evenement dans le parcours scolaire d'un étudiant"""
|
||||
|
||||
__tablename__ = "scolar_events"
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
event_id = db.synonym("id")
|
||||
etudid = db.Column(
|
||||
db.Integer,
|
||||
db.ForeignKey("identite.id"),
|
||||
)
|
||||
event_date = db.Column(db.DateTime(timezone=True), server_default=db.func.now())
|
||||
formsemestre_id = db.Column(
|
||||
db.Integer,
|
||||
db.ForeignKey("notes_formsemestre.id"),
|
||||
)
|
||||
ue_id = db.Column(
|
||||
db.Integer,
|
||||
db.ForeignKey("notes_ue.id"),
|
||||
)
|
||||
# 'CREATION', 'INSCRIPTION', 'DEMISSION',
|
||||
# 'AUT_RED', 'EXCLUS', 'VALID_UE', 'VALID_SEM'
|
||||
# 'ECHEC_SEM'
|
||||
# 'UTIL_COMPENSATION'
|
||||
event_type = db.Column(db.String(SHORT_STR_LEN))
|
||||
# Semestre compensé par formsemestre_id:
|
||||
comp_formsemestre_id = db.Column(
|
||||
db.Integer,
|
||||
db.ForeignKey("notes_formsemestre.id"),
|
||||
)
|
||||
|
||||
|
||||
class ScolarFormsemestreValidation(db.Model):
|
||||
"""Décisions de jury"""
|
||||
|
||||
__tablename__ = "scolar_formsemestre_validation"
|
||||
# Assure unicité de la décision:
|
||||
__table_args__ = (db.UniqueConstraint("etudid", "formsemestre_id", "ue_id"),)
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
formsemestre_validation_id = db.synonym("id")
|
||||
etudid = db.Column(
|
||||
db.Integer,
|
||||
db.ForeignKey("identite.id"),
|
||||
)
|
||||
formsemestre_id = db.Column(
|
||||
db.Integer,
|
||||
db.ForeignKey("notes_formsemestre.id"),
|
||||
)
|
||||
ue_id = db.Column(
|
||||
db.Integer,
|
||||
db.ForeignKey("notes_ue.id"),
|
||||
)
|
||||
code = db.Column(db.String(CODE_STR_LEN), nullable=False)
|
||||
# NULL pour les UE, True|False pour les semestres:
|
||||
assidu = db.Column(db.Boolean)
|
||||
event_date = db.Column(db.DateTime(timezone=True), server_default=db.func.now())
|
||||
# NULL sauf si compense un semestre:
|
||||
compense_formsemestre_id = db.Column(
|
||||
db.Integer,
|
||||
db.ForeignKey("notes_formsemestre.id"),
|
||||
)
|
||||
moy_ue = db.Column(db.Float)
|
||||
# (normalement NULL) indice du semestre, utile seulement pour
|
||||
# UE "antérieures" et si la formation définit des UE utilisées
|
||||
# dans plusieurs semestres (cas R&T IUTV v2)
|
||||
semestre_id = db.Column(db.Integer)
|
||||
# Si UE validée dans le cursus d'un autre etablissement
|
||||
is_external = db.Column(db.Boolean, default=False)
|
||||
|
||||
|
||||
class ScolarAutorisationInscription(db.Model):
|
||||
"""Autorisation d'inscription dans un semestre"""
|
||||
|
||||
__tablename__ = "scolar_autorisation_inscription"
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
autorisation_inscription_id = db.synonym("id")
|
||||
|
||||
etudid = db.Column(
|
||||
db.Integer,
|
||||
db.ForeignKey("identite.id"),
|
||||
)
|
||||
formation_code = db.Column(db.String(CODE_STR_LEN), nullable=False)
|
||||
# semestre ou on peut s'inscrire:
|
||||
semestre_id = db.Column(db.Integer)
|
||||
date = db.Column(db.DateTime(timezone=True), server_default=db.func.now())
|
||||
origin_formsemestre_id = db.Column(
|
||||
db.Integer,
|
||||
db.ForeignKey("notes_formsemestre.id"),
|
||||
)
|
||||
|
||||
|
||||
class NotesAppreciations(db.Model):
|
||||
"""Appréciations sur bulletins"""
|
||||
|
||||
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"),
|
||||
index=True,
|
||||
)
|
||||
formsemestre_id = db.Column(
|
||||
db.Integer,
|
||||
db.ForeignKey("notes_formsemestre.id"),
|
||||
)
|
||||
author = db.Column(db.Text) # login, sans contrainte
|
||||
comment = db.Column(db.Text) # texte libre
|
||||
|
||||
|
||||
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"),
|
||||
)
|
||||
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"))
|
||||
|
||||
|
||||
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"),
|
||||
)
|
||||
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"))
|
18
app/models/preferences.py
Normal file
18
app/models/preferences.py
Normal file
@ -0,0 +1,18 @@
|
||||
# -*- coding: UTF-8 -*
|
||||
|
||||
"""Model : preferences
|
||||
"""
|
||||
|
||||
from app import db
|
||||
|
||||
|
||||
class ScoPreferences(db.Model):
|
||||
"""ScoDoc preferences"""
|
||||
|
||||
__tablename__ = "sco_prefs"
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
pref_id = db.synonym("id")
|
||||
dept = db.Column(db.String(16), index=True)
|
||||
name = db.Column(db.String(128), nullable=False)
|
||||
value = db.Column(db.Text())
|
||||
formsemestre_id = db.Column(db.Integer, db.ForeignKey("notes_formsemestre.id"))
|
@ -102,7 +102,7 @@ def do_modalite_delete(context, oid, REQUEST=None):
|
||||
_modaliteEditor.delete(cnx, oid)
|
||||
|
||||
|
||||
def do_modalite_edit(context, *args, **kw):
|
||||
def do_modalite_edit(context, *args, **kw): # unused
|
||||
"edit a modalite"
|
||||
cnx = ndb.GetDBConnexion()
|
||||
# check
|
||||
|
@ -202,34 +202,34 @@ CREATE TABLE etud_annotations (
|
||||
) WITH OIDS;
|
||||
|
||||
-- ------------ Nouvelle gestion des absences ------------
|
||||
CREATE SEQUENCE abs_idgen;
|
||||
CREATE FUNCTION abs_newid( text ) returns text as '
|
||||
select $1 || to_char( nextval(''abs_idgen''), ''FM999999999'' )
|
||||
as result;
|
||||
' language SQL;
|
||||
-- CREATE SEQUENCE abs_idgen;
|
||||
-- CREATE FUNCTION abs_newid( text ) returns text as '
|
||||
-- select $1 || to_char( nextval(''abs_idgen''), ''FM999999999'' )
|
||||
-- as result;
|
||||
-- ' language SQL;
|
||||
|
||||
CREATE TABLE abs_absences (
|
||||
absid text default abs_newid('AB') PRIMARY KEY,
|
||||
etudid character(32),
|
||||
abs_begin timestamp with time zone,
|
||||
abs_end timestamp with time zone
|
||||
) WITH OIDS;
|
||||
-- CREATE TABLE abs_absences (
|
||||
-- absid text default abs_newid('AB') PRIMARY KEY,
|
||||
-- etudid character(32),
|
||||
-- abs_begin timestamp with time zone,
|
||||
-- abs_end timestamp with time zone
|
||||
-- ) WITH OIDS;
|
||||
|
||||
CREATE TABLE abs_presences (
|
||||
absid text default abs_newid('PR') PRIMARY KEY,
|
||||
etudid character(32),
|
||||
abs_begin timestamp with time zone,
|
||||
abs_end timestamp with time zone
|
||||
) WITH OIDS;
|
||||
-- CREATE TABLE abs_presences (
|
||||
-- absid text default abs_newid('PR') PRIMARY KEY,
|
||||
-- etudid character(32),
|
||||
-- abs_begin timestamp with time zone,
|
||||
-- abs_end timestamp with time zone
|
||||
-- ) WITH OIDS;
|
||||
|
||||
CREATE TABLE abs_justifs (
|
||||
absid text default abs_newid('JU') PRIMARY KEY,
|
||||
etudid character(32),
|
||||
abs_begin timestamp with time zone,
|
||||
abs_end timestamp with time zone,
|
||||
category text,
|
||||
description text
|
||||
) WITH OIDS;
|
||||
-- CREATE TABLE abs_justifs (
|
||||
-- absid text default abs_newid('JU') PRIMARY KEY,
|
||||
-- etudid character(32),
|
||||
-- abs_begin timestamp with time zone,
|
||||
-- abs_end timestamp with time zone,
|
||||
-- category text,
|
||||
-- description text
|
||||
-- ) WITH OIDS;
|
||||
|
||||
|
||||
|
||||
@ -600,12 +600,12 @@ CREATE TABLE scolar_events (
|
||||
etudid text,
|
||||
event_date timestamp default now(),
|
||||
formsemestre_id text REFERENCES notes_formsemestre(formsemestre_id),
|
||||
ue_id text REFERENCES notes_ue(ue_id),
|
||||
ue_id text REFERENCES notes_ue(ue_id),
|
||||
event_type text, -- 'CREATION', 'INSCRIPTION', 'DEMISSION',
|
||||
-- 'AUT_RED', 'EXCLUS', 'VALID_UE', 'VALID_SEM'
|
||||
-- 'ECHEC_SEM'
|
||||
-- 'UTIL_COMPENSATION'
|
||||
comp_formsemestre_id text REFERENCES notes_formsemestre(formsemestre_id)
|
||||
comp_formsemestre_id text REFERENCES notes_formsemestre(formsemestre_id)
|
||||
-- semestre compense par formsemestre_id
|
||||
) WITH OIDS;
|
||||
|
||||
|
23
scodoc.py
23
scodoc.py
@ -19,6 +19,9 @@ from flask.cli import with_appcontext
|
||||
from app import create_app, cli, db
|
||||
|
||||
from app.auth.models import User, Role, UserRole
|
||||
|
||||
from app import models
|
||||
from app.models import ScoPreferences, FormSemestre, FormModalite
|
||||
from app.views import notes, scolar, absences
|
||||
import app.utils as utils
|
||||
|
||||
@ -35,11 +38,17 @@ def make_shell_context():
|
||||
from flask_login import login_user, logout_user, current_user
|
||||
|
||||
admin_role = Role.query.filter_by(name="SuperAdmin").first()
|
||||
admin = (
|
||||
User.query.join(UserRole)
|
||||
.filter((UserRole.user_id == User.id) & (UserRole.role_id == admin_role.id))
|
||||
.first()
|
||||
)
|
||||
if admin_role:
|
||||
admin = (
|
||||
User.query.join(UserRole)
|
||||
.filter((UserRole.user_id == User.id) & (UserRole.role_id == admin_role.id))
|
||||
.first()
|
||||
)
|
||||
else:
|
||||
click.echo(
|
||||
"Warning: user database not initialized !\n (use: flask user-db-init)"
|
||||
)
|
||||
admin = None
|
||||
|
||||
return {
|
||||
"db": db,
|
||||
@ -58,6 +67,10 @@ def make_shell_context():
|
||||
"logout_user": logout_user,
|
||||
"admin": admin,
|
||||
"ctx": app.test_request_context(),
|
||||
# "FormModalite": FormModalite,
|
||||
# "ScoPreferences": ScoPreferences,
|
||||
# "FormSemestre": FormSemestre,
|
||||
"models": models,
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user