forked from ScoDoc/ScoDoc
Cascades sur Identite. Inscription aux parcours BUT.
This commit is contained in:
commit
3c9cc3121f
@ -4,7 +4,6 @@
|
|||||||
# See LICENSE
|
# See LICENSE
|
||||||
##############################################################################
|
##############################################################################
|
||||||
from xml.etree import ElementTree
|
from xml.etree import ElementTree
|
||||||
from typing import TextIO
|
|
||||||
|
|
||||||
import sqlalchemy
|
import sqlalchemy
|
||||||
|
|
||||||
|
@ -70,6 +70,7 @@ class ResultatsSemestre(ResultatsCache):
|
|||||||
self.etud_moy_gen: pd.Series = None
|
self.etud_moy_gen: pd.Series = None
|
||||||
self.etud_moy_gen_ranks = {}
|
self.etud_moy_gen_ranks = {}
|
||||||
self.etud_moy_gen_ranks_int = {}
|
self.etud_moy_gen_ranks_int = {}
|
||||||
|
self.moy_gen_rangs_by_group = None # virtual
|
||||||
self.modimpl_inscr_df: pd.DataFrame = None
|
self.modimpl_inscr_df: pd.DataFrame = None
|
||||||
"Inscriptions: row etudid, col modimlpl_id"
|
"Inscriptions: row etudid, col modimlpl_id"
|
||||||
self.modimpls_results: ModuleImplResults = None
|
self.modimpls_results: ModuleImplResults = None
|
||||||
@ -824,17 +825,25 @@ class ResultatsSemestre(ResultatsCache):
|
|||||||
self.formsemestre.id
|
self.formsemestre.id
|
||||||
)
|
)
|
||||||
first_partition = True
|
first_partition = True
|
||||||
|
col_order = 10
|
||||||
for partition in partitions:
|
for partition in partitions:
|
||||||
cid = f"part_{partition['partition_id']}"
|
cid = f"part_{partition['partition_id']}"
|
||||||
|
rg_cid = cid + "_rg" # rang dans la partition
|
||||||
titles[cid] = partition["partition_name"]
|
titles[cid] = partition["partition_name"]
|
||||||
if first_partition:
|
if first_partition:
|
||||||
klass = "partition"
|
klass = "partition"
|
||||||
else:
|
else:
|
||||||
klass = "partition partition_aux"
|
klass = "partition partition_aux"
|
||||||
titles[f"_{cid}_class"] = klass
|
titles[f"_{cid}_class"] = klass
|
||||||
titles[f"_{cid}_col_order"] = 10
|
titles[f"_{cid}_col_order"] = col_order
|
||||||
|
titles[f"_{rg_cid}_col_order"] = col_order + 1
|
||||||
|
col_order += 2
|
||||||
|
if partition["bul_show_rank"]:
|
||||||
|
titles[rg_cid] = f"Rg {partition['partition_name']}"
|
||||||
|
titles[f"_{rg_cid}_class"] = "partition_rangs"
|
||||||
partition_etud_groups = partitions_etud_groups[partition["partition_id"]]
|
partition_etud_groups = partitions_etud_groups[partition["partition_id"]]
|
||||||
for row in rows:
|
for row in rows:
|
||||||
|
group = None # group (dict) de l'étudiant dans cette partition
|
||||||
# dans NotesTableCompat, à revoir
|
# dans NotesTableCompat, à revoir
|
||||||
etud_etat = self.get_etud_etat(row["etudid"])
|
etud_etat = self.get_etud_etat(row["etudid"])
|
||||||
if etud_etat == "D":
|
if etud_etat == "D":
|
||||||
@ -847,8 +856,17 @@ class ResultatsSemestre(ResultatsCache):
|
|||||||
group = partition_etud_groups.get(row["etudid"])
|
group = partition_etud_groups.get(row["etudid"])
|
||||||
gr_name = group["group_name"] if group else ""
|
gr_name = group["group_name"] if group else ""
|
||||||
if gr_name:
|
if gr_name:
|
||||||
row[f"{cid}"] = gr_name
|
row[cid] = gr_name
|
||||||
row[f"_{cid}_class"] = klass
|
row[f"_{cid}_class"] = klass
|
||||||
|
# Rangs dans groupe
|
||||||
|
if (
|
||||||
|
partition["bul_show_rank"]
|
||||||
|
and (group is not None)
|
||||||
|
and (group["id"] in self.moy_gen_rangs_by_group)
|
||||||
|
):
|
||||||
|
rang = self.moy_gen_rangs_by_group[group["id"]][0]
|
||||||
|
row[rg_cid] = rang.get(row["etudid"], "")
|
||||||
|
|
||||||
first_partition = False
|
first_partition = False
|
||||||
|
|
||||||
def _recap_add_evaluations(
|
def _recap_add_evaluations(
|
||||||
|
@ -11,7 +11,9 @@ class Absence(db.Model):
|
|||||||
|
|
||||||
__tablename__ = "absences"
|
__tablename__ = "absences"
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
etudid = db.Column(db.Integer, db.ForeignKey("identite.id"), index=True)
|
etudid = db.Column(
|
||||||
|
db.Integer, db.ForeignKey("identite.id", ondelete="CASCADE"), index=True
|
||||||
|
)
|
||||||
jour = db.Column(db.Date)
|
jour = db.Column(db.Date)
|
||||||
estabs = db.Column(db.Boolean())
|
estabs = db.Column(db.Boolean())
|
||||||
estjust = db.Column(db.Boolean())
|
estjust = db.Column(db.Boolean())
|
||||||
@ -50,7 +52,7 @@ class AbsenceNotification(db.Model):
|
|||||||
id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
etudid = db.Column(
|
etudid = db.Column(
|
||||||
db.Integer,
|
db.Integer,
|
||||||
db.ForeignKey("identite.id"),
|
db.ForeignKey("identite.id", ondelete="CASCADE"),
|
||||||
)
|
)
|
||||||
notification_date = db.Column(
|
notification_date = db.Column(
|
||||||
db.DateTime(timezone=True), server_default=db.func.now()
|
db.DateTime(timezone=True), server_default=db.func.now()
|
||||||
|
@ -436,7 +436,7 @@ class Adresse(db.Model):
|
|||||||
adresse_id = db.synonym("id")
|
adresse_id = db.synonym("id")
|
||||||
etudid = db.Column(
|
etudid = db.Column(
|
||||||
db.Integer,
|
db.Integer,
|
||||||
db.ForeignKey("identite.id"),
|
db.ForeignKey("identite.id", ondelete="CASCADE"),
|
||||||
)
|
)
|
||||||
email = db.Column(db.Text()) # mail institutionnel
|
email = db.Column(db.Text()) # mail institutionnel
|
||||||
emailperso = db.Column(db.Text) # email personnel (exterieur)
|
emailperso = db.Column(db.Text) # email personnel (exterieur)
|
||||||
@ -470,7 +470,7 @@ class Admission(db.Model):
|
|||||||
adm_id = db.synonym("id")
|
adm_id = db.synonym("id")
|
||||||
etudid = db.Column(
|
etudid = db.Column(
|
||||||
db.Integer,
|
db.Integer,
|
||||||
db.ForeignKey("identite.id"),
|
db.ForeignKey("identite.id", ondelete="CASCADE"),
|
||||||
)
|
)
|
||||||
# Anciens champs de ScoDoc7, à revoir pour être plus générique et souple
|
# Anciens champs de ScoDoc7, à revoir pour être plus générique et souple
|
||||||
# notamment dans le cadre du bac 2021
|
# notamment dans le cadre du bac 2021
|
||||||
@ -540,7 +540,7 @@ class ItemSuivi(db.Model):
|
|||||||
itemsuivi_id = db.synonym("id")
|
itemsuivi_id = db.synonym("id")
|
||||||
etudid = db.Column(
|
etudid = db.Column(
|
||||||
db.Integer,
|
db.Integer,
|
||||||
db.ForeignKey("identite.id"),
|
db.ForeignKey("identite.id", ondelete="CASCADE"),
|
||||||
)
|
)
|
||||||
item_date = db.Column(db.DateTime(timezone=True), server_default=db.func.now())
|
item_date = db.Column(db.DateTime(timezone=True), server_default=db.func.now())
|
||||||
situation = db.Column(db.Text)
|
situation = db.Column(db.Text)
|
||||||
|
@ -323,6 +323,25 @@ class FormSemestre(db.Model):
|
|||||||
return ""
|
return ""
|
||||||
return ", ".join(sorted([etape.etape_apo for etape in self.etapes if etape]))
|
return ", ".join(sorted([etape.etape_apo for etape in self.etapes if etape]))
|
||||||
|
|
||||||
|
def regroupements_coherents_etud(self) -> list[tuple[UniteEns, UniteEns]]:
|
||||||
|
"""Calcule la liste des regroupements cohérents d'UE impliquant ce
|
||||||
|
formsemestre.
|
||||||
|
Pour une année donnée: l'étudiant est inscrit dans ScoDoc soit dans le semestre
|
||||||
|
impair, soit pair, soit les deux (il est rare mais pas impossible d'avoir une
|
||||||
|
inscription seulement en semestre pair, par exemple suite à un transfert ou un
|
||||||
|
arrêt temporaire du cursus).
|
||||||
|
|
||||||
|
1. Déterminer l'*autre* formsemestre: semestre précédent ou suivant de la même
|
||||||
|
année, formation compatible (même référentiel de compétence) dans lequel
|
||||||
|
l'étudiant est inscrit.
|
||||||
|
|
||||||
|
2. Construire les couples d'UE (regroupements cohérents): apparier les UE qui
|
||||||
|
ont le même `ApcParcoursNiveauCompetence`.
|
||||||
|
"""
|
||||||
|
if not self.formation.is_apc():
|
||||||
|
return []
|
||||||
|
raise NotImplementedError() # XXX
|
||||||
|
|
||||||
def responsables_str(self, abbrev_prenom=True) -> str:
|
def responsables_str(self, abbrev_prenom=True) -> str:
|
||||||
"""chaîne "J. Dupond, X. Martin"
|
"""chaîne "J. Dupond, X. Martin"
|
||||||
ou "Jacques Dupond, Xavier Martin"
|
ou "Jacques Dupond, Xavier Martin"
|
||||||
@ -614,7 +633,9 @@ class FormSemestreInscription(db.Model):
|
|||||||
id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
formsemestre_inscription_id = db.synonym("id")
|
formsemestre_inscription_id = db.synonym("id")
|
||||||
|
|
||||||
etudid = db.Column(db.Integer, db.ForeignKey("identite.id"), index=True)
|
etudid = db.Column(
|
||||||
|
db.Integer, db.ForeignKey("identite.id", ondelete="CASCADE"), index=True
|
||||||
|
)
|
||||||
formsemestre_id = db.Column(
|
formsemestre_id = db.Column(
|
||||||
db.Integer,
|
db.Integer,
|
||||||
db.ForeignKey("notes_formsemestre.id"),
|
db.ForeignKey("notes_formsemestre.id"),
|
||||||
@ -634,11 +655,16 @@ class FormSemestreInscription(db.Model):
|
|||||||
)
|
)
|
||||||
# I inscrit, D demission en cours de semestre, DEF si "defaillant"
|
# I inscrit, D demission en cours de semestre, DEF si "defaillant"
|
||||||
etat = db.Column(db.String(CODE_STR_LEN), index=True)
|
etat = db.Column(db.String(CODE_STR_LEN), index=True)
|
||||||
# etape apogee d'inscription (experimental 2020)
|
# Etape Apogée d'inscription (ajout 2020)
|
||||||
etape = db.Column(db.String(APO_CODE_STR_LEN))
|
etape = db.Column(db.String(APO_CODE_STR_LEN))
|
||||||
|
# Parcours (pour les BUT)
|
||||||
|
parcour_id = db.Column(db.Integer, db.ForeignKey("apc_parcours.id"), index=True)
|
||||||
|
parcour = db.relationship(ApcParcours)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"<{self.__class__.__name__} {self.id} etudid={self.etudid} sem={self.formsemestre_id} etat={self.etat}>"
|
return f"""<{self.__class__.__name__} {self.id} etudid={self.etudid} sem={
|
||||||
|
self.formsemestre_id} etat={self.etat} {
|
||||||
|
('parcours='+str(self.parcour)) if self.parcour else ''}>"""
|
||||||
|
|
||||||
|
|
||||||
class NotesSemSet(db.Model):
|
class NotesSemSet(db.Model):
|
||||||
|
@ -106,7 +106,7 @@ class GroupDescr(db.Model):
|
|||||||
|
|
||||||
group_membership = db.Table(
|
group_membership = db.Table(
|
||||||
"group_membership",
|
"group_membership",
|
||||||
db.Column("etudid", db.Integer, db.ForeignKey("identite.id")),
|
db.Column("etudid", db.Integer, db.ForeignKey("identite.id", ondelete="CASCADE")),
|
||||||
db.Column("group_id", db.Integer, db.ForeignKey("group_descr.id")),
|
db.Column("group_id", db.Integer, db.ForeignKey("group_descr.id")),
|
||||||
db.UniqueConstraint("etudid", "group_id"),
|
db.UniqueConstraint("etudid", "group_id"),
|
||||||
)
|
)
|
||||||
@ -116,5 +116,5 @@ group_membership = db.Table(
|
|||||||
# __tablename__ = "group_membership"
|
# __tablename__ = "group_membership"
|
||||||
# __table_args__ = (db.UniqueConstraint("etudid", "group_id"),)
|
# __table_args__ = (db.UniqueConstraint("etudid", "group_id"),)
|
||||||
# id = db.Column(db.Integer, primary_key=True)
|
# id = db.Column(db.Integer, primary_key=True)
|
||||||
# etudid = db.Column(db.Integer, db.ForeignKey("identite.id"))
|
# etudid = db.Column(db.Integer, db.ForeignKey("identite.id", ondelete="CASCADE"))
|
||||||
# group_id = db.Column(db.Integer, db.ForeignKey("group_descr.id"))
|
# group_id = db.Column(db.Integer, db.ForeignKey("group_descr.id"))
|
||||||
|
@ -17,7 +17,7 @@ class BulAppreciations(db.Model):
|
|||||||
date = db.Column(db.DateTime(timezone=True), server_default=db.func.now())
|
date = db.Column(db.DateTime(timezone=True), server_default=db.func.now())
|
||||||
etudid = db.Column(
|
etudid = db.Column(
|
||||||
db.Integer,
|
db.Integer,
|
||||||
db.ForeignKey("identite.id"),
|
db.ForeignKey("identite.id", ondelete="CASCADE"),
|
||||||
index=True,
|
index=True,
|
||||||
)
|
)
|
||||||
formsemestre_id = db.Column(
|
formsemestre_id = db.Column(
|
||||||
@ -36,7 +36,7 @@ class NotesNotes(db.Model):
|
|||||||
id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
etudid = db.Column(
|
etudid = db.Column(
|
||||||
db.Integer,
|
db.Integer,
|
||||||
db.ForeignKey("identite.id"),
|
db.ForeignKey("identite.id", ondelete="CASCADE"),
|
||||||
)
|
)
|
||||||
evaluation_id = db.Column(
|
evaluation_id = db.Column(
|
||||||
db.Integer, db.ForeignKey("notes_evaluation.id"), index=True
|
db.Integer, db.ForeignKey("notes_evaluation.id"), index=True
|
||||||
@ -56,7 +56,7 @@ class NotesNotesLog(db.Model):
|
|||||||
|
|
||||||
etudid = db.Column(
|
etudid = db.Column(
|
||||||
db.Integer,
|
db.Integer,
|
||||||
db.ForeignKey("identite.id"),
|
db.ForeignKey("identite.id", ondelete="CASCADE"),
|
||||||
)
|
)
|
||||||
evaluation_id = db.Column(
|
evaluation_id = db.Column(
|
||||||
db.Integer,
|
db.Integer,
|
||||||
|
@ -19,7 +19,7 @@ class ScolarFormSemestreValidation(db.Model):
|
|||||||
formsemestre_validation_id = db.synonym("id")
|
formsemestre_validation_id = db.synonym("id")
|
||||||
etudid = db.Column(
|
etudid = db.Column(
|
||||||
db.Integer,
|
db.Integer,
|
||||||
db.ForeignKey("identite.id"),
|
db.ForeignKey("identite.id", ondelete="CASCADE"),
|
||||||
index=True,
|
index=True,
|
||||||
)
|
)
|
||||||
formsemestre_id = db.Column(
|
formsemestre_id = db.Column(
|
||||||
@ -66,7 +66,7 @@ class ScolarAutorisationInscription(db.Model):
|
|||||||
|
|
||||||
etudid = db.Column(
|
etudid = db.Column(
|
||||||
db.Integer,
|
db.Integer,
|
||||||
db.ForeignKey("identite.id"),
|
db.ForeignKey("identite.id", ondelete="CASCADE"),
|
||||||
)
|
)
|
||||||
formation_code = db.Column(db.String(SHORT_STR_LEN), nullable=False)
|
formation_code = db.Column(db.String(SHORT_STR_LEN), nullable=False)
|
||||||
# semestre ou on peut s'inscrire:
|
# semestre ou on peut s'inscrire:
|
||||||
@ -86,7 +86,7 @@ class ScolarEvent(db.Model):
|
|||||||
event_id = db.synonym("id")
|
event_id = db.synonym("id")
|
||||||
etudid = db.Column(
|
etudid = db.Column(
|
||||||
db.Integer,
|
db.Integer,
|
||||||
db.ForeignKey("identite.id"),
|
db.ForeignKey("identite.id", ondelete="CASCADE"),
|
||||||
)
|
)
|
||||||
event_date = db.Column(db.DateTime(timezone=True), server_default=db.func.now())
|
event_date = db.Column(db.DateTime(timezone=True), server_default=db.func.now())
|
||||||
formsemestre_id = db.Column(
|
formsemestre_id = db.Column(
|
||||||
|
@ -244,7 +244,11 @@ def formation_edit(formation_id=None, create=False):
|
|||||||
return (
|
return (
|
||||||
"\n".join(H)
|
"\n".join(H)
|
||||||
+ tf_error_message(
|
+ tf_error_message(
|
||||||
"Valeurs incorrectes: il existe déjà une formation avec même titre, acronyme et version."
|
f"""Valeurs incorrectes: il existe déjà <a href="{
|
||||||
|
url_for('notes.ue_table', scodoc_dept=g.scodoc_dept, formation_id=others[0]["id"])
|
||||||
|
}">une formation</a> avec même titre,
|
||||||
|
acronyme et version.
|
||||||
|
"""
|
||||||
)
|
)
|
||||||
+ tf[1]
|
+ tf[1]
|
||||||
+ html_sco_header.sco_footer()
|
+ html_sco_header.sco_footer()
|
||||||
|
@ -352,7 +352,7 @@ def module_edit(
|
|||||||
title = f"""Création {object_name} dans la formation
|
title = f"""Création {object_name} dans la formation
|
||||||
{formation.acronyme}"""
|
{formation.acronyme}"""
|
||||||
else:
|
else:
|
||||||
page_title = "Modification du module {module.code or module.titre or ''}"
|
page_title = f"Modification du module {module.code or module.titre or ''}"
|
||||||
title = f"""Modification du module {module.code or ''} {module.titre or ''}
|
title = f"""Modification du module {module.code or ''} {module.titre or ''}
|
||||||
(formation {formation.acronyme}, version {formation.version})
|
(formation {formation.acronyme}, version {formation.version})
|
||||||
"""
|
"""
|
||||||
|
@ -1009,7 +1009,7 @@ def edit_partition_form(formsemestre_id=None):
|
|||||||
<input type="submit" name="ok" disabled="1" value="Nouvelle partition"/>
|
<input type="submit" name="ok" disabled="1" value="Nouvelle partition"/>
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
if formsemestre.formation.is_apc() and "Parcours" not in (
|
if formsemestre.formation.is_apc() and scu.PARTITION_PARCOURS not in (
|
||||||
p["partition_name"] for p in partitions
|
p["partition_name"] for p in partitions
|
||||||
):
|
):
|
||||||
# propose création partition "Parcours"
|
# propose création partition "Parcours"
|
||||||
@ -1068,9 +1068,7 @@ def partition_set_attr(partition_id, attr, value):
|
|||||||
partition[attr] = value
|
partition[attr] = value
|
||||||
partitionEditor.edit(cnx, partition)
|
partitionEditor.edit(cnx, partition)
|
||||||
# invalid bulletin cache
|
# invalid bulletin cache
|
||||||
sco_cache.invalidate_formsemestre(
|
sco_cache.invalidate_formsemestre(formsemestre_id=partition["formsemestre_id"])
|
||||||
pdfonly=True, formsemestre_id=partition["formsemestre_id"]
|
|
||||||
)
|
|
||||||
return "enregistré"
|
return "enregistré"
|
||||||
|
|
||||||
|
|
||||||
|
@ -111,6 +111,8 @@ MODULE_TYPE_NAMES = {
|
|||||||
None: "Module",
|
None: "Module",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PARTITION_PARCOURS = "Parcours"
|
||||||
|
|
||||||
MALUS_MAX = 20.0
|
MALUS_MAX = 20.0
|
||||||
MALUS_MIN = -20.0
|
MALUS_MIN = -20.0
|
||||||
|
|
||||||
|
@ -15,13 +15,23 @@ $(function () {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "toggle_partitions",
|
name: "toggle_partitions",
|
||||||
text: "Toutes les partitions",
|
text: "Montrer groupes",
|
||||||
action: function (e, dt, node, config) {
|
action: function (e, dt, node, config) {
|
||||||
let visible = dt.columns(".partition_aux").visible()[0];
|
let visible = dt.columns(".partition_aux").visible()[0];
|
||||||
dt.columns(".partition_aux").visible(!visible);
|
dt.columns(".partition_aux").visible(!visible);
|
||||||
dt.buttons('toggle_partitions:name').text(visible ? "Toutes les partitions" : "Cacher les partitions");
|
dt.buttons('toggle_partitions:name').text(visible ? "Montrer groupes" : "Cacher les groupes");
|
||||||
}
|
}
|
||||||
}];
|
},
|
||||||
|
{
|
||||||
|
name: "toggle_partitions_rangs",
|
||||||
|
text: "Rangs groupes",
|
||||||
|
action: function (e, dt, node, config) {
|
||||||
|
let rangs_visible = dt.columns(".partition_rangs").visible()[0];
|
||||||
|
dt.columns(".partition_rangs").visible(!rangs_visible);
|
||||||
|
dt.buttons('toggle_partitions_rangs:name').text(rangs_visible ? "Rangs groupes" : "Cacher rangs groupes");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
];
|
||||||
if (!$('table.table_recap').hasClass("jury")) {
|
if (!$('table.table_recap').hasClass("jury")) {
|
||||||
buttons.push(
|
buttons.push(
|
||||||
$('table.table_recap').hasClass("apc") ?
|
$('table.table_recap').hasClass("apc") ?
|
||||||
@ -95,7 +105,7 @@ $(function () {
|
|||||||
"columnDefs": [
|
"columnDefs": [
|
||||||
{
|
{
|
||||||
// cache les codes, le détail de l'identité, les groupes, les colonnes admission et les vides
|
// cache les codes, le détail de l'identité, les groupes, les colonnes admission et les vides
|
||||||
targets: ["codes", "identite_detail", "partition_aux", "admission", "col_empty"],
|
targets: ["codes", "identite_detail", "partition_aux", "partition_rangs", "admission", "col_empty"],
|
||||||
visible: false,
|
visible: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -7,8 +7,8 @@
|
|||||||
|
|
||||||
<div class="help">
|
<div class="help">
|
||||||
<p>Ces codes (ADM, AJ, ...) sont utilisés pour représenter les décisions de jury
|
<p>Ces codes (ADM, AJ, ...) sont utilisés pour représenter les décisions de jury
|
||||||
et les validations de semestres ou d'UE. les valeurs indiquées ici sont utilisées
|
et les validations de semestres ou d'UE.
|
||||||
dans les exports Apogée.
|
Les valeurs indiquées ici sont utilisées dans les exports Apogée.
|
||||||
<p>
|
<p>
|
||||||
<p>Ne les modifier que si vous savez ce que vous faites !
|
<p>Ne les modifier que si vous savez ce que vous faites !
|
||||||
</p>
|
</p>
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
<li>Code: <tt>{{ue.ue_code}}</tt></li>
|
<li>Code: <tt>{{ue.ue_code}}</tt></li>
|
||||||
<li>Type: {{ue.type}}</li>
|
<li>Type: {{ue.type}}</li>
|
||||||
<li>Externe: {{ "oui" if ue.is_external else "non" }}</li>
|
<li>Externe: {{ "oui" if ue.is_external else "non" }}</li>
|
||||||
<li>Code Apogée: {{ue.code_apogee}}</li>
|
<li>Code Apogée: {{ue.code_apogee or "aucun"}}</li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li>Formation:
|
<li>Formation:
|
||||||
|
@ -915,13 +915,14 @@ sco_publish(
|
|||||||
@permission_required(Permission.ScoView)
|
@permission_required(Permission.ScoView)
|
||||||
@scodoc7func
|
@scodoc7func
|
||||||
def create_partition_parcours(formsemestre_id):
|
def create_partition_parcours(formsemestre_id):
|
||||||
"""Création d'une partitions nommée "Parcours" avec un groupe par parcours."""
|
"""Création d'une partitions nommée "Parcours" (PARTITION_PARCOURS)
|
||||||
|
avec un groupe par parcours."""
|
||||||
formsemestre = FormSemestre.query.get_or_404(formsemestre_id)
|
formsemestre = FormSemestre.query.get_or_404(formsemestre_id)
|
||||||
if "Parcours" in (p.partition_name for p in formsemestre.partitions):
|
if scu.PARTITION_PARCOURS in (p.partition_name for p in formsemestre.partitions):
|
||||||
flash("""Partition "Parcours" déjà existante""")
|
flash(f"""Partition "{scu.PARTITION_PARCOURS}" déjà existante""")
|
||||||
else:
|
else:
|
||||||
partition_id = sco_groups.partition_create(
|
partition_id = sco_groups.partition_create(
|
||||||
formsemestre_id, partition_name="Parcours", redirect=False
|
formsemestre_id, partition_name=scu.PARTITION_PARCOURS, redirect=False
|
||||||
)
|
)
|
||||||
n = 0
|
n = 0
|
||||||
for parcour in formsemestre.parcours:
|
for parcour in formsemestre.parcours:
|
||||||
|
308
migrations/versions/a2771105c21c_parcours_inscriptions_casc.py
Normal file
308
migrations/versions/a2771105c21c_parcours_inscriptions_casc.py
Normal file
@ -0,0 +1,308 @@
|
|||||||
|
"""Formsemestre / parcours, Inscriptions aux parcours + cascades sur Identite
|
||||||
|
|
||||||
|
Revision ID: a2771105c21c
|
||||||
|
Revises: 6002d7d366e5
|
||||||
|
Create Date: 2022-05-25 20:32:06.868296
|
||||||
|
|
||||||
|
"""
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = "a2771105c21c"
|
||||||
|
down_revision = "6002d7d366e5"
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.create_table(
|
||||||
|
"parcours_formsemestre",
|
||||||
|
sa.Column("parcours_id", sa.Integer(), nullable=False),
|
||||||
|
sa.Column("formsemestre_id", sa.Integer(), nullable=False),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["formsemestre_id"], ["notes_formsemestre.id"], ondelete="CASCADE"
|
||||||
|
),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["parcours_id"],
|
||||||
|
["apc_parcours.id"],
|
||||||
|
),
|
||||||
|
sa.PrimaryKeyConstraint("parcours_id", "formsemestre_id"),
|
||||||
|
)
|
||||||
|
op.drop_constraint("absences_etudid_fkey", "absences", type_="foreignkey")
|
||||||
|
op.create_foreign_key(
|
||||||
|
"absences_etudid_fkey",
|
||||||
|
"absences",
|
||||||
|
"identite",
|
||||||
|
["etudid"],
|
||||||
|
["id"],
|
||||||
|
ondelete="CASCADE",
|
||||||
|
)
|
||||||
|
op.drop_constraint(
|
||||||
|
"absences_notifications_etudid_fkey",
|
||||||
|
"absences_notifications",
|
||||||
|
type_="foreignkey",
|
||||||
|
)
|
||||||
|
op.create_foreign_key(
|
||||||
|
"absences_notifications_etudid_fkey",
|
||||||
|
"absences_notifications",
|
||||||
|
"identite",
|
||||||
|
["etudid"],
|
||||||
|
["id"],
|
||||||
|
ondelete="CASCADE",
|
||||||
|
)
|
||||||
|
op.drop_constraint("admissions_etudid_fkey", "admissions", type_="foreignkey")
|
||||||
|
op.create_foreign_key(
|
||||||
|
"admissions_etudid_fkey",
|
||||||
|
"admissions",
|
||||||
|
"identite",
|
||||||
|
["etudid"],
|
||||||
|
["id"],
|
||||||
|
ondelete="CASCADE",
|
||||||
|
)
|
||||||
|
op.drop_constraint("adresse_etudid_fkey", "adresse", type_="foreignkey")
|
||||||
|
op.create_foreign_key(
|
||||||
|
"adresse_etudid_fkey",
|
||||||
|
"adresse",
|
||||||
|
"identite",
|
||||||
|
["etudid"],
|
||||||
|
["id"],
|
||||||
|
ondelete="CASCADE",
|
||||||
|
)
|
||||||
|
op.drop_constraint(
|
||||||
|
"group_membership_etudid_fkey", "group_membership", type_="foreignkey"
|
||||||
|
)
|
||||||
|
op.create_foreign_key(
|
||||||
|
"group_membership_etudid_fkey",
|
||||||
|
"group_membership",
|
||||||
|
"identite",
|
||||||
|
["etudid"],
|
||||||
|
["id"],
|
||||||
|
ondelete="CASCADE",
|
||||||
|
)
|
||||||
|
op.drop_constraint("itemsuivi_etudid_fkey", "itemsuivi", type_="foreignkey")
|
||||||
|
op.create_foreign_key(
|
||||||
|
"itemsuivi_etudid_fkey",
|
||||||
|
"itemsuivi",
|
||||||
|
"identite",
|
||||||
|
["etudid"],
|
||||||
|
["id"],
|
||||||
|
ondelete="CASCADE",
|
||||||
|
)
|
||||||
|
op.drop_constraint(
|
||||||
|
"notes_appreciations_etudid_fkey", "notes_appreciations", type_="foreignkey"
|
||||||
|
)
|
||||||
|
op.create_foreign_key(
|
||||||
|
"notes_appreciations_etudid_fkey",
|
||||||
|
"notes_appreciations",
|
||||||
|
"identite",
|
||||||
|
["etudid"],
|
||||||
|
["id"],
|
||||||
|
ondelete="CASCADE",
|
||||||
|
)
|
||||||
|
# INSCRIPTIONS
|
||||||
|
op.drop_constraint(
|
||||||
|
"notes_formsemestre_inscription_etudid_fkey",
|
||||||
|
"notes_formsemestre_inscription",
|
||||||
|
type_="foreignkey",
|
||||||
|
)
|
||||||
|
op.create_foreign_key(
|
||||||
|
"notes_formsemestre_inscription_etudid_fkey",
|
||||||
|
"notes_formsemestre_inscription",
|
||||||
|
"identite",
|
||||||
|
["etudid"],
|
||||||
|
["id"],
|
||||||
|
ondelete="CASCADE",
|
||||||
|
)
|
||||||
|
op.add_column(
|
||||||
|
"notes_formsemestre_inscription",
|
||||||
|
sa.Column("parcour_id", sa.Integer(), nullable=True),
|
||||||
|
)
|
||||||
|
op.create_index(
|
||||||
|
op.f("ix_notes_formsemestre_inscription_parcour_id"),
|
||||||
|
"notes_formsemestre_inscription",
|
||||||
|
["parcour_id"],
|
||||||
|
unique=False,
|
||||||
|
)
|
||||||
|
op.create_foreign_key(
|
||||||
|
"notes_formsemestre_inscription_parcour_id_fkey",
|
||||||
|
"notes_formsemestre_inscription",
|
||||||
|
"apc_parcours",
|
||||||
|
["parcour_id"],
|
||||||
|
["id"],
|
||||||
|
)
|
||||||
|
# ---
|
||||||
|
op.drop_constraint("notes_notes_etudid_fkey", "notes_notes", type_="foreignkey")
|
||||||
|
op.create_foreign_key(
|
||||||
|
"notes_notes_etudid_fkey",
|
||||||
|
"notes_notes",
|
||||||
|
"identite",
|
||||||
|
["etudid"],
|
||||||
|
["id"],
|
||||||
|
ondelete="CASCADE",
|
||||||
|
)
|
||||||
|
op.drop_constraint(
|
||||||
|
"notes_notes_log_etudid_fkey", "notes_notes_log", type_="foreignkey"
|
||||||
|
)
|
||||||
|
op.create_foreign_key(
|
||||||
|
"notes_notes_log_etudid_fkey",
|
||||||
|
"notes_notes_log",
|
||||||
|
"identite",
|
||||||
|
["etudid"],
|
||||||
|
["id"],
|
||||||
|
ondelete="CASCADE",
|
||||||
|
)
|
||||||
|
op.drop_constraint(
|
||||||
|
"scolar_autorisation_inscription_etudid_fkey",
|
||||||
|
"scolar_autorisation_inscription",
|
||||||
|
type_="foreignkey",
|
||||||
|
)
|
||||||
|
op.create_foreign_key(
|
||||||
|
"scolar_autorisation_inscription_etudid_fkey",
|
||||||
|
"scolar_autorisation_inscription",
|
||||||
|
"identite",
|
||||||
|
["etudid"],
|
||||||
|
["id"],
|
||||||
|
ondelete="CASCADE",
|
||||||
|
)
|
||||||
|
op.drop_constraint("scolar_events_etudid_fkey", "scolar_events", type_="foreignkey")
|
||||||
|
op.create_foreign_key(
|
||||||
|
"scolar_events_etudid_fkey",
|
||||||
|
"scolar_events",
|
||||||
|
"identite",
|
||||||
|
["etudid"],
|
||||||
|
["id"],
|
||||||
|
ondelete="CASCADE",
|
||||||
|
)
|
||||||
|
op.drop_constraint(
|
||||||
|
"scolar_formsemestre_validation_etudid_fkey",
|
||||||
|
"scolar_formsemestre_validation",
|
||||||
|
type_="foreignkey",
|
||||||
|
)
|
||||||
|
op.create_foreign_key(
|
||||||
|
"scolar_formsemestre_validation_etudid_fkey",
|
||||||
|
"scolar_formsemestre_validation",
|
||||||
|
"identite",
|
||||||
|
["etudid"],
|
||||||
|
["id"],
|
||||||
|
ondelete="CASCADE",
|
||||||
|
)
|
||||||
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.drop_constraint(
|
||||||
|
"scolar_formsemestre_validation_etudid_fkey",
|
||||||
|
"scolar_formsemestre_validation",
|
||||||
|
type_="foreignkey",
|
||||||
|
)
|
||||||
|
op.create_foreign_key(
|
||||||
|
"scolar_formsemestre_validation_etudid_fkey",
|
||||||
|
"scolar_formsemestre_validation",
|
||||||
|
"identite",
|
||||||
|
["etudid"],
|
||||||
|
["id"],
|
||||||
|
)
|
||||||
|
op.drop_constraint("scolar_events_etudid_fkey", "scolar_events", type_="foreignkey")
|
||||||
|
op.create_foreign_key(
|
||||||
|
"scolar_events_etudid_fkey", "scolar_events", "identite", ["etudid"], ["id"]
|
||||||
|
)
|
||||||
|
op.drop_constraint(
|
||||||
|
"scolar_autorisation_inscription_etudid_fkey",
|
||||||
|
"scolar_autorisation_inscription",
|
||||||
|
type_="foreignkey",
|
||||||
|
)
|
||||||
|
op.create_foreign_key(
|
||||||
|
"scolar_autorisation_inscription_etudid_fkey",
|
||||||
|
"scolar_autorisation_inscription",
|
||||||
|
"identite",
|
||||||
|
["etudid"],
|
||||||
|
["id"],
|
||||||
|
)
|
||||||
|
op.drop_constraint(
|
||||||
|
"notes_notes_log_etudid_fkey", "notes_notes_log", type_="foreignkey"
|
||||||
|
)
|
||||||
|
op.create_foreign_key(
|
||||||
|
"notes_notes_log_etudid_fkey", "notes_notes_log", "identite", ["etudid"], ["id"]
|
||||||
|
)
|
||||||
|
op.drop_constraint("notes_notes_etudid_fkey", "notes_notes", type_="foreignkey")
|
||||||
|
op.create_foreign_key(
|
||||||
|
"notes_notes_etudid_fkey", "notes_notes", "identite", ["etudid"], ["id"]
|
||||||
|
)
|
||||||
|
# INSCRIPTIONS
|
||||||
|
op.drop_constraint(
|
||||||
|
"notes_formsemestre_inscription_etudid_fkey",
|
||||||
|
"notes_formsemestre_inscription",
|
||||||
|
type_="foreignkey",
|
||||||
|
)
|
||||||
|
op.create_foreign_key(
|
||||||
|
"notes_formsemestre_inscription_etudid_fkey",
|
||||||
|
"notes_formsemestre_inscription",
|
||||||
|
"identite",
|
||||||
|
["etudid"],
|
||||||
|
["id"],
|
||||||
|
)
|
||||||
|
op.drop_constraint(
|
||||||
|
"notes_formsemestre_inscription_parcour_id_fkey",
|
||||||
|
"notes_formsemestre_inscription",
|
||||||
|
type_="foreignkey",
|
||||||
|
)
|
||||||
|
op.drop_index(
|
||||||
|
op.f("ix_notes_formsemestre_inscription_parcour_id"),
|
||||||
|
table_name="notes_formsemestre_inscription",
|
||||||
|
)
|
||||||
|
op.drop_column("notes_formsemestre_inscription", "parcour_id")
|
||||||
|
# --
|
||||||
|
op.drop_constraint(
|
||||||
|
"notes_appreciations_etudid_fkey", "notes_appreciations", type_="foreignkey"
|
||||||
|
)
|
||||||
|
op.create_foreign_key(
|
||||||
|
"notes_appreciations_etudid_fkey",
|
||||||
|
"notes_appreciations",
|
||||||
|
"identite",
|
||||||
|
["etudid"],
|
||||||
|
["id"],
|
||||||
|
)
|
||||||
|
op.drop_constraint("itemsuivi_etudid_fkey", "itemsuivi", type_="foreignkey")
|
||||||
|
op.create_foreign_key(
|
||||||
|
"itemsuivi_etudid_fkey", "itemsuivi", "identite", ["etudid"], ["id"]
|
||||||
|
)
|
||||||
|
op.drop_constraint(
|
||||||
|
"group_membership_etudid_fkey", "group_membership", type_="foreignkey"
|
||||||
|
)
|
||||||
|
op.create_foreign_key(
|
||||||
|
"group_membership_etudid_fkey",
|
||||||
|
"group_membership",
|
||||||
|
"identite",
|
||||||
|
["etudid"],
|
||||||
|
["id"],
|
||||||
|
)
|
||||||
|
op.drop_constraint("adresse_etudid_fkey", "adresse", type_="foreignkey")
|
||||||
|
op.create_foreign_key(
|
||||||
|
"adresse_etudid_fkey", "adresse", "identite", ["etudid"], ["id"]
|
||||||
|
)
|
||||||
|
op.drop_constraint("admissions_etudid_fkey", "admissions", type_="foreignkey")
|
||||||
|
op.create_foreign_key(
|
||||||
|
"admissions_etudid_fkey", "admissions", "identite", ["etudid"], ["id"]
|
||||||
|
)
|
||||||
|
op.drop_constraint(
|
||||||
|
"absences_notifications_etudid_fkey",
|
||||||
|
"absences_notifications",
|
||||||
|
type_="foreignkey",
|
||||||
|
)
|
||||||
|
op.create_foreign_key(
|
||||||
|
"absences_notifications_etudid_fkey",
|
||||||
|
"absences_notifications",
|
||||||
|
"identite",
|
||||||
|
["etudid"],
|
||||||
|
["id"],
|
||||||
|
)
|
||||||
|
op.drop_constraint("absences_etudid_fkey", "absences", type_="foreignkey")
|
||||||
|
op.create_foreign_key(
|
||||||
|
"absences_etudid_fkey", "absences", "identite", ["etudid"], ["id"]
|
||||||
|
)
|
||||||
|
op.drop_table("parcours_formsemestre")
|
||||||
|
# ### end Alembic commands ###
|
@ -14,6 +14,7 @@ Au besoin, créer un base de test neuve:
|
|||||||
import random
|
import random
|
||||||
|
|
||||||
from flask import g
|
from flask import g
|
||||||
|
from app.models.formsemestre import FormSemestreInscription
|
||||||
|
|
||||||
from config import TestConfig
|
from config import TestConfig
|
||||||
from tests.unit import sco_fake_gen
|
from tests.unit import sco_fake_gen
|
||||||
@ -85,6 +86,15 @@ def run_sco_basic(verbose=False):
|
|||||||
# --- Inscription des étudiants
|
# --- Inscription des étudiants
|
||||||
for etud in etuds:
|
for etud in etuds:
|
||||||
G.inscrit_etudiant(formsemestre_id, etud)
|
G.inscrit_etudiant(formsemestre_id, etud)
|
||||||
|
# Vérification incription semestre:
|
||||||
|
q = FormSemestreInscription.query.filter_by(
|
||||||
|
etudid=etuds[0].id, formsemestre_id=formsemestre_id
|
||||||
|
)
|
||||||
|
assert q.count() == 1
|
||||||
|
ins = q.first()
|
||||||
|
assert ins.etape == None
|
||||||
|
assert ins.etat == "I"
|
||||||
|
assert ins.parcour == None
|
||||||
|
|
||||||
# --- Creation évaluation
|
# --- Creation évaluation
|
||||||
e = G.create_evaluation(
|
e = G.create_evaluation(
|
||||||
@ -217,3 +227,15 @@ def run_sco_basic(verbose=False):
|
|||||||
dec_ues = nt.get_etud_decision_ues(etud["etudid"])
|
dec_ues = nt.get_etud_decision_ues(etud["etudid"])
|
||||||
for ue_id in dec_ues:
|
for ue_id in dec_ues:
|
||||||
assert dec_ues[ue_id]["code"] in {"ADM", "CMP"}
|
assert dec_ues[ue_id]["code"] in {"ADM", "CMP"}
|
||||||
|
|
||||||
|
# ---- Suppression étudiant, vérification inscription
|
||||||
|
# (permet de tester les cascades)
|
||||||
|
etud = etuds[0]
|
||||||
|
etudid = etud.id
|
||||||
|
db.session.delete(etud)
|
||||||
|
db.session.commit()
|
||||||
|
# Vérification incription semestre:
|
||||||
|
q = FormSemestreInscription.query.filter_by(
|
||||||
|
etudid=etudid, formsemestre_id=formsemestre_id
|
||||||
|
)
|
||||||
|
assert q.count() == 0
|
||||||
|
Loading…
Reference in New Issue
Block a user