forked from ScoDoc/ScoDoc
Modernise code inscription/passage semestre. Closes #859
This commit is contained in:
parent
e6d61fcd8a
commit
56aa5fbba3
@ -85,17 +85,6 @@ UE_ELECTIVE = 4 # UE "élective" dans certains cursus (UCAC?, ISCID)
|
||||
UE_PROFESSIONNELLE = 5 # UE "professionnelle" (ISCID, ...)
|
||||
UE_OPTIONNELLE = 6 # UE non fondamentales (ILEPS, ...)
|
||||
|
||||
|
||||
def ue_is_fondamentale(ue_type):
|
||||
return ue_type in (UE_STANDARD, UE_STAGE_LP, UE_PROFESSIONNELLE)
|
||||
|
||||
|
||||
def ue_is_professionnelle(ue_type):
|
||||
return (
|
||||
ue_type == UE_PROFESSIONNELLE
|
||||
) # NB: les UE_PROFESSIONNELLE sont à la fois fondamentales et pro
|
||||
|
||||
|
||||
UE_TYPE_NAME = {
|
||||
UE_STANDARD: "Standard",
|
||||
UE_SPORT: "Sport/Culture (points bonus)",
|
||||
@ -104,8 +93,6 @@ UE_TYPE_NAME = {
|
||||
UE_ELECTIVE: "Elective (ISCID)",
|
||||
UE_PROFESSIONNELLE: "Professionnelle (ISCID)",
|
||||
UE_OPTIONNELLE: "Optionnelle",
|
||||
# UE_FONDAMENTALE : '"Fondamentale" (eg UCAC)',
|
||||
# UE_OPTIONNELLE : '"Optionnelle" (UCAC)'
|
||||
}
|
||||
|
||||
# Couleurs RGB (dans [0.,1.]) des UE pour les bulletins:
|
||||
|
@ -191,7 +191,23 @@ def do_formsemestre_inscription_edit(args=None, formsemestre_id=None):
|
||||
) # > modif inscription semestre
|
||||
|
||||
|
||||
def do_formsemestre_desinscription(etudid, formsemestre_id):
|
||||
def check_if_has_decision_jury(
|
||||
formsemestre: FormSemestre, etudids: list[int] | set[int]
|
||||
):
|
||||
"raise exception if one of the etuds has a decision in formsemestre"
|
||||
nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
|
||||
for etudid in etudids:
|
||||
if nt.etud_has_decision(etudid):
|
||||
etud = Identite.query.get(etudid)
|
||||
raise ScoValueError(
|
||||
f"""désinscription impossible: l'étudiant {etud.nomprenom} a
|
||||
une décision de jury (la supprimer avant si nécessaire)"""
|
||||
)
|
||||
|
||||
|
||||
def do_formsemestre_desinscription(
|
||||
etudid, formsemestre_id: int, check_has_dec_jury=True
|
||||
):
|
||||
"""Désinscription d'un étudiant.
|
||||
Si semestre extérieur et dernier inscrit, suppression de ce semestre.
|
||||
"""
|
||||
@ -204,13 +220,8 @@ def do_formsemestre_desinscription(etudid, formsemestre_id):
|
||||
raise ScoValueError("désinscription impossible: semestre verrouille")
|
||||
|
||||
# -- Si decisions de jury, désinscription interdite
|
||||
nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
|
||||
|
||||
if nt.etud_has_decision(etudid):
|
||||
raise ScoValueError(
|
||||
f"""désinscription impossible: l'étudiant {etud.nomprenom} a
|
||||
une décision de jury (la supprimer avant si nécessaire)"""
|
||||
)
|
||||
if check_has_dec_jury:
|
||||
check_if_has_decision_jury(formsemestre, [etudid])
|
||||
|
||||
insem = do_formsemestre_inscription_list(
|
||||
args={"formsemestre_id": formsemestre_id, "etudid": etudid}
|
||||
|
@ -36,13 +36,14 @@ from flask import url_for, g, request
|
||||
import app.scodoc.notesdb as ndb
|
||||
import app.scodoc.sco_utils as scu
|
||||
from app import db, log
|
||||
from app.models import Formation, FormSemestre, GroupDescr
|
||||
from app.comp import res_sem
|
||||
from app.comp.res_compat import NotesTableCompat
|
||||
from app.models import Formation, FormSemestre, GroupDescr, Identite
|
||||
from app.scodoc.gen_tables import GenTable
|
||||
from app.scodoc import html_sco_header
|
||||
from app.scodoc import sco_cache
|
||||
from app.scodoc import codes_cursus
|
||||
from app.scodoc import sco_etud
|
||||
from app.scodoc import sco_formsemestre
|
||||
from app.scodoc import sco_formsemestre_inscriptions
|
||||
from app.scodoc import sco_groups
|
||||
from app.scodoc import sco_preferences
|
||||
@ -50,62 +51,69 @@ from app.scodoc import sco_pv_dict
|
||||
from app.scodoc.sco_exceptions import ScoValueError
|
||||
|
||||
|
||||
def list_authorized_etuds_by_sem(sem, delai=274, ignore_jury=False):
|
||||
def _list_authorized_etuds_by_sem(
|
||||
formsemestre: FormSemestre, ignore_jury=False
|
||||
) -> tuple[dict[int, dict], list[dict], dict[int, Identite]]:
|
||||
"""Liste des etudiants autorisés à s'inscrire dans sem.
|
||||
delai = nb de jours max entre la date de l'autorisation et celle de debut du semestre cible.
|
||||
ignore_jury: si vrai, considère tous les étudiants comme autorisés, même
|
||||
s'ils n'ont pas de décision de jury.
|
||||
"""
|
||||
src_sems = list_source_sems(sem, delai=delai)
|
||||
inscrits = list_inscrits(sem["formsemestre_id"])
|
||||
src_sems = _list_source_sems(formsemestre)
|
||||
inscrits = list_inscrits(formsemestre.id)
|
||||
r = {}
|
||||
candidats = {} # etudid : etud (tous les etudiants candidats)
|
||||
nb = 0 # debug
|
||||
for src in src_sems:
|
||||
src_formsemestre: FormSemestre
|
||||
for src_formsemestre in src_sems:
|
||||
if ignore_jury:
|
||||
# liste de tous les inscrits au semestre (sans dems)
|
||||
liste = list_inscrits(src["formsemestre_id"]).values()
|
||||
etud_list = list_inscrits(formsemestre.id).values()
|
||||
else:
|
||||
# liste des étudiants autorisés par le jury à s'inscrire ici
|
||||
liste = list_etuds_from_sem(src, sem)
|
||||
etud_list = _list_etuds_from_sem(src_formsemestre, formsemestre)
|
||||
liste_filtree = []
|
||||
for e in liste:
|
||||
for e in etud_list:
|
||||
# Filtre ceux qui se sont déjà inscrit dans un semestre APRES le semestre src
|
||||
auth_used = False # autorisation deja utilisée ?
|
||||
etud = sco_etud.get_etud_info(etudid=e["etudid"], filled=True)[0]
|
||||
for isem in etud["sems"]:
|
||||
if ndb.DateDMYtoISO(isem["date_debut"]) >= ndb.DateDMYtoISO(
|
||||
src["date_fin"]
|
||||
):
|
||||
etud = Identite.get_etud(e["etudid"])
|
||||
for inscription in etud.inscriptions():
|
||||
if inscription.formsemestre.date_debut >= src_formsemestre.date_fin:
|
||||
auth_used = True
|
||||
if not auth_used:
|
||||
candidats[e["etudid"]] = etud
|
||||
liste_filtree.append(e)
|
||||
nb += 1
|
||||
r[src["formsemestre_id"]] = {
|
||||
r[src_formsemestre.id] = {
|
||||
"etuds": liste_filtree,
|
||||
"infos": {
|
||||
"id": src["formsemestre_id"],
|
||||
"title": src["titreannee"],
|
||||
"title_target": "formsemestre_status?formsemestre_id=%s"
|
||||
% src["formsemestre_id"],
|
||||
"id": src_formsemestre.id,
|
||||
"title": src_formsemestre.titre_annee(),
|
||||
"title_target": url_for(
|
||||
"notes.formsemestre_status",
|
||||
scodoc_dept=g.scodoc_dept,
|
||||
formsemestre_id=src_formsemestre.id,
|
||||
),
|
||||
"filename": "etud_autorises",
|
||||
},
|
||||
}
|
||||
# ajoute attribut inscrit qui indique si l'étudiant est déjà inscrit dans le semestre dest.
|
||||
for e in r[src["formsemestre_id"]]["etuds"]:
|
||||
for e in r[src_formsemestre.id]["etuds"]:
|
||||
e["inscrit"] = e["etudid"] in inscrits
|
||||
|
||||
# Ajoute liste des etudiants actuellement inscrits
|
||||
for e in inscrits.values():
|
||||
e["inscrit"] = True
|
||||
r[sem["formsemestre_id"]] = {
|
||||
r[formsemestre.id] = {
|
||||
"etuds": list(inscrits.values()),
|
||||
"infos": {
|
||||
"id": sem["formsemestre_id"],
|
||||
"title": "Semestre cible: " + sem["titreannee"],
|
||||
"title_target": "formsemestre_status?formsemestre_id=%s"
|
||||
% sem["formsemestre_id"],
|
||||
"id": formsemestre.id,
|
||||
"title": "Semestre cible: " + formsemestre.titre_annee(),
|
||||
"title_target": url_for(
|
||||
"notes.formsemestre_status",
|
||||
scodoc_dept=g.scodoc_dept,
|
||||
formsemestre_id=formsemestre.id,
|
||||
),
|
||||
"comment": " actuellement inscrits dans ce semestre",
|
||||
"help": "Ces étudiants sont actuellement inscrits dans ce semestre. Si vous les décochez, il seront désinscrits.",
|
||||
"filename": "etud_inscrits",
|
||||
@ -115,7 +123,7 @@ def list_authorized_etuds_by_sem(sem, delai=274, ignore_jury=False):
|
||||
return r, inscrits, candidats
|
||||
|
||||
|
||||
def list_inscrits(formsemestre_id, with_dems=False):
|
||||
def list_inscrits(formsemestre_id: int, with_dems=False) -> list[dict]:
|
||||
"""Étudiants déjà inscrits à ce semestre
|
||||
{ etudid : etud }
|
||||
"""
|
||||
@ -133,28 +141,27 @@ def list_inscrits(formsemestre_id, with_dems=False):
|
||||
return inscr
|
||||
|
||||
|
||||
def list_etuds_from_sem(src, dst) -> list[dict]:
|
||||
"""Liste des etudiants du semestre src qui sont autorisés à passer dans le semestre dst."""
|
||||
target = dst["semestre_id"]
|
||||
dpv = sco_pv_dict.dict_pvjury(src["formsemestre_id"])
|
||||
def _list_etuds_from_sem(src: FormSemestre, dst: FormSemestre) -> list[dict]:
|
||||
"""Liste des étudiants du semestre src qui sont autorisés à passer dans le semestre dst."""
|
||||
target_semestre_id = dst.semestre_id
|
||||
dpv = sco_pv_dict.dict_pvjury(src.id)
|
||||
if not dpv:
|
||||
return []
|
||||
etuds = [
|
||||
x["identite"]
|
||||
for x in dpv["decisions"]
|
||||
if target in [a["semestre_id"] for a in x["autorisations"]]
|
||||
if target_semestre_id in [a["semestre_id"] for a in x["autorisations"]]
|
||||
]
|
||||
return etuds
|
||||
|
||||
|
||||
def list_inscrits_date(sem):
|
||||
"""Liste les etudiants inscrits dans n'importe quel semestre
|
||||
du même département
|
||||
SAUF sem à la date de début de sem.
|
||||
def list_inscrits_date(formsemestre: FormSemestre):
|
||||
"""Liste les etudiants inscrits à la date de début de formsemestre
|
||||
dans n'importe quel semestre du même département
|
||||
SAUF formsemestre
|
||||
"""
|
||||
cnx = ndb.GetDBConnexion()
|
||||
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
|
||||
sem["date_debut_iso"] = ndb.DateDMYtoISO(sem["date_debut"])
|
||||
cursor.execute(
|
||||
"""SELECT ins.etudid
|
||||
FROM
|
||||
@ -166,12 +173,18 @@ def list_inscrits_date(sem):
|
||||
AND S.date_fin >= %(date_debut_iso)s
|
||||
AND S.dept_id = %(dept_id)s
|
||||
""",
|
||||
sem,
|
||||
{
|
||||
"formsemestre_id": formsemestre.id,
|
||||
"date_debut_iso": formsemestre.date_debut.isoformat(),
|
||||
"dept_id": formsemestre.dept_id,
|
||||
},
|
||||
)
|
||||
return [x[0] for x in cursor.fetchall()]
|
||||
|
||||
|
||||
def do_inscrit(sem, etudids, inscrit_groupes=False, inscrit_parcours=False):
|
||||
def do_inscrit(
|
||||
formsemestre: FormSemestre, etudids, inscrit_groupes=False, inscrit_parcours=False
|
||||
):
|
||||
"""Inscrit ces etudiants dans ce semestre
|
||||
(la liste doit avoir été vérifiée au préalable)
|
||||
En option:
|
||||
@ -181,12 +194,11 @@ def do_inscrit(sem, etudids, inscrit_groupes=False, inscrit_parcours=False):
|
||||
(si les deux sont vrais, inscrit_parcours n'a pas d'effet)
|
||||
"""
|
||||
# TODO à ré-écrire pour utiliser les modèles, notamment GroupDescr
|
||||
formsemestre: FormSemestre = db.session.get(FormSemestre, sem["formsemestre_id"])
|
||||
formsemestre.setup_parcours_groups()
|
||||
log(f"do_inscrit (inscrit_groupes={inscrit_groupes}): {etudids}")
|
||||
for etudid in etudids:
|
||||
sco_formsemestre_inscriptions.do_formsemestre_inscription_with_modules(
|
||||
sem["formsemestre_id"],
|
||||
formsemestre.id,
|
||||
etudid,
|
||||
etat=scu.INSCRIT,
|
||||
method="formsemestre_inscr_passage",
|
||||
@ -210,7 +222,7 @@ def do_inscrit(sem, etudids, inscrit_groupes=False, inscrit_parcours=False):
|
||||
|
||||
cursem_groups_by_name = {
|
||||
g["group_name"]: g
|
||||
for g in sco_groups.get_sem_groups(sem["formsemestre_id"])
|
||||
for g in sco_groups.get_sem_groups(formsemestre.id)
|
||||
if g["group_name"]
|
||||
}
|
||||
|
||||
@ -234,53 +246,46 @@ def do_inscrit(sem, etudids, inscrit_groupes=False, inscrit_parcours=False):
|
||||
sco_groups.change_etud_group_in_partition(etudid, group)
|
||||
|
||||
|
||||
def do_desinscrit(sem: dict, etudids: list[int]):
|
||||
def do_desinscrit(
|
||||
formsemestre: FormSemestre, etudids: list[int], check_has_dec_jury=True
|
||||
):
|
||||
"désinscrit les étudiants indiqués du formsemestre"
|
||||
log(f"do_desinscrit: {etudids}")
|
||||
for etudid in etudids:
|
||||
sco_formsemestre_inscriptions.do_formsemestre_desinscription(
|
||||
etudid, sem["formsemestre_id"]
|
||||
etudid, formsemestre.id, check_has_dec_jury=check_has_dec_jury
|
||||
)
|
||||
|
||||
|
||||
def list_source_sems(sem, delai=None) -> list[dict]:
|
||||
def _list_source_sems(formsemestre: FormSemestre) -> list[FormSemestre]:
|
||||
"""Liste des semestres sources
|
||||
sem est le semestre destination
|
||||
formsemestre est le semestre destination
|
||||
"""
|
||||
# liste des semestres débutant a moins
|
||||
# de delai (en jours) de la date de fin du semestre d'origine.
|
||||
sems = sco_formsemestre.do_formsemestre_list()
|
||||
othersems = []
|
||||
d, m, y = [int(x) for x in sem["date_debut"].split("/")]
|
||||
date_debut_dst = datetime.date(y, m, d)
|
||||
|
||||
delais = datetime.timedelta(delai)
|
||||
for s in sems:
|
||||
if s["formsemestre_id"] == sem["formsemestre_id"]:
|
||||
continue # saute le semestre destination
|
||||
if s["date_fin"]:
|
||||
d, m, y = [int(x) for x in s["date_fin"].split("/")]
|
||||
date_fin = datetime.date(y, m, d)
|
||||
if date_debut_dst - date_fin > delais:
|
||||
continue # semestre trop ancien
|
||||
if date_fin > date_debut_dst:
|
||||
continue # semestre trop récent
|
||||
# Elimine les semestres de formations speciales (sans parcours)
|
||||
if s["semestre_id"] == codes_cursus.NO_SEMESTRE_ID:
|
||||
continue
|
||||
#
|
||||
formation: Formation = Formation.query.get_or_404(s["formation_id"])
|
||||
parcours = codes_cursus.get_cursus_from_code(formation.type_parcours)
|
||||
if not parcours.ALLOW_SEM_SKIP:
|
||||
if s["semestre_id"] < (sem["semestre_id"] - 1):
|
||||
continue
|
||||
othersems.append(s)
|
||||
return othersems
|
||||
# liste des semestres du même type de cursus terminant
|
||||
# pas trop loin de la date de début du semestre destination
|
||||
date_fin_min = formsemestre.date_debut - datetime.timedelta(days=275)
|
||||
date_fin_max = formsemestre.date_debut + datetime.timedelta(days=45)
|
||||
return (
|
||||
FormSemestre.query.filter(
|
||||
FormSemestre.dept_id == formsemestre.dept_id,
|
||||
# saute le semestre destination:
|
||||
FormSemestre.id != formsemestre.id,
|
||||
# et les semestres de formations speciales (monosemestres):
|
||||
FormSemestre.semestre_id != codes_cursus.NO_SEMESTRE_ID,
|
||||
# semestre pas trop dans le futur
|
||||
FormSemestre.date_fin <= date_fin_max,
|
||||
# ni trop loin dans le passé
|
||||
FormSemestre.date_fin >= date_fin_min,
|
||||
)
|
||||
.join(Formation)
|
||||
.filter_by(type_parcours=formsemestre.formation.type_parcours)
|
||||
).all()
|
||||
|
||||
|
||||
# view, GET, POST
|
||||
def formsemestre_inscr_passage(
|
||||
formsemestre_id,
|
||||
etuds=[],
|
||||
etuds: str | list[int] | list[str] | int | None = None,
|
||||
inscrit_groupes=False,
|
||||
inscrit_parcours=False,
|
||||
submitted=False,
|
||||
@ -300,36 +305,41 @@ def formsemestre_inscr_passage(
|
||||
- Confirmation: indiquer les étudiants inscrits et ceux désinscrits, le total courant.
|
||||
|
||||
"""
|
||||
formsemestre = FormSemestre.get_formsemestre(formsemestre_id)
|
||||
inscrit_groupes = int(inscrit_groupes)
|
||||
inscrit_parcours = int(inscrit_parcours)
|
||||
ignore_jury = int(ignore_jury)
|
||||
sem = sco_formsemestre.get_formsemestre(formsemestre_id)
|
||||
# -- check lock
|
||||
if not sem["etat"]:
|
||||
if not formsemestre.etat:
|
||||
raise ScoValueError("opération impossible: semestre verrouille")
|
||||
header = html_sco_header.sco_header(page_title="Passage des étudiants")
|
||||
header = html_sco_header.sco_header(
|
||||
page_title="Passage des étudiants",
|
||||
init_qtip=True,
|
||||
javascripts=["js/etud_info.js"],
|
||||
)
|
||||
footer = html_sco_header.sco_footer()
|
||||
H = [header]
|
||||
etuds = [] if etuds is None else etuds
|
||||
if isinstance(etuds, str):
|
||||
# list de strings, vient du form de confirmation
|
||||
# string, vient du form de confirmation
|
||||
etuds = [int(x) for x in etuds.split(",") if x]
|
||||
elif isinstance(etuds, int):
|
||||
etuds = [etuds]
|
||||
elif etuds and isinstance(etuds[0], str):
|
||||
etuds = [int(x) for x in etuds]
|
||||
|
||||
auth_etuds_by_sem, inscrits, candidats = list_authorized_etuds_by_sem(
|
||||
sem, ignore_jury=ignore_jury
|
||||
auth_etuds_by_sem, inscrits, candidats = _list_authorized_etuds_by_sem(
|
||||
formsemestre, ignore_jury=ignore_jury
|
||||
)
|
||||
etuds_set = set(etuds)
|
||||
candidats_set = set(candidats)
|
||||
inscrits_set = set(inscrits)
|
||||
candidats_non_inscrits = candidats_set - inscrits_set
|
||||
inscrits_ailleurs = set(list_inscrits_date(sem))
|
||||
inscrits_ailleurs = set(list_inscrits_date(formsemestre))
|
||||
|
||||
def set_to_sorted_etud_list(etudset):
|
||||
def set_to_sorted_etud_list(etudset) -> list[Identite]:
|
||||
etuds = [candidats[etudid] for etudid in etudset]
|
||||
etuds.sort(key=itemgetter("nom"))
|
||||
etuds.sort(key=lambda e: e.sort_key)
|
||||
return etuds
|
||||
|
||||
if submitted:
|
||||
@ -340,7 +350,7 @@ def formsemestre_inscr_passage(
|
||||
|
||||
if not submitted:
|
||||
H += _build_page(
|
||||
sem,
|
||||
formsemestre,
|
||||
auth_etuds_by_sem,
|
||||
inscrits,
|
||||
candidats_non_inscrits,
|
||||
@ -355,30 +365,31 @@ def formsemestre_inscr_passage(
|
||||
if a_inscrire:
|
||||
H.append("<h3>Étudiants à inscrire</h3><ol>")
|
||||
for etud in set_to_sorted_etud_list(a_inscrire):
|
||||
H.append("<li>%(nomprenom)s</li>" % etud)
|
||||
H.append(f"<li>{etud.nomprenom}</li>")
|
||||
H.append("</ol>")
|
||||
a_inscrire_en_double = inscrits_ailleurs.intersection(a_inscrire)
|
||||
if a_inscrire_en_double:
|
||||
H.append("<h3>dont étudiants déjà inscrits:</h3><ul>")
|
||||
for etud in set_to_sorted_etud_list(a_inscrire_en_double):
|
||||
H.append('<li class="inscrailleurs">%(nomprenom)s</li>' % etud)
|
||||
H.append(f'<li class="inscrit-ailleurs">{etud.nomprenom}</li>')
|
||||
H.append("</ul>")
|
||||
if a_desinscrire:
|
||||
H.append("<h3>Étudiants à désinscrire</h3><ol>")
|
||||
for etudid in a_desinscrire:
|
||||
H.append(
|
||||
'<li class="desinscription">%(nomprenom)s</li>'
|
||||
% inscrits[etudid]
|
||||
a_desinscrire_ident = sorted(
|
||||
(Identite.query.get(eid) for eid in a_desinscrire),
|
||||
key=lambda x: x.sort_key,
|
||||
)
|
||||
for etud in a_desinscrire_ident:
|
||||
H.append(f'<li class="desinscription">{etud.nomprenom}</li>')
|
||||
H.append("</ol>")
|
||||
todo = a_inscrire or a_desinscrire
|
||||
if not todo:
|
||||
H.append("""<h3>Il n'y a rien à modifier !</h3>""")
|
||||
H.append(
|
||||
scu.confirm_dialog(
|
||||
dest_url="formsemestre_inscr_passage"
|
||||
if todo
|
||||
else "formsemestre_status",
|
||||
dest_url=(
|
||||
"formsemestre_inscr_passage" if todo else "formsemestre_status"
|
||||
),
|
||||
message="<p>Confirmer ?</p>" if todo else "",
|
||||
add_headers=False,
|
||||
cancel_url="formsemestre_inscr_passage?formsemestre_id="
|
||||
@ -395,16 +406,26 @@ def formsemestre_inscr_passage(
|
||||
)
|
||||
)
|
||||
else:
|
||||
# check decisions jury ici pour éviter de recontruire le cache
|
||||
# après chaque desinscription
|
||||
sco_formsemestre_inscriptions.check_if_has_decision_jury(
|
||||
formsemestre, a_desinscrire
|
||||
)
|
||||
# check decisions jury ici pour éviter de recontruire le cache
|
||||
# après chaque desinscription
|
||||
sco_formsemestre_inscriptions.check_if_has_decision_jury(
|
||||
formsemestre, a_desinscrire
|
||||
)
|
||||
with sco_cache.DeferredSemCacheManager():
|
||||
# Inscription des étudiants au nouveau semestre:
|
||||
do_inscrit(
|
||||
sem,
|
||||
formsemestre,
|
||||
a_inscrire,
|
||||
inscrit_groupes=inscrit_groupes,
|
||||
inscrit_parcours=inscrit_parcours,
|
||||
)
|
||||
# Désinscriptions:
|
||||
do_desinscrit(sem, a_desinscrire)
|
||||
do_desinscrit(formsemestre, a_desinscrire, check_has_dec_jury=False)
|
||||
|
||||
H.append(
|
||||
f"""<h3>Opération effectuée</h3>
|
||||
@ -441,7 +462,7 @@ def formsemestre_inscr_passage(
|
||||
|
||||
|
||||
def _build_page(
|
||||
sem,
|
||||
formsemestre: FormSemestre,
|
||||
auth_etuds_by_sem,
|
||||
inscrits,
|
||||
candidats_non_inscrits,
|
||||
@ -450,7 +471,6 @@ def _build_page(
|
||||
inscrit_parcours=False,
|
||||
ignore_jury=False,
|
||||
):
|
||||
formsemestre: FormSemestre = db.session.get(FormSemestre, sem["formsemestre_id"])
|
||||
inscrit_groupes = int(inscrit_groupes)
|
||||
inscrit_parcours = int(inscrit_parcours)
|
||||
ignore_jury = int(ignore_jury)
|
||||
@ -472,7 +492,7 @@ def _build_page(
|
||||
),
|
||||
f"""<form name="f" method="post" action="{request.base_url}">
|
||||
|
||||
<input type="hidden" name="formsemestre_id" value="{sem['formsemestre_id']}"/>
|
||||
<input type="hidden" name="formsemestre_id" value="{formsemestre.id}"/>
|
||||
|
||||
<input type="submit" name="submitted" value="Appliquer les modifications"/>
|
||||
<a href="#help">aide</a>
|
||||
@ -491,7 +511,7 @@ def _build_page(
|
||||
</div>
|
||||
|
||||
<div>{scu.EMO_WARNING}
|
||||
<em>Seuls les semestres dont la date de fin est antérieure à la date de début
|
||||
<em>Seuls les semestres dont la date de fin est proche de la date de début
|
||||
de ce semestre ({formsemestre.date_debut.strftime("%d/%m/%Y")}) sont pris en
|
||||
compte.</em>
|
||||
</div>
|
||||
@ -499,7 +519,7 @@ def _build_page(
|
||||
|
||||
<input type="submit" name="submitted" value="Appliquer les modifications"/>
|
||||
|
||||
{formsemestre_inscr_passage_help(sem)}
|
||||
{formsemestre_inscr_passage_help(formsemestre)}
|
||||
|
||||
</form>
|
||||
""",
|
||||
@ -524,19 +544,20 @@ def _build_page(
|
||||
return H
|
||||
|
||||
|
||||
def formsemestre_inscr_passage_help(sem: dict):
|
||||
def formsemestre_inscr_passage_help(formsemestre: FormSemestre):
|
||||
"texte d'aide en bas de la page passage des étudiants"
|
||||
return f"""<div class="pas_help"><h3><a name="help">Explications</a></h3>
|
||||
<p>Cette page permet d'inscrire des étudiants dans le semestre destination
|
||||
<a class="stdlink"
|
||||
href="{
|
||||
url_for("notes.formsemestre_status", scodoc_dept=g.scodoc_dept, formsemestre_id=sem["formsemestre_id"] )
|
||||
}">{sem['titreannee']}</a>,
|
||||
url_for("notes.formsemestre_status",
|
||||
scodoc_dept=g.scodoc_dept, formsemestre_id=formsemestre.id )
|
||||
}">{formsemestre.titre_annee()}</a>,
|
||||
et d'en désincrire si besoin.
|
||||
</p>
|
||||
<p>Les étudiants sont groupés par semestre d'origine. Ceux qui sont en caractères
|
||||
<span class="inscrit">gras</span> sont déjà inscrits dans le semestre destination.
|
||||
Ceux qui sont en <span class"inscrailleurs">gras et en rouge</span> sont inscrits
|
||||
<span class="deja-inscrit">gras</span> sont déjà inscrits dans le semestre destination.
|
||||
Ceux qui sont en <span class="inscrit-ailleurs">gras et en rouge</span> sont inscrits
|
||||
dans un <em>autre</em> semestre.
|
||||
</p>
|
||||
<p>Au départ, les étudiants déjà inscrits sont sélectionnés; vous pouvez ajouter
|
||||
@ -555,7 +576,7 @@ def formsemestre_inscr_passage_help(sem: dict):
|
||||
conserve les groupes, on conserve les parcours (là aussi, pensez à les cocher dans
|
||||
<a class="stdlink" href="{
|
||||
url_for("notes.formsemestre_editwithmodules", scodoc_dept=g.scodoc_dept,
|
||||
formsemestre_id=sem["formsemestre_id"] )
|
||||
formsemestre_id=formsemestre.id )
|
||||
}">modifier le semestre</a> avant de faire passer les étudiants).
|
||||
</a>
|
||||
|
||||
@ -656,25 +677,24 @@ def etuds_select_boxes(
|
||||
H.append("</div>")
|
||||
for etud in etuds:
|
||||
if etud.get("inscrit", False):
|
||||
c = " inscrit"
|
||||
c = " deja-inscrit"
|
||||
checked = 'checked="checked"'
|
||||
else:
|
||||
checked = ""
|
||||
if etud["etudid"] in inscrits_ailleurs:
|
||||
c = " inscrailleurs"
|
||||
c = " inscrit-ailleurs"
|
||||
else:
|
||||
c = ""
|
||||
sco_etud.format_etud_ident(etud)
|
||||
if etud["etudid"]:
|
||||
elink = """<a class="discretelink %s" href="%s">%s</a>""" % (
|
||||
c,
|
||||
url_for(
|
||||
"scolar.fiche_etud",
|
||||
elink = f"""<a id="{etud['etudid']}" class="discretelink etudinfo {c}"
|
||||
href="{ url_for(
|
||||
'scolar.fiche_etud',
|
||||
scodoc_dept=g.scodoc_dept,
|
||||
etudid=etud["etudid"],
|
||||
),
|
||||
etud["nomprenom"],
|
||||
etudid=etud['etudid'],
|
||||
)
|
||||
}">{etud['nomprenom']}</a>
|
||||
"""
|
||||
else:
|
||||
# ce n'est pas un etudiant ScoDoc
|
||||
elink = etud["nomprenom"]
|
||||
|
@ -35,7 +35,7 @@ from flask import g, url_for
|
||||
from flask_login import current_user
|
||||
|
||||
from app import db, log
|
||||
from app.models import Admission, Adresse, Identite, ScolarNews
|
||||
from app.models import Admission, Adresse, FormSemestre, Identite, ScolarNews
|
||||
|
||||
import app.scodoc.sco_utils as scu
|
||||
import app.scodoc.notesdb as ndb
|
||||
@ -94,6 +94,7 @@ def formsemestre_synchro_etuds(
|
||||
que l'on va importer/inscrire
|
||||
"""
|
||||
etuds = etuds or []
|
||||
formsemestre = FormSemestre.get_formsemestre(formsemestre_id)
|
||||
inscrits_without_key = inscrits_without_key or []
|
||||
log(f"formsemestre_synchro_etuds: formsemestre_id={formsemestre_id}")
|
||||
sem = sco_formsemestre.get_formsemestre(formsemestre_id)
|
||||
@ -184,7 +185,7 @@ def formsemestre_synchro_etuds(
|
||||
inscrits_without_key
|
||||
)
|
||||
log("a_desinscrire_without_key=%s" % a_desinscrire_without_key)
|
||||
inscrits_ailleurs = set(sco_inscr_passage.list_inscrits_date(sem))
|
||||
inscrits_ailleurs = set(sco_inscr_passage.list_inscrits_date(formsemestre))
|
||||
a_inscrire = a_inscrire.intersection(etuds_set)
|
||||
|
||||
if not dialog_confirmed:
|
||||
@ -205,10 +206,12 @@ def formsemestre_synchro_etuds(
|
||||
|
||||
a_inscrire_en_double = inscrits_ailleurs.intersection(a_inscrire)
|
||||
if a_inscrire_en_double:
|
||||
H.append("<h3>dont étudiants déjà inscrits:</h3><ol>")
|
||||
H.append(
|
||||
"<h3>dont étudiants déjà inscrits dans un autre semestre:</h3><ol>"
|
||||
)
|
||||
for key in a_inscrire_en_double:
|
||||
nom = f"""{etudsapo_ident[key]['nom']} {etudsapo_ident[key].get("prenom", "")}"""
|
||||
H.append(f'<li class="inscrailleurs">{nom}</li>')
|
||||
H.append(f'<li class="inscrit-ailleurs">{nom}</li>')
|
||||
H.append("</ol>")
|
||||
|
||||
if a_desinscrire:
|
||||
@ -260,16 +263,26 @@ def formsemestre_synchro_etuds(
|
||||
etudids_a_desinscrire = [nip2etudid(x) for x in a_desinscrire]
|
||||
etudids_a_desinscrire += a_desinscrire_without_key
|
||||
#
|
||||
# check decisions jury ici pour éviter de recontruire le cache
|
||||
# après chaque desinscription
|
||||
sco_formsemestre_inscriptions.check_if_has_decision_jury(
|
||||
formsemestre, a_desinscrire
|
||||
)
|
||||
with sco_cache.DeferredSemCacheManager():
|
||||
do_import_etuds_from_portal(sem, a_importer, etudsapo_ident)
|
||||
sco_inscr_passage.do_inscrit(sem, etudids_a_inscrire)
|
||||
sco_inscr_passage.do_desinscrit(sem, etudids_a_desinscrire)
|
||||
do_import_etuds_from_portal(formsemestre, a_importer, etudsapo_ident)
|
||||
sco_inscr_passage.do_inscrit(formsemestre, etudids_a_inscrire)
|
||||
sco_inscr_passage.do_desinscrit(
|
||||
formsemestre, etudids_a_desinscrire, check_has_dec_jury=False
|
||||
)
|
||||
|
||||
H.append(
|
||||
"""<h3>Opération effectuée</h3>
|
||||
f"""<h3>Opération effectuée</h3>
|
||||
<ul>
|
||||
<li><a class="stdlink" href="formsemestre_synchro_etuds?formsemestre_id=%s">Continuer la synchronisation</a></li>"""
|
||||
% formsemestre_id
|
||||
<li><a class="stdlink" href="{
|
||||
url_for('notes.formsemestre_synchro_etuds',
|
||||
scodoc_dept=g.scodoc_dept, formsemestre_id=formsemestre_id
|
||||
)}">Continuer la synchronisation</a>
|
||||
</li>"""
|
||||
)
|
||||
#
|
||||
partitions = sco_groups.get_partitions_list(
|
||||
@ -279,8 +292,9 @@ def formsemestre_synchro_etuds(
|
||||
H.append(
|
||||
f"""<li><a class="stdlink" href="{
|
||||
url_for("scolar.partition_editor",
|
||||
scodoc_dept=g.scodoc_dept, formsemestre_id=formsemestre_id)
|
||||
}">Répartir les groupes de {partitions[0]["partition_name"]}</a></li>
|
||||
scodoc_dept=g.scodoc_dept, formsemestre_id=formsemestre_id
|
||||
)}">Répartir les groupes de {partitions[0]["partition_name"]}</a>
|
||||
</li>
|
||||
"""
|
||||
)
|
||||
|
||||
@ -618,7 +632,7 @@ def get_annee_naissance(ddmmyyyyy: str) -> int:
|
||||
return None
|
||||
|
||||
|
||||
def do_import_etuds_from_portal(sem, a_importer, etudsapo_ident):
|
||||
def do_import_etuds_from_portal(formsemestre: FormSemestre, a_importer, etudsapo_ident):
|
||||
"""Inscrit les etudiants Apogee dans ce semestre."""
|
||||
log(f"do_import_etuds_from_portal: a_importer={a_importer}")
|
||||
if not a_importer:
|
||||
@ -672,7 +686,7 @@ def do_import_etuds_from_portal(sem, a_importer, etudsapo_ident):
|
||||
|
||||
# Inscription au semestre
|
||||
sco_formsemestre_inscriptions.do_formsemestre_inscription_with_modules(
|
||||
sem["formsemestre_id"],
|
||||
formsemestre.id,
|
||||
etud.id,
|
||||
etat=scu.INSCRIT,
|
||||
etape=args["etape"],
|
||||
@ -716,7 +730,7 @@ def do_import_etuds_from_portal(sem, a_importer, etudsapo_ident):
|
||||
ScolarNews.add(
|
||||
typ=ScolarNews.NEWS_INSCR,
|
||||
text=f"Import Apogée de {len(created_etudids)} étudiants en ",
|
||||
obj=sem["formsemestre_id"],
|
||||
obj=formsemestre.id,
|
||||
)
|
||||
|
||||
|
||||
|
@ -3714,10 +3714,17 @@ span.sp_etape {
|
||||
color: black;
|
||||
}
|
||||
|
||||
.inscrailleurs {
|
||||
.deja-inscrit {
|
||||
font-weight: bold;
|
||||
color: rgb(1, 76, 1) !important;
|
||||
}
|
||||
.inscrit-ailleurs {
|
||||
font-weight: bold;
|
||||
color: red !important;
|
||||
}
|
||||
div.etuds_select_boxes {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
span.paspaye,
|
||||
span.paspaye a {
|
||||
|
Loading…
Reference in New Issue
Block a user