forked from ScoDoc/ScoDoc
WIP: jury BUT: prise en compte des UE capitalisées dans les RCUEs
This commit is contained in:
parent
06caacbb47
commit
386471a47f
@ -383,43 +383,47 @@ class DecisionsProposeesAnnee(DecisionsProposees):
|
||||
#
|
||||
|
||||
def infos(self) -> str:
|
||||
"informations, for debugging purpose"
|
||||
return f"""<b>DecisionsProposeesAnnee</b>
|
||||
"""informations, for debugging purpose."""
|
||||
text = f"""<b>DecisionsProposeesAnnee</b>
|
||||
<ul>
|
||||
<li>Etudiant: <a href="{url_for("scolar.ficheEtud",
|
||||
scodoc_dept=g.scodoc_dept, etudid=self.etud.id)
|
||||
}">{self.etud.nomprenom}</a>
|
||||
</li>
|
||||
<li>formsemestre_impair: <a href="{url_for("notes.formsemestre_status",
|
||||
scodoc_dept=g.scodoc_dept, formsemestre_id=self.formsemestre_impair.id)
|
||||
}">{html.escape(str(self.formsemestre_impair))}</a>
|
||||
<ul>
|
||||
<li>Formation: <a href="{url_for('notes.ue_table', scodoc_dept=g.scodoc_dept,
|
||||
semestre_idx=self.formsemestre_impair.semestre_id,
|
||||
formation_id=self.formsemestre_impair.formation.id)}">
|
||||
{self.formsemestre_impair.formation.to_html()} ({self.formsemestre_impair.formation.id})</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>formsemestre_pair: <a href="{url_for("notes.formsemestre_status",
|
||||
scodoc_dept=g.scodoc_dept, formsemestre_id=self.formsemestre_pair.id)
|
||||
}">{html.escape(str(self.formsemestre_pair))}</a>
|
||||
<ul>
|
||||
<li>Formation: <a href="{url_for('notes.ue_table', scodoc_dept=g.scodoc_dept,
|
||||
semestre_idx=self.formsemestre_pair.semestre_id,
|
||||
formation_id=self.formsemestre_pair.formation.id)}">
|
||||
{self.formsemestre_pair.formation.to_html()} ({self.formsemestre_pair.formation.id})</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li>RCUEs: {html.escape(str(self.rcues_annee))}</li>
|
||||
<li>nb_competences: {getattr(self, "nb_competences", "-")}</li>
|
||||
<li>nb_validables: {getattr(self, "nb_validables", "-")}</li>
|
||||
<li>codes: {self.codes}</li>
|
||||
<li>explanation: {self.explanation}</li>
|
||||
</ul>
|
||||
"""
|
||||
for formsemestre, title in (
|
||||
(self.formsemestre_impair, "formsemestre_impair"),
|
||||
(self.formsemestre_pair, "formsemestre_pair"),
|
||||
):
|
||||
text += f"<li>{title}:"
|
||||
if formsemestre is not None:
|
||||
text += f"""
|
||||
<a href="{url_for("notes.formsemestre_status",
|
||||
scodoc_dept=g.scodoc_dept, formsemestre_id=formsemestre.id)
|
||||
}">{html.escape(str(formsemestre))}</a>
|
||||
<ul>
|
||||
<li>Formation: <a href="{url_for('notes.ue_table',
|
||||
scodoc_dept=g.scodoc_dept,
|
||||
semestre_idx=formsemestre.semestre_id,
|
||||
formation_id=formsemestre.formation.id)}">
|
||||
{formsemestre.formation.to_html()} ({
|
||||
formsemestre.formation.id})</a>
|
||||
</li>
|
||||
</ul>
|
||||
"""
|
||||
else:
|
||||
text += " aucun."
|
||||
text += "</li>"
|
||||
|
||||
text += f"""
|
||||
<li>RCUEs: {html.escape(str(self.rcues_annee))}</li>
|
||||
<li>nb_competences: {getattr(self, "nb_competences", "-")}</li>
|
||||
<li>nb_validables: {getattr(self, "nb_validables", "-")}</li>
|
||||
<li>codes: {self.codes}</li>
|
||||
<li>explanation: {self.explanation}</li>
|
||||
</ul>
|
||||
"""
|
||||
return text
|
||||
|
||||
def annee_scolaire(self) -> int:
|
||||
"L'année de début de l'année scolaire"
|
||||
@ -434,14 +438,19 @@ class DecisionsProposeesAnnee(DecisionsProposees):
|
||||
def comp_formsemestres(
|
||||
self, formsemestre: FormSemestre
|
||||
) -> tuple[FormSemestre, FormSemestre]:
|
||||
"""les deux formsemestres de l'année scolaire à laquelle appartient formsemestre."""
|
||||
"""Les deux formsemestres du niveau auquel appartient formsemestre.
|
||||
Complète le niveau avec le formsemestre antérieur le plus récent.
|
||||
L'"autre" formsemestre peut ainsi appartenir à l'année scolaire
|
||||
antérieure (redoublants).
|
||||
-> S_impair, S_pair
|
||||
"""
|
||||
if not formsemestre.formation.is_apc(): # garde fou
|
||||
return None, None
|
||||
if formsemestre.semestre_id % 2 == 0:
|
||||
other_semestre_id = formsemestre.semestre_id - 1
|
||||
else:
|
||||
other_semestre_id = formsemestre.semestre_id + 1
|
||||
annee_scolaire = formsemestre.annee_scolaire()
|
||||
|
||||
other_formsemestre = None
|
||||
for inscr in self.etud.formsemestre_inscriptions:
|
||||
if (
|
||||
@ -452,8 +461,13 @@ class DecisionsProposeesAnnee(DecisionsProposees):
|
||||
)
|
||||
# L'autre semestre
|
||||
and (inscr.formsemestre.semestre_id == other_semestre_id)
|
||||
# de la même année scolaire:
|
||||
and (inscr.formsemestre.annee_scolaire() == annee_scolaire)
|
||||
# Antérieur
|
||||
and inscr.formsemestre.date_debut < formsemestre.date_debut
|
||||
# Et plus le récent possible
|
||||
and (
|
||||
(other_formsemestre is None)
|
||||
or (other_formsemestre.date_debut < inscr.formsemestre.date_debut)
|
||||
)
|
||||
):
|
||||
other_formsemestre = inscr.formsemestre
|
||||
if formsemestre.semestre_id % 2 == 0:
|
||||
@ -512,9 +526,9 @@ class DecisionsProposeesAnnee(DecisionsProposees):
|
||||
rcue = RegroupementCoherentUE(
|
||||
self.etud,
|
||||
self.formsemestre_impair,
|
||||
ue_impair,
|
||||
self.decisions_ues[ue_impair.id],
|
||||
self.formsemestre_pair,
|
||||
ue_pair,
|
||||
self.decisions_ues[ue_pair.id],
|
||||
self.inscription_etat,
|
||||
)
|
||||
ues_impair_sans_rcue.discard(ue_impair.id)
|
||||
@ -976,18 +990,23 @@ class DecisionsProposeesUE(DecisionsProposees):
|
||||
self.codes = [
|
||||
sco_codes.DEM if inscription_etat == scu.DEMISSION else sco_codes.DEF
|
||||
]
|
||||
self.moy_ue = np.NaN
|
||||
self.moy_ue = self.moy_ue_with_cap = np.NaN
|
||||
self.ue_status = {}
|
||||
return
|
||||
|
||||
# Moyenne de l'UE ?
|
||||
res: ResultatsSemestreBUT = res_sem.load_formsemestre_results(formsemestre)
|
||||
# Safety checks:
|
||||
if not ue.id in res.etud_moy_ue:
|
||||
self.explanation = "UE sans résultat"
|
||||
return
|
||||
if not etud.id in res.etud_moy_ue[ue.id]:
|
||||
self.explanation = "Étudiant sans résultat dans cette UE"
|
||||
return
|
||||
self.moy_ue = res.etud_moy_ue[ue.id][etud.id]
|
||||
ue_status = res.get_etud_ue_status(etud.id, ue.id)
|
||||
self.moy_ue = ue_status["cur_moy_ue"]
|
||||
self.moy_ue_with_cap = ue_status["moy"]
|
||||
self.ue_status = ue_status
|
||||
|
||||
def set_rcue(self, rcue: RegroupementCoherentUE):
|
||||
"""Rattache cette UE à un RCUE. Cela peut modifier les codes
|
||||
|
@ -58,15 +58,15 @@ def formsemestre_saisie_jury_but(
|
||||
# DecisionsProposeesAnnee(etud, formsemestre2)
|
||||
# Pour le 1er etud, faire un check_ues_ready_jury(self) -> page d'erreur
|
||||
# -> rcue .ue_1, .ue_2 -> stroe moy ues, rcue.moy_rcue, etc
|
||||
if formsemestre2.semestre_id % 2 != 0:
|
||||
raise ScoValueError("Cette page ne fonctionne que sur les semestres pairs")
|
||||
# XXX if formsemestre2.semestre_id % 2 != 0:
|
||||
# raise ScoValueError("Cette page ne fonctionne que sur les semestres pairs")
|
||||
|
||||
if formsemestre2.formation.referentiel_competence is None:
|
||||
raise ScoValueError(
|
||||
"""
|
||||
<p>Pas de référentiel de compétences associé à la formation !</p>
|
||||
<p>Pour associer un référentiel, passer par le menu <b>Semestre /
|
||||
Voir la formation... </b> et suivre le lien <em>"associer à un référentiel
|
||||
<p>Pour associer un référentiel, passer par le menu <b>Semestre /
|
||||
Voir la formation... </b> et suivre le lien <em>"associer à un référentiel
|
||||
de compétences"</em>
|
||||
"""
|
||||
)
|
||||
@ -262,7 +262,7 @@ class RowCollector:
|
||||
# --- Codes (seront cachés, mais exportés en excel)
|
||||
self.add_cell("etudid", "etudid", etud.id, "codes")
|
||||
self.add_cell("code_nip", "code_nip", etud.code_nip or "", "codes")
|
||||
# --- Identité étudiant (adapté de res_comon/get_table_recap, à factoriser XXX TODO)
|
||||
# --- Identité étudiant (adapté de res_common/get_table_recap, à factoriser XXX TODO)
|
||||
self.add_cell("civilite_str", "Civ.", etud.civilite_str, "identite_detail")
|
||||
self.add_cell("nom_disp", "Nom", etud.nom_disp(), "identite_detail")
|
||||
self["_nom_disp_order"] = etud.sort_key
|
||||
|
@ -82,8 +82,6 @@ def show_etud(deca: DecisionsProposeesAnnee, read_only: bool = True) -> str:
|
||||
H.append(
|
||||
_gen_but_niveau_ue(
|
||||
dec_rcue.rcue.ue_1,
|
||||
deca.decisions_ues[dec_rcue.rcue.ue_1.id].moy_ue,
|
||||
# dec_rcue.rcue.moy_ue_1,
|
||||
deca.decisions_ues[dec_rcue.rcue.ue_1.id],
|
||||
disabled=read_only,
|
||||
)
|
||||
@ -92,8 +90,6 @@ def show_etud(deca: DecisionsProposeesAnnee, read_only: bool = True) -> str:
|
||||
H.append(
|
||||
_gen_but_niveau_ue(
|
||||
dec_rcue.rcue.ue_2,
|
||||
deca.decisions_ues[dec_rcue.rcue.ue_2.id].moy_ue,
|
||||
# dec_rcue.rcue.moy_ue_2,
|
||||
deca.decisions_ues[dec_rcue.rcue.ue_2.id],
|
||||
disabled=read_only,
|
||||
)
|
||||
@ -134,7 +130,7 @@ def _gen_but_select(
|
||||
for code in codes
|
||||
]
|
||||
)
|
||||
return f"""<select required name="{name}"
|
||||
return f"""<select required name="{name}"
|
||||
class="but_code {klass}"
|
||||
onchange="change_menu_code(this);"
|
||||
{"disabled" if disabled else ""}
|
||||
@ -142,20 +138,40 @@ def _gen_but_select(
|
||||
"""
|
||||
|
||||
|
||||
def _gen_but_niveau_ue(
|
||||
ue: UniteEns, moy_ue: float, dec_ue: DecisionsProposeesUE, disabled=False
|
||||
):
|
||||
def _gen_but_niveau_ue(ue: UniteEns, dec_ue: DecisionsProposeesUE, disabled=False):
|
||||
if dec_ue.ue_status and dec_ue.ue_status["is_capitalized"]:
|
||||
moy_ue_str = f"""<span class="ue_cap">{
|
||||
scu.fmt_note(dec_ue.moy_ue_with_cap)}</span>"""
|
||||
scoplement = f"""<div class="scoplement">
|
||||
<div>
|
||||
<b>UE {ue.acronyme} capitalisée le
|
||||
{dec_ue.ue_status["event_date"].strftime("%d/%m/%Y")}
|
||||
</b>
|
||||
</div>
|
||||
<div>UE en cours avec moyenne
|
||||
{scu.fmt_note(dec_ue.moy_ue)}
|
||||
</div>
|
||||
</div>
|
||||
"""
|
||||
else:
|
||||
moy_ue_str = f"""<span>{scu.fmt_note(dec_ue.moy_ue)}</span>"""
|
||||
scoplement = ""
|
||||
|
||||
return f"""<div class="but_niveau_ue {
|
||||
'recorded' if dec_ue.code_valide is not None else ''}
|
||||
">
|
||||
<div title="{ue.titre}">{ue.acronyme}</div>
|
||||
<div class="but_note">{scu.fmt_note(moy_ue)}</div>
|
||||
<div class="but_note with_scoplement">
|
||||
<div>{moy_ue_str}</div>
|
||||
{scoplement}
|
||||
</div>
|
||||
<div class="but_code">{
|
||||
_gen_but_select("code_ue_"+str(ue.id),
|
||||
dec_ue.codes,
|
||||
dec_ue.code_valide, disabled=disabled
|
||||
)
|
||||
}</div>
|
||||
|
||||
</div>"""
|
||||
|
||||
|
||||
@ -295,7 +311,6 @@ def jury_but_semestriel(
|
||||
H.append(
|
||||
_gen_but_niveau_ue(
|
||||
ue,
|
||||
dec_ue.moy_ue,
|
||||
dec_ue,
|
||||
disabled=read_only,
|
||||
)
|
||||
|
@ -316,7 +316,7 @@ class ResultatsSemestre(ResultatsCache):
|
||||
"""L'état de l'UE pour cet étudiant.
|
||||
Result: dict, ou None si l'UE n'est pas dans ce semestre.
|
||||
"""
|
||||
ue = UniteEns.query.get(ue_id) # TODO cacher nos UEs ?
|
||||
ue = UniteEns.query.get(ue_id)
|
||||
if ue.type == UE_SPORT:
|
||||
return {
|
||||
"is_capitalized": False,
|
||||
|
@ -84,28 +84,28 @@ class RegroupementCoherentUE:
|
||||
"""Le regroupement cohérent d'UE, dans la terminologie du BUT, est le couple d'UEs
|
||||
de la même année (BUT1,2,3) liées au *même niveau de compétence*.
|
||||
|
||||
La moyenne (10/20) au RCU déclenche la compensation des UE.
|
||||
La moyenne (10/20) au RCUE déclenche la compensation des UE.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
etud: Identite,
|
||||
formsemestre_1: FormSemestre,
|
||||
ue_1: UniteEns,
|
||||
dec_ue_1: "DecisionsProposeesUE",
|
||||
formsemestre_2: FormSemestre,
|
||||
ue_2: UniteEns,
|
||||
dec_ue_2: "DecisionsProposeesUE",
|
||||
inscription_etat: str,
|
||||
):
|
||||
from app.comp import res_sem
|
||||
from app.comp.res_but import ResultatsSemestreBUT
|
||||
|
||||
# from app.but.jury_but import DecisionsProposeesUE
|
||||
ue_1 = dec_ue_1.ue
|
||||
ue_2 = dec_ue_2.ue
|
||||
# Ordonne les UE dans le sens croissant (S1,S2) ou (S3,S4)...
|
||||
if formsemestre_1.semestre_id > formsemestre_2.semestre_id:
|
||||
(ue_1, formsemestre_1), (ue_2, formsemestre_2) = (
|
||||
(
|
||||
ue_2,
|
||||
formsemestre_2,
|
||||
),
|
||||
(ue_2, formsemestre_2),
|
||||
(ue_1, formsemestre_1),
|
||||
)
|
||||
assert formsemestre_1.semestre_id % 2 == 1
|
||||
@ -125,21 +125,12 @@ class RegroupementCoherentUE:
|
||||
self.moy_ue_1 = self.moy_ue_2 = "-"
|
||||
self.moy_ue_1_val = self.moy_ue_2_val = 0.0
|
||||
return
|
||||
res: ResultatsSemestreBUT = res_sem.load_formsemestre_results(formsemestre_1)
|
||||
if ue_1.id in res.etud_moy_ue and etud.id in res.etud_moy_ue[ue_1.id]:
|
||||
self.moy_ue_1 = res.etud_moy_ue[ue_1.id][etud.id]
|
||||
self.moy_ue_1_val = self.moy_ue_1 # toujours float, peut être NaN
|
||||
else:
|
||||
self.moy_ue_1 = None
|
||||
self.moy_ue_1_val = 0.0
|
||||
res: ResultatsSemestreBUT = res_sem.load_formsemestre_results(formsemestre_2)
|
||||
if ue_2.id in res.etud_moy_ue and etud.id in res.etud_moy_ue[ue_2.id]:
|
||||
self.moy_ue_2 = res.etud_moy_ue[ue_2.id][etud.id]
|
||||
self.moy_ue_2_val = self.moy_ue_2
|
||||
else:
|
||||
self.moy_ue_2 = None
|
||||
self.moy_ue_2_val = 0.0
|
||||
# Calcul de la moyenne au RCUE
|
||||
self.moy_ue_1 = dec_ue_1.moy_ue_with_cap
|
||||
self.moy_ue_1_val = self.moy_ue_1 if self.moy_ue_1 is not None else 0.0
|
||||
self.moy_ue_2 = dec_ue_2.moy_ue_with_cap
|
||||
self.moy_ue_2_val = self.moy_ue_2 if self.moy_ue_2 is not None else 0.0
|
||||
|
||||
# Calcul de la moyenne au RCUE (utilise les moy d'UE capitalisées)
|
||||
if (self.moy_ue_1 is not None) and (self.moy_ue_2 is not None):
|
||||
# Moyenne RCUE (les pondérations par défaut sont 1.)
|
||||
self.moy_rcue = (
|
||||
@ -149,7 +140,9 @@ class RegroupementCoherentUE:
|
||||
self.moy_rcue = None
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"<{self.__class__.__name__} {self.ue_1.acronyme}({self.moy_ue_1}) {self.ue_2.acronyme}({self.moy_ue_2})>"
|
||||
return f"""<{self.__class__.__name__} {
|
||||
self.ue_1.acronyme}({self.moy_ue_1}) {
|
||||
self.ue_2.acronyme}({self.moy_ue_2})>"""
|
||||
|
||||
def query_validations(
|
||||
self,
|
||||
@ -218,62 +211,62 @@ class RegroupementCoherentUE:
|
||||
|
||||
|
||||
# unused
|
||||
def find_rcues(
|
||||
formsemestre: FormSemestre, ue: UniteEns, etud: Identite, inscription_etat: str
|
||||
) -> list[RegroupementCoherentUE]:
|
||||
"""Les RCUE (niveau de compétence) à considérer pour cet étudiant dans
|
||||
ce semestre pour cette UE.
|
||||
# def find_rcues(
|
||||
# formsemestre: FormSemestre, ue: UniteEns, etud: Identite, inscription_etat: str
|
||||
# ) -> list[RegroupementCoherentUE]:
|
||||
# """Les RCUE (niveau de compétence) à considérer pour cet étudiant dans
|
||||
# ce semestre pour cette UE.
|
||||
|
||||
Cherche les UEs du même niveau de compétence auxquelles l'étudiant est inscrit.
|
||||
En cas de redoublement, il peut y en avoir plusieurs, donc plusieurs RCUEs.
|
||||
# Cherche les UEs du même niveau de compétence auxquelles l'étudiant est inscrit.
|
||||
# En cas de redoublement, il peut y en avoir plusieurs, donc plusieurs RCUEs.
|
||||
|
||||
Résultat: la liste peut être vide.
|
||||
"""
|
||||
if (ue.niveau_competence is None) or (ue.semestre_idx is None):
|
||||
return []
|
||||
# Résultat: la liste peut être vide.
|
||||
# """
|
||||
# if (ue.niveau_competence is None) or (ue.semestre_idx is None):
|
||||
# return []
|
||||
|
||||
if ue.semestre_idx % 2: # S1, S3, S5
|
||||
other_semestre_idx = ue.semestre_idx + 1
|
||||
else:
|
||||
other_semestre_idx = ue.semestre_idx - 1
|
||||
# if ue.semestre_idx % 2: # S1, S3, S5
|
||||
# other_semestre_idx = ue.semestre_idx + 1
|
||||
# else:
|
||||
# other_semestre_idx = ue.semestre_idx - 1
|
||||
|
||||
cursor = db.session.execute(
|
||||
text(
|
||||
"""SELECT
|
||||
ue.id, formsemestre.id
|
||||
FROM
|
||||
notes_ue ue,
|
||||
notes_formsemestre_inscription inscr,
|
||||
notes_formsemestre formsemestre
|
||||
# cursor = db.session.execute(
|
||||
# text(
|
||||
# """SELECT
|
||||
# ue.id, formsemestre.id
|
||||
# FROM
|
||||
# notes_ue ue,
|
||||
# notes_formsemestre_inscription inscr,
|
||||
# notes_formsemestre formsemestre
|
||||
|
||||
WHERE
|
||||
inscr.etudid = :etudid
|
||||
AND inscr.formsemestre_id = formsemestre.id
|
||||
|
||||
AND formsemestre.semestre_id = :other_semestre_idx
|
||||
AND ue.formation_id = formsemestre.formation_id
|
||||
AND ue.niveau_competence_id = :ue_niveau_competence_id
|
||||
AND ue.semestre_idx = :other_semestre_idx
|
||||
"""
|
||||
),
|
||||
{
|
||||
"etudid": etud.id,
|
||||
"other_semestre_idx": other_semestre_idx,
|
||||
"ue_niveau_competence_id": ue.niveau_competence_id,
|
||||
},
|
||||
)
|
||||
rcues = []
|
||||
for ue_id, formsemestre_id in cursor:
|
||||
other_ue = UniteEns.query.get(ue_id)
|
||||
other_formsemestre = FormSemestre.query.get(formsemestre_id)
|
||||
rcues.append(
|
||||
RegroupementCoherentUE(
|
||||
etud, formsemestre, ue, other_formsemestre, other_ue, inscription_etat
|
||||
)
|
||||
)
|
||||
# safety check: 1 seul niveau de comp. concerné:
|
||||
assert len({rcue.ue_1.niveau_competence_id for rcue in rcues}) == 1
|
||||
return rcues
|
||||
# WHERE
|
||||
# inscr.etudid = :etudid
|
||||
# AND inscr.formsemestre_id = formsemestre.id
|
||||
|
||||
# AND formsemestre.semestre_id = :other_semestre_idx
|
||||
# AND ue.formation_id = formsemestre.formation_id
|
||||
# AND ue.niveau_competence_id = :ue_niveau_competence_id
|
||||
# AND ue.semestre_idx = :other_semestre_idx
|
||||
# """
|
||||
# ),
|
||||
# {
|
||||
# "etudid": etud.id,
|
||||
# "other_semestre_idx": other_semestre_idx,
|
||||
# "ue_niveau_competence_id": ue.niveau_competence_id,
|
||||
# },
|
||||
# )
|
||||
# rcues = []
|
||||
# for ue_id, formsemestre_id in cursor:
|
||||
# other_ue = UniteEns.query.get(ue_id)
|
||||
# other_formsemestre = FormSemestre.query.get(formsemestre_id)
|
||||
# rcues.append(
|
||||
# RegroupementCoherentUE(
|
||||
# etud, formsemestre, ue, other_formsemestre, other_ue, inscription_etat
|
||||
# )
|
||||
# )
|
||||
# # safety check: 1 seul niveau de comp. concerné:
|
||||
# assert len({rcue.ue_1.niveau_competence_id for rcue in rcues}) == 1
|
||||
# return rcues
|
||||
|
||||
|
||||
class ApcValidationAnnee(db.Model):
|
||||
|
@ -150,7 +150,7 @@ class FormSemestre(db.Model):
|
||||
self.modalite = FormationModalite.DEFAULT_MODALITE
|
||||
|
||||
def __repr__(self):
|
||||
return f"<{self.__class__.__name__} {self.id} {self.titre_num()}>"
|
||||
return f"<{self.__class__.__name__} {self.id} {self.titre_annee()}>"
|
||||
|
||||
def to_dict(self, convert_objects=False) -> dict:
|
||||
"""dict (compatible ScoDoc7).
|
||||
|
@ -25,7 +25,7 @@
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
"""Feuille excel pour preparation des jurys
|
||||
"""Feuille excel pour préparation des jurys classiques (non BUT)
|
||||
"""
|
||||
import time
|
||||
|
||||
@ -51,7 +51,9 @@ import sco_version
|
||||
|
||||
|
||||
def feuille_preparation_jury(formsemestre_id):
|
||||
"Feuille excel pour preparation des jurys"
|
||||
"""Feuille excel pour préparation des jurys classiques.
|
||||
Non adaptée pour le BUT.
|
||||
"""
|
||||
formsemestre = FormSemestre.query.get_or_404(formsemestre_id)
|
||||
nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
|
||||
etuds: Identite = nt.get_inscrits(order_by="moy") # tri par moy gen
|
||||
|
@ -52,6 +52,7 @@
|
||||
.but_note {
|
||||
border-right: 1px solid #aaa;
|
||||
padding: 8px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.but_annee select {
|
||||
|
@ -12,7 +12,6 @@ body {
|
||||
font-size: 12pt;
|
||||
}
|
||||
|
||||
|
||||
@media print {
|
||||
.noprint {
|
||||
display: none;
|
||||
@ -3168,7 +3167,8 @@ td.ue_cmp {
|
||||
color: green;
|
||||
}
|
||||
|
||||
td.ue_capitalized {
|
||||
td.ue_capitalized,
|
||||
.ue_cap {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
@ -3330,6 +3330,42 @@ div.module_check_absences ul {
|
||||
|
||||
/* ----------------------------------------------- */
|
||||
|
||||
.scoplement {
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
bottom: 100%;
|
||||
left: 0;
|
||||
padding: 8px;
|
||||
border-radius: 4px;
|
||||
background: rgb(205, 228, 255);
|
||||
color: #000;
|
||||
border: 1px solid rgb(4, 16, 159);
|
||||
opacity: 0;
|
||||
display: grid !important;
|
||||
grid-template-columns: 1fr;
|
||||
gap: 0 !important;
|
||||
column-gap: 4px !important;
|
||||
}
|
||||
|
||||
.with_scoplement:hover .scoplement {
|
||||
opacity: 1;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.scoplement>div {
|
||||
text-align: left;
|
||||
display: inline-block;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.scoplement>div:nth-child(1),
|
||||
.scoplement>div:nth-child(7) {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------- */
|
||||
|
||||
|
||||
/* ----------------------------- */
|
||||
/* TABLES generees par gen_table */
|
||||
/* ----------------------------- */
|
||||
|
@ -2658,7 +2658,7 @@ def formsemestre_saisie_jury(formsemestre_id: int, selected_etudid: int = None):
|
||||
"""
|
||||
read_only = not sco_permissions_check.can_validate_sem(formsemestre_id)
|
||||
formsemestre = FormSemestre.query.get_or_404(formsemestre_id)
|
||||
if formsemestre.formation.is_apc() and formsemestre.semestre_id % 2 == 0:
|
||||
if formsemestre.formation.is_apc(): # and formsemestre.semestre_id % 2 == 0:
|
||||
return jury_but_recap.formsemestre_saisie_jury_but(
|
||||
formsemestre, read_only, selected_etudid=selected_etudid
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user