WIP: Affichage validation cursus BUT sur page etudiant.
This commit is contained in:
parent
0b9c9be222
commit
bdf90dfd69
@ -13,7 +13,7 @@ Classe raccordant avec ScoDoc 7:
|
||||
avec la même interface.
|
||||
|
||||
"""
|
||||
|
||||
import collections
|
||||
from typing import Union
|
||||
|
||||
from flask import g, url_for
|
||||
@ -47,12 +47,14 @@ from app.models.validations import ScolarFormSemestreValidation
|
||||
from app.scodoc import sco_codes_parcours as sco_codes
|
||||
from app.scodoc.sco_codes_parcours import RED, UE_STANDARD
|
||||
from app.scodoc import sco_utils as scu
|
||||
from app.scodoc.sco_exceptions import ScoException, ScoValueError
|
||||
from app.scodoc.sco_exceptions import ScoNoReferentielCompetences, ScoValueError
|
||||
|
||||
from app.scodoc import sco_cursus_dut
|
||||
|
||||
|
||||
class SituationEtudCursusBUT(sco_cursus_dut.SituationEtudCursusClassic):
|
||||
"""Pour compat ScoDoc 7: à revoir pour le BUT"""
|
||||
|
||||
def __init__(self, etud: dict, formsemestre_id: int, res: ResultatsSemestreBUT):
|
||||
super().__init__(etud, formsemestre_id, res)
|
||||
# Ajustements pour le BUT
|
||||
@ -65,3 +67,114 @@ class SituationEtudCursusBUT(sco_cursus_dut.SituationEtudCursusClassic):
|
||||
def parcours_validated(self):
|
||||
"True si le parcours est validé"
|
||||
return False # XXX TODO
|
||||
|
||||
|
||||
class EtudCursusBUT:
|
||||
"""L'état de l'étudiant dans son cursus BUT
|
||||
Liste des niveaux validés/à valider
|
||||
"""
|
||||
|
||||
def __init__(self, etud: Identite, formation: Formation):
|
||||
"""formation indique la spécialité préparée"""
|
||||
# Vérifie que l'étudiant est bien inscrit à un sem. de cette formation
|
||||
if formation.id not in (
|
||||
ins.formsemestre.formation.id for ins in etud.formsemestre_inscriptions
|
||||
):
|
||||
raise ScoValueError(
|
||||
f"{etud.nomprenom} non inscrit dans {formation.titre} v{formation.version}"
|
||||
)
|
||||
if not formation.referentiel_competence:
|
||||
raise ScoNoReferentielCompetences(formation=formation)
|
||||
#
|
||||
self.etud = etud
|
||||
self.formation = formation
|
||||
self.inscriptions = sorted(
|
||||
[
|
||||
ins
|
||||
for ins in etud.formsemestre_inscriptions
|
||||
if ins.formsemestre.formation.referentiel_competence.id
|
||||
== formation.referentiel_competence.id
|
||||
],
|
||||
key=lambda s: (s.formsemestre.semestre_id, s.formsemestre.date_debut),
|
||||
)
|
||||
"Liste des inscriptions aux sem. de la formation, triées par indice et chronologie"
|
||||
self.parcour: ApcParcours = self.inscriptions[-1].parcour
|
||||
"Le parcour à valider: celui du DERNIER semestre suivi (peut être None)"
|
||||
self.niveaux_by_annee = {}
|
||||
"{ annee : liste des niveaux à valider }"
|
||||
self.niveaux: dict[int, ApcNiveau] = {}
|
||||
"cache les niveaux"
|
||||
for annee in (1, 2, 3):
|
||||
niveaux_d = formation.referentiel_competence.get_niveaux_by_parcours(
|
||||
annee, self.parcour
|
||||
)[1]
|
||||
# groupe les niveaux de tronc commun et ceux spécifiques au parcour
|
||||
self.niveaux_by_annee[annee] = niveaux_d["TC"] + (
|
||||
niveaux_d[self.parcour.id] if self.parcour else []
|
||||
)
|
||||
self.niveaux.update(
|
||||
{niveau.id: niveau for niveau in self.niveaux_by_annee[annee]}
|
||||
)
|
||||
# Probablement inutile:
|
||||
# # Cherche les validations de jury enregistrées pour chaque niveau
|
||||
# self.validations_by_niveau = collections.defaultdict(lambda: [])
|
||||
# " { niveau_id : [ ApcValidationRCUE ] }"
|
||||
# for validation_rcue in ApcValidationRCUE.query.filter_by(etud=etud):
|
||||
# self.validations_by_niveau[validation_rcue.niveau().id].append(
|
||||
# validation_rcue
|
||||
# )
|
||||
# self.validation_by_niveau = {
|
||||
# niveau_id: sorted(
|
||||
# validations, key=lambda v: sco_codes.BUT_CODES_ORDERED[v.code]
|
||||
# )[0]
|
||||
# for niveau_id, validations in self.validations_by_niveau.items()
|
||||
# }
|
||||
# "{ niveau_id : meilleure validation pour ce niveau }"
|
||||
|
||||
self.validation_par_competence_et_annee = {}
|
||||
"{ competence_id : { 'BUT1' : validation_rcue, ... } }"
|
||||
for validation_rcue in ApcValidationRCUE.query.filter_by(etud=etud):
|
||||
niveau = validation_rcue.niveau()
|
||||
if not niveau.competence.id in self.validation_par_competence_et_annee:
|
||||
self.validation_par_competence_et_annee[niveau.competence.id] = {}
|
||||
previous_validation = self.validation_par_competence_et_annee.get(
|
||||
niveau.competence.id
|
||||
)
|
||||
# prend la "meilleure" validation
|
||||
if (not previous_validation) or (
|
||||
sco_codes.BUT_CODES_ORDERED[validation_rcue.code]
|
||||
> sco_codes.BUT_CODES_ORDERED[previous_validation.code]
|
||||
):
|
||||
self.validation_par_competence_et_annee[niveau.competence.id][
|
||||
niveau.annee
|
||||
] = validation_rcue
|
||||
|
||||
self.competences = {
|
||||
competence.id: competence
|
||||
for competence in (
|
||||
self.parcour.query_competences()
|
||||
if self.parcour
|
||||
else self.formation.referentiel_competence.get_competences_tronc_commun()
|
||||
)
|
||||
}
|
||||
"cache { competence_id : competence }"
|
||||
|
||||
def to_dict(self):
|
||||
"""
|
||||
{
|
||||
competence_id : {
|
||||
annee : meilleure_validation
|
||||
}
|
||||
}
|
||||
"""
|
||||
return {
|
||||
competence.id: {
|
||||
annee: {
|
||||
self.validation_par_competence_et_annee.get(competence.id, {}).get(
|
||||
annee
|
||||
)
|
||||
}
|
||||
for annee in ("BUT1", "BUT2", "BUT3")
|
||||
}
|
||||
for competence in self.competences.values()
|
||||
}
|
||||
|
@ -94,9 +94,10 @@ class ApcReferentielCompetences(db.Model, XMLModel):
|
||||
return ""
|
||||
return self.version_orebut.split()[0]
|
||||
|
||||
def to_dict(self):
|
||||
def to_dict(self, parcours: list["ApcParcours"] = None, with_app_critiques=True):
|
||||
"""Représentation complète du ref. de comp.
|
||||
comme un dict.
|
||||
Si parcours est une liste de parcours, restreint l'export aux parcours listés.
|
||||
"""
|
||||
return {
|
||||
"dept_id": self.dept_id,
|
||||
@ -111,8 +112,14 @@ class ApcReferentielCompetences(db.Model, XMLModel):
|
||||
if self.scodoc_date_loaded
|
||||
else "",
|
||||
"scodoc_orig_filename": self.scodoc_orig_filename,
|
||||
"competences": {x.titre: x.to_dict() for x in self.competences},
|
||||
"parcours": {x.code: x.to_dict() for x in self.parcours},
|
||||
"competences": {
|
||||
x.titre: x.to_dict(with_app_critiques=with_app_critiques)
|
||||
for x in self.competences
|
||||
},
|
||||
"parcours": {
|
||||
x.code: x.to_dict()
|
||||
for x in (self.parcours if parcours is None else parcours)
|
||||
},
|
||||
}
|
||||
|
||||
def get_niveaux_by_parcours(
|
||||
@ -174,6 +181,27 @@ class ApcReferentielCompetences(db.Model, XMLModel):
|
||||
niveaux_by_parcours_no_tc["TC"] = niveaux_tc
|
||||
return parcours, niveaux_by_parcours_no_tc
|
||||
|
||||
def get_competences_tronc_commun(self) -> list["ApcCompetence"]:
|
||||
"""Liste des compétences communes à tous les parcours du référentiel."""
|
||||
parcours = self.parcours.all()
|
||||
if not parcours:
|
||||
return []
|
||||
|
||||
ids = set.intersection(
|
||||
*[
|
||||
{competence.id for competence in parcour.query_competences()}
|
||||
for parcour in parcours
|
||||
]
|
||||
)
|
||||
return sorted(
|
||||
[
|
||||
competence
|
||||
for competence in parcours[0].query_competences()
|
||||
if competence.id in ids
|
||||
],
|
||||
key=lambda c: c.numero or 0,
|
||||
)
|
||||
|
||||
|
||||
class ApcCompetence(db.Model, XMLModel):
|
||||
"Compétence"
|
||||
@ -215,7 +243,7 @@ class ApcCompetence(db.Model, XMLModel):
|
||||
def __repr__(self):
|
||||
return f"<ApcCompetence {self.id} {self.titre!r}>"
|
||||
|
||||
def to_dict(self):
|
||||
def to_dict(self, with_app_critiques=True):
|
||||
"repr dict recursive sur situations, composantes, niveaux"
|
||||
return {
|
||||
"id_orebut": self.id_orebut,
|
||||
@ -227,7 +255,10 @@ class ApcCompetence(db.Model, XMLModel):
|
||||
"composantes_essentielles": [
|
||||
x.to_dict() for x in self.composantes_essentielles
|
||||
],
|
||||
"niveaux": {x.annee: x.to_dict() for x in self.niveaux},
|
||||
"niveaux": {
|
||||
x.annee: x.to_dict(with_app_critiques=with_app_critiques)
|
||||
for x in self.niveaux
|
||||
},
|
||||
}
|
||||
|
||||
def to_dict_bul(self) -> dict:
|
||||
@ -293,13 +324,15 @@ class ApcNiveau(db.Model, XMLModel):
|
||||
return f"""<{self.__class__.__name__} {self.id} ordre={self.ordre!r} annee={
|
||||
self.annee!r} {self.competence!r}>"""
|
||||
|
||||
def to_dict(self):
|
||||
"as a dict, recursif sur les AC"
|
||||
def to_dict(self, with_app_critiques=True):
|
||||
"as a dict, recursif (ou non) sur les AC"
|
||||
return {
|
||||
"libelle": self.libelle,
|
||||
"annee": self.annee,
|
||||
"ordre": self.ordre,
|
||||
"app_critiques": {x.code: x.to_dict() for x in self.app_critiques},
|
||||
"app_critiques": {x.code: x.to_dict() for x in self.app_critiques}
|
||||
if with_app_critiques
|
||||
else {},
|
||||
}
|
||||
|
||||
def to_dict_bul(self):
|
||||
@ -471,6 +504,14 @@ class ApcParcours(db.Model, XMLModel):
|
||||
d["annees"] = {x.ordre: x.to_dict() for x in self.annees}
|
||||
return d
|
||||
|
||||
def query_competences(self) -> flask_sqlalchemy.BaseQuery:
|
||||
"Les compétences associées à ce parcours"
|
||||
return (
|
||||
ApcCompetence.query.join(ApcParcoursNiveauCompetence, ApcAnneeParcours)
|
||||
.filter_by(parcours_id=self.id)
|
||||
.order_by(ApcCompetence.numero)
|
||||
)
|
||||
|
||||
|
||||
class ApcAnneeParcours(db.Model, XMLModel):
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
|
@ -76,6 +76,12 @@ class ApcValidationRCUE(db.Model):
|
||||
# Par convention, il est donné par la seconde UE
|
||||
return self.ue2.niveau_competence
|
||||
|
||||
def to_dict(self):
|
||||
"as a dict"
|
||||
d = dict(self.__dict__)
|
||||
d.pop("_sa_instance_state", None)
|
||||
return d
|
||||
|
||||
def to_dict_bul(self) -> dict:
|
||||
"Export dict pour bulletins: le code et le niveau de compétence"
|
||||
niveau = self.niveau()
|
||||
|
@ -30,14 +30,15 @@
|
||||
Fiche description d'un étudiant et de son parcours
|
||||
|
||||
"""
|
||||
from flask import abort, url_for, g, request
|
||||
from flask import abort, url_for, g, render_template, request
|
||||
from flask_login import current_user
|
||||
|
||||
import app.scodoc.sco_utils as scu
|
||||
import app.scodoc.notesdb as ndb
|
||||
from app import log
|
||||
from app.but import jury_but_view
|
||||
from app.models.etudiants import make_etud_args
|
||||
from app.but import cursus_but, jury_but_view
|
||||
from app.models.etudiants import Identite, make_etud_args
|
||||
from app.models.formsemestre import FormSemestre
|
||||
from app.scodoc import html_sco_header
|
||||
from app.scodoc import htmlutils
|
||||
from app.scodoc import sco_archives_etud
|
||||
@ -169,11 +170,12 @@ def ficheEtud(etudid=None):
|
||||
if not etuds:
|
||||
log(f"ficheEtud: etudid={etudid!r} request.args={request.args!r}")
|
||||
raise ScoValueError("Étudiant inexistant !")
|
||||
etud = etuds[0]
|
||||
etudid = etud["etudid"]
|
||||
sco_etud.fill_etuds_info([etud])
|
||||
etud_ = etuds[0] # transition: etud_ à éliminer et remplacer par etud
|
||||
etudid = etud_["etudid"]
|
||||
etud = Identite.query.get(etudid)
|
||||
sco_etud.fill_etuds_info([etud_])
|
||||
#
|
||||
info = etud
|
||||
info = etud_
|
||||
info["ScoURL"] = scu.ScoURL()
|
||||
info["authuser"] = authuser
|
||||
info["info_naissance"] = info["date_naissance"]
|
||||
@ -181,7 +183,7 @@ def ficheEtud(etudid=None):
|
||||
info["info_naissance"] += " à " + info["lieu_naissance"]
|
||||
if info["dept_naissance"]:
|
||||
info["info_naissance"] += f" ({info['dept_naissance']})"
|
||||
info["etudfoto"] = sco_photos.etud_photo_html(etud)
|
||||
info["etudfoto"] = sco_photos.etud_photo_html(etud_)
|
||||
if (
|
||||
(not info["domicile"])
|
||||
and (not info["codepostaldomicile"])
|
||||
@ -206,7 +208,7 @@ def ficheEtud(etudid=None):
|
||||
info["emaillink"] = ", ".join(
|
||||
[
|
||||
'<a class="stdlink" href="mailto:%s">%s</a>' % (m, m)
|
||||
for m in [etud["email"], etud["emailperso"]]
|
||||
for m in [etud_["email"], etud_["emailperso"]]
|
||||
if m
|
||||
]
|
||||
)
|
||||
@ -277,7 +279,7 @@ def ficheEtud(etudid=None):
|
||||
sem_info[sem["formsemestre_id"]] = grlink
|
||||
|
||||
if info["sems"]:
|
||||
Se = sco_cursus.get_situation_etud_cursus(etud, info["last_formsemestre_id"])
|
||||
Se = sco_cursus.get_situation_etud_cursus(etud_, info["last_formsemestre_id"])
|
||||
info["liste_inscriptions"] = formsemestre_recap_parcours_table(
|
||||
Se,
|
||||
etudid,
|
||||
@ -454,6 +456,18 @@ def ficheEtud(etudid=None):
|
||||
# raccordement provisoire pour juillet 2022, avant refonte complète de cette fiche...
|
||||
info["but_infos_mkup"] = jury_but_view.infos_fiche_etud_html(etudid)
|
||||
|
||||
# XXX dev
|
||||
info["but_cursus_mkup"] = ""
|
||||
if info["sems"]:
|
||||
last_sem = FormSemestre.query.get_or_404(info["sems"][-1]["formsemestre_id"])
|
||||
if last_sem.formation.is_apc():
|
||||
but_cursus = cursus_but.EtudCursusBUT(etud, last_sem.formation)
|
||||
info["but_cursus_mkup"] = render_template(
|
||||
"but/cursus_etud.j2",
|
||||
cursus=but_cursus,
|
||||
scu=scu,
|
||||
)
|
||||
|
||||
tmpl = """<div class="menus_etud">%(menus_etud)s</div>
|
||||
<div class="ficheEtud" id="ficheEtud"><table>
|
||||
<tr><td>
|
||||
@ -488,6 +502,8 @@ def ficheEtud(etudid=None):
|
||||
|
||||
%(but_infos_mkup)s
|
||||
|
||||
%(but_cursus_mkup)s
|
||||
|
||||
<div class="ficheadmission">
|
||||
%(adm_data)s
|
||||
|
||||
@ -524,7 +540,11 @@ def ficheEtud(etudid=None):
|
||||
"""
|
||||
header = html_sco_header.sco_header(
|
||||
page_title="Fiche étudiant %(prenom)s %(nom)s" % info,
|
||||
cssstyles=["libjs/jQuery-tagEditor/jquery.tag-editor.css", "css/jury_but.css"],
|
||||
cssstyles=[
|
||||
"libjs/jQuery-tagEditor/jquery.tag-editor.css",
|
||||
"css/jury_but.css",
|
||||
"css/cursus_but.css",
|
||||
],
|
||||
javascripts=[
|
||||
"libjs/jinplace-1.2.1.min.js",
|
||||
"js/ue_list.js",
|
||||
|
42
app/static/css/cursus_but.css
Normal file
42
app/static/css/cursus_but.css
Normal file
@ -0,0 +1,42 @@
|
||||
/* Affichage cursus BUT étudiant (sur sa fiche) */
|
||||
|
||||
|
||||
.cursus_but {
|
||||
margin-left: 32px;
|
||||
display: inline-grid;
|
||||
grid-template-columns: repeat(4, auto);
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.cursus_but>* {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-top: 0px;
|
||||
padding-bottom: 0px;
|
||||
padding-left: 16px;
|
||||
padding-right: 0px;
|
||||
|
||||
background: #FFF;
|
||||
border: 1px solid #aaa;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.cursus_but>div.cb_head {
|
||||
background: rgb(242, 242, 238);
|
||||
border: none;
|
||||
border-radius: 0px;
|
||||
border-bottom: 1px solid gray;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
div.cb_titre_competence {
|
||||
background: #09c !important;
|
||||
color: #FFF;
|
||||
padding: 8px !important;
|
||||
}
|
||||
|
||||
div.code_rcue {
|
||||
padding-top: 8px;
|
||||
padding-bottom: 8px;
|
||||
position: relative;
|
||||
}
|
@ -1,24 +1,27 @@
|
||||
:host{
|
||||
:host {
|
||||
font-family: Verdana;
|
||||
background: #222;
|
||||
background: rgb(14, 5, 73);
|
||||
display: block;
|
||||
padding: 12px 32px;
|
||||
color: #FFF;
|
||||
max-width: 1000px;
|
||||
margin: auto;
|
||||
}
|
||||
h1{
|
||||
|
||||
h1 {
|
||||
font-weight: 100;
|
||||
}
|
||||
|
||||
/**********************/
|
||||
/* Zone parcours */
|
||||
/**********************/
|
||||
.parcours{
|
||||
.parcours {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
padding-right: 4px;
|
||||
}
|
||||
.parcours>div{
|
||||
|
||||
.parcours>div {
|
||||
background: #09c;
|
||||
font-size: 18px;
|
||||
text-align: center;
|
||||
@ -29,65 +32,89 @@ h1{
|
||||
transition: 0.1s;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.parcours>div:hover,
|
||||
.competence>div:hover{
|
||||
.competence>div:hover {
|
||||
color: #ccc;
|
||||
}
|
||||
.parcours>.focus{
|
||||
|
||||
.parcours>.focus {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/**********************/
|
||||
/* Zone compétences */
|
||||
/**********************/
|
||||
.competences{
|
||||
display: grid;
|
||||
.competences {
|
||||
display: grid;
|
||||
margin-top: 8px;
|
||||
row-gap: 4px;
|
||||
}
|
||||
.competences>div{
|
||||
|
||||
.competences>div {
|
||||
padding: 4px 8px;
|
||||
border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
width: var(--competence-size);
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.comp1{background:#a44}
|
||||
.comp2{background:#84a}
|
||||
.comp3{background:#a84}
|
||||
.comp4{background:#8a4}
|
||||
.comp5{background:#4a8}
|
||||
.comp6{background:#48a}
|
||||
.comp1 {
|
||||
background: #a44
|
||||
}
|
||||
|
||||
.competences>.focus{
|
||||
.comp2 {
|
||||
background: #84a
|
||||
}
|
||||
|
||||
.comp3 {
|
||||
background: #a84
|
||||
}
|
||||
|
||||
.comp4 {
|
||||
background: #8a4
|
||||
}
|
||||
|
||||
.comp5 {
|
||||
background: #4a8
|
||||
}
|
||||
|
||||
.comp6 {
|
||||
background: #48a
|
||||
}
|
||||
|
||||
.competences>.focus {
|
||||
outline: 2px solid;
|
||||
}
|
||||
|
||||
/**********************/
|
||||
/* Zone AC */
|
||||
/**********************/
|
||||
h2{
|
||||
h2 {
|
||||
display: table;
|
||||
padding: 8px 16px;
|
||||
font-size: 20px;
|
||||
border-radius: 16px 0;
|
||||
}
|
||||
.ACs{
|
||||
|
||||
.ACs {
|
||||
padding-right: 4px;
|
||||
}
|
||||
.AC li{
|
||||
|
||||
.AC li {
|
||||
display: grid;
|
||||
grid-template-columns: auto 1fr;
|
||||
align-items: start;
|
||||
gap: 4px;
|
||||
margin-bottom: 4px;
|
||||
border-bottom: 1px solid;
|
||||
border-bottom: 1px solid;
|
||||
}
|
||||
.AC li>div:nth-child(1){
|
||||
|
||||
.AC li>div:nth-child(1) {
|
||||
padding: 2px 4px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.AC li>div:nth-child(2){
|
||||
|
||||
.AC li>div:nth-child(2) {
|
||||
padding-bottom: 2px;
|
||||
}
|
26
app/templates/but/cursus_etud.j2
Normal file
26
app/templates/but/cursus_etud.j2
Normal file
@ -0,0 +1,26 @@
|
||||
{# Affichage cursus BUT fiche étudiant #}
|
||||
|
||||
<div class="cursus_but">
|
||||
<div class="cb_head"></div>
|
||||
<div class="cb_head">BUT 1</div>
|
||||
<div class="cb_head">BUT 2</div>
|
||||
<div class="cb_head">BUT 3</div>
|
||||
{% for competence_id in cursus.to_dict() %}
|
||||
<div class="cb_titre_competence">{{ cursus.competences[competence_id].titre }}</div>
|
||||
{% for annee in ('BUT1', 'BUT2', 'BUT3') %}
|
||||
{% set validation = cursus.validation_par_competence_et_annee.get(competence_id, {}).get(annee) %}
|
||||
<div>
|
||||
{% if validation %}
|
||||
<div class="code_rcue with_scoplement">
|
||||
<div>{{validation.code}}</div>
|
||||
<div class="scoplement">Validé le {{
|
||||
validation.date.strftime("%d/%m/%Y à %H:%M")
|
||||
}}</div>
|
||||
</div>
|
||||
{% else %}
|
||||
-
|
||||
{%endif%}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
</div>
|
19
scodoc.py
19
scodoc.py
@ -33,6 +33,13 @@ from app.models import Identite
|
||||
from app.models import ModuleImpl, ModuleImplInscription
|
||||
from app.models import Partition
|
||||
from app.models import ScolarFormSemestreValidation
|
||||
from app.models.but_refcomp import (
|
||||
ApcCompetence,
|
||||
ApcNiveau,
|
||||
ApcParcours,
|
||||
ApcReferentielCompetences,
|
||||
)
|
||||
from app.models.but_validations import ApcValidationAnnee, ApcValidationRCUE
|
||||
from app.models.evaluations import Evaluation
|
||||
from app.scodoc.sco_logos import make_logo_local
|
||||
from app.scodoc.sco_permissions import Permission
|
||||
@ -57,6 +64,12 @@ def make_shell_context():
|
||||
from app.scodoc import sco_utils as scu
|
||||
|
||||
return {
|
||||
"ApcCompetence": ApcCompetence,
|
||||
"ApcNiveau": ApcNiveau,
|
||||
"ApcParcours": ApcParcours,
|
||||
"ApcReferentielCompetences": ApcReferentielCompetences,
|
||||
"ApcValidationRCUE": ApcValidationRCUE,
|
||||
"ApcValidationAnnee": ApcValidationAnnee,
|
||||
"ctx": app.test_request_context(),
|
||||
"current_app": flask.current_app,
|
||||
"current_user": current_user,
|
||||
@ -71,21 +84,21 @@ def make_shell_context():
|
||||
"login_user": login_user,
|
||||
"logout_user": logout_user,
|
||||
"mapp": mapp,
|
||||
"models": models,
|
||||
"Matiere": Matiere,
|
||||
"models": models,
|
||||
"Module": Module,
|
||||
"ModuleImpl": ModuleImpl,
|
||||
"ModuleImplInscription": ModuleImplInscription,
|
||||
"Partition": Partition,
|
||||
"ndb": ndb,
|
||||
"notes": notes,
|
||||
"np": np,
|
||||
"Partition": Partition,
|
||||
"pd": pd,
|
||||
"Permission": Permission,
|
||||
"pp": pp,
|
||||
"Role": Role,
|
||||
"res_sem": res_sem,
|
||||
"ResultatsSemestreBUT": ResultatsSemestreBUT,
|
||||
"Role": Role,
|
||||
"scolar": scolar,
|
||||
"ScolarFormSemestreValidation": ScolarFormSemestreValidation,
|
||||
"ScolarNews": models.ScolarNews,
|
||||
|
Loading…
Reference in New Issue
Block a user