préparatifs/refactoring
This commit is contained in:
parent
c455f6261f
commit
b1bc8b3f41
@ -49,6 +49,32 @@ class Identite(db.Model):
|
||||
def __repr__(self):
|
||||
return f"<Etud {self.id} {self.nom} {self.prenom}>"
|
||||
|
||||
def civilite_str(self):
|
||||
"""returns 'M.' ou 'Mme' ou '' (pour le genre neutre,
|
||||
personnes ne souhaitant pas d'affichage).
|
||||
"""
|
||||
return {"M": "M.", "F": "Mme", "X": ""}[self.civilite]
|
||||
|
||||
def nom_disp(self):
|
||||
"nom à afficher"
|
||||
if self.nom_usuel:
|
||||
return (
|
||||
(self.nom_usuel + " (" + self.nom + ")") if self.nom else self.nom_usuel
|
||||
)
|
||||
else:
|
||||
return self.nom
|
||||
|
||||
def inscription_courante(self):
|
||||
"""La première inscription à un formsemestre _actuellement_ en cours.
|
||||
None s'il n'y en a pas (ou plus, ou pas encore).
|
||||
"""
|
||||
r = [
|
||||
ins
|
||||
for ins in self.formsemestre_inscriptions
|
||||
if ins.formsemestre.est_courant()
|
||||
]
|
||||
return r[0] if r else None
|
||||
|
||||
|
||||
class Adresse(db.Model):
|
||||
"""Adresse d'un étudiant
|
||||
|
@ -241,7 +241,7 @@ class Module(db.Model):
|
||||
|
||||
def is_apc(self):
|
||||
"True si module SAÉ ou Ressource"
|
||||
return scu.ModuleType(self.module_type) in {
|
||||
return self.module_type and scu.ModuleType(self.module_type) in {
|
||||
scu.ModuleType.RESSOURCE,
|
||||
scu.ModuleType.SAE,
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
"""ScoDoc models: formsemestre
|
||||
"""
|
||||
import datetime
|
||||
from typing import Any
|
||||
|
||||
import flask_sqlalchemy
|
||||
@ -13,11 +14,14 @@ from app.models import CODE_STR_LEN
|
||||
from app.models import UniteEns
|
||||
|
||||
import app.scodoc.notesdb as ndb
|
||||
import app.scodoc.sco_utils as scu
|
||||
from app.scodoc import sco_evaluation_db
|
||||
from app.models.formations import UniteEns, Module
|
||||
from app.models.moduleimpls import ModuleImpl
|
||||
from app.models.etudiants import Identite
|
||||
from app.scodoc import sco_codes_parcours
|
||||
from app.scodoc import sco_preferences
|
||||
from app.scodoc.sco_vdi import ApoEtapeVDI
|
||||
|
||||
|
||||
class FormSemestre(db.Model):
|
||||
@ -40,7 +44,7 @@ class FormSemestre(db.Model):
|
||||
) # False si verrouillé
|
||||
modalite = db.Column(
|
||||
db.String(SHORT_STR_LEN), db.ForeignKey("notes_form_modalites.modalite")
|
||||
)
|
||||
) # "FI", "FAP", "FC", ...
|
||||
# gestion compensation sem DUT:
|
||||
gestion_compensation = db.Column(
|
||||
db.Boolean(), nullable=False, default=False, server_default="false"
|
||||
@ -89,7 +93,12 @@ class FormSemestre(db.Model):
|
||||
viewonly=True,
|
||||
lazy="dynamic",
|
||||
)
|
||||
|
||||
responsables = db.relationship(
|
||||
"User",
|
||||
secondary="notes_formsemestre_responsables",
|
||||
lazy=True,
|
||||
backref=db.backref("formsemestres", lazy=True),
|
||||
)
|
||||
# Ancien id ScoDoc7 pour les migrations de bases anciennes
|
||||
# ne pas utiliser après migrate_scodoc7_dept_archives
|
||||
scodoc7_id = db.Column(db.Text(), nullable=True)
|
||||
@ -99,6 +108,18 @@ class FormSemestre(db.Model):
|
||||
if self.modalite is None:
|
||||
self.modalite = FormationModalite.DEFAULT_MODALITE
|
||||
|
||||
def to_dict(self):
|
||||
d = dict(self.__dict__)
|
||||
d.pop("_sa_instance_state", None)
|
||||
# ScoDoc7 output_formators: (backward compat)
|
||||
d["formsemestre_id"] = self.id
|
||||
d["date_debut"] = (
|
||||
self.date_debut.strftime("%d/%m/%Y") if self.date_debut else ""
|
||||
)
|
||||
d["date_fin"] = self.date_fin.strftime("%d/%m/%Y") if self.date_fin else ""
|
||||
d["responsables"] = [u.id for u in self.responsables]
|
||||
return d
|
||||
|
||||
def query_ues(self, with_sport=False) -> flask_sqlalchemy.BaseQuery:
|
||||
"""UE des modules de ce semestre.
|
||||
- Formations classiques: les UEs auxquelles appartiennent
|
||||
@ -120,6 +141,76 @@ class FormSemestre(db.Model):
|
||||
sem_ues = sem_ues.filter(UniteEns.type != sco_codes_parcours.UE_SPORT)
|
||||
return sem_ues
|
||||
|
||||
def est_courant(self) -> bool:
|
||||
"""Vrai si la date actuelle (now) est dans le semestre
|
||||
(les dates de début et fin sont incluses)
|
||||
"""
|
||||
today = datetime.date.today()
|
||||
return (self.date_debut <= today) and (today <= self.date_fin)
|
||||
|
||||
def est_decale(self):
|
||||
"""Vrai si semestre "décalé"
|
||||
c'est à dire semestres impairs commençant entre janvier et juin
|
||||
et les pairs entre juillet et decembre
|
||||
"""
|
||||
if self.semestre_id <= 0:
|
||||
return False # formations sans semestres
|
||||
return (self.semestre_id % 2 and self.date_debut.month <= 6) or (
|
||||
not self.semestre_id % 2 and self.date_debut.month > 6
|
||||
)
|
||||
|
||||
def etapes_apo_str(self) -> str:
|
||||
"""Chaine décrivant les étapes de ce semestre
|
||||
ex: "V1RT, V1RT3, V1RT4"
|
||||
"""
|
||||
if not self.etapes:
|
||||
return ""
|
||||
return ", ".join([str(x.etape_apo) for x in self.etapes])
|
||||
|
||||
def responsables_str(self, abbrev_prenom=True) -> str:
|
||||
"""chaîne "J. Dupond, X. Martin"
|
||||
ou "Jacques Dupond, Xavier Martin"
|
||||
"""
|
||||
if not self.responsables:
|
||||
return ""
|
||||
if abbrev_prenom:
|
||||
return ", ".join([u.get_prenomnom() for u in self.responsables])
|
||||
else:
|
||||
return ", ".join([u.get_nomcomplet() for u in self.responsables])
|
||||
|
||||
def session_id(self) -> str:
|
||||
"""identifiant externe de semestre de formation
|
||||
Exemple: RT-DUT-FI-S1-ANNEE
|
||||
|
||||
DEPT-TYPE-MODALITE+-S?|SPECIALITE
|
||||
|
||||
TYPE=DUT|LP*|M*
|
||||
MODALITE=FC|FI|FA (si plusieurs, en inverse alpha)
|
||||
|
||||
SPECIALITE=[A-Z]+ EON,ASSUR, ... (si pas Sn ou SnD)
|
||||
|
||||
ANNEE=annee universitaire de debut (exemple: un S2 de 2013-2014 sera S2-2013)
|
||||
"""
|
||||
imputation_dept = sco_preferences.get_preference("ImputationDept", self.id)
|
||||
if not imputation_dept:
|
||||
imputation_dept = sco_preferences.get_preference("DeptName")
|
||||
imputation_dept = imputation_dept.upper()
|
||||
parcours_name = self.formation.get_parcours().NAME
|
||||
modalite = self.modalite
|
||||
# exception pour code Apprentissage:
|
||||
modalite = (modalite or "").replace("FAP", "FA").replace("APP", "FA")
|
||||
if self.semestre_id > 0:
|
||||
decale = "D" if self.est_decale() else ""
|
||||
semestre_id = f"S{self.semestre_id}{decale}"
|
||||
else:
|
||||
semestre_id = self.formation.code_specialite or ""
|
||||
annee_sco = str(
|
||||
scu.annee_scolaire_debut(self.date_debut.year, self.date_debut.month)
|
||||
)
|
||||
return scu.sanitize_string(
|
||||
"-".join((imputation_dept, parcours_name, modalite, semestre_id, annee_sco))
|
||||
)
|
||||
|
||||
|
||||
# Association id des utilisateurs responsables (aka directeurs des etudes) du semestre
|
||||
notes_formsemestre_responsables = db.Table(
|
||||
@ -144,6 +235,12 @@ class FormsemestreEtape(db.Model):
|
||||
)
|
||||
etape_apo = db.Column(db.String(APO_CODE_STR_LEN))
|
||||
|
||||
def __repr__(self):
|
||||
return f"<Etape {self.id} apo={self.etape_apo}>"
|
||||
|
||||
def as_apovdi(self):
|
||||
return ApoEtapeVDI(self.etape_apo)
|
||||
|
||||
|
||||
class FormationModalite(db.Model):
|
||||
"""Modalités de formation, utilisées pour la présentation
|
||||
|
@ -1028,20 +1028,26 @@ def get_abs_count(etudid, sem):
|
||||
tuple (nb abs non justifiées, nb abs justifiées)
|
||||
Utilise un cache.
|
||||
"""
|
||||
date_debut = sem["date_debut_iso"]
|
||||
date_fin = sem["date_fin_iso"]
|
||||
key = str(etudid) + "_" + date_debut + "_" + date_fin
|
||||
return get_abs_count_in_interval(etudid, sem["date_debut_iso"], sem["date_fin_iso"])
|
||||
|
||||
|
||||
def get_abs_count_in_interval(etudid, date_debut_iso, date_fin_iso):
|
||||
"""Les comptes d'absences de cet étudiant entre ces deux dates, incluses:
|
||||
tuple (nb abs non justifiées, nb abs justifiées)
|
||||
Utilise un cache.
|
||||
"""
|
||||
key = str(etudid) + "_" + date_debut_iso + "_" + date_fin_iso
|
||||
r = sco_cache.AbsSemEtudCache.get(key)
|
||||
if not r:
|
||||
nb_abs = count_abs( # was CountAbs XXX
|
||||
nb_abs = count_abs(
|
||||
etudid=etudid,
|
||||
debut=date_debut,
|
||||
fin=date_fin,
|
||||
debut=date_debut_iso,
|
||||
fin=date_fin_iso,
|
||||
)
|
||||
nb_abs_just = count_abs_just( # XXX was CountAbsJust
|
||||
nb_abs_just = count_abs_just(
|
||||
etudid=etudid,
|
||||
debut=date_debut,
|
||||
fin=date_fin,
|
||||
debut=date_debut_iso,
|
||||
fin=date_fin_iso,
|
||||
)
|
||||
r = (nb_abs, nb_abs_just)
|
||||
ans = sco_cache.AbsSemEtudCache.set(key, r)
|
||||
|
@ -584,7 +584,7 @@ du programme" (menu "Semestre") si vous avez un semestre en cours);
|
||||
H.append(
|
||||
f"""
|
||||
<ul>
|
||||
<li>{descr_refcomp} <a class="stdlink" href="{url_for('notes.refcomp_assoc',
|
||||
<li>{descr_refcomp} <a class="stdlink" href="{url_for('notes.refcomp_assoc_formation',
|
||||
scodoc_dept=g.scodoc_dept, formation_id=formation_id)
|
||||
}">{msg_refcomp}</a>
|
||||
</li>
|
||||
|
@ -47,36 +47,6 @@ from app.scodoc import sco_preferences
|
||||
from app.scodoc.scolog import logdb
|
||||
from app.scodoc.TrivialFormulator import TrivialFormulator
|
||||
|
||||
MONTH_NAMES_ABBREV = [
|
||||
"Jan ",
|
||||
"Fév ",
|
||||
"Mars",
|
||||
"Avr ",
|
||||
"Mai ",
|
||||
"Juin",
|
||||
"Jul ",
|
||||
"Août",
|
||||
"Sept",
|
||||
"Oct ",
|
||||
"Nov ",
|
||||
"Déc ",
|
||||
]
|
||||
|
||||
MONTH_NAMES = [
|
||||
"janvier",
|
||||
"février",
|
||||
"mars",
|
||||
"avril",
|
||||
"mai",
|
||||
"juin",
|
||||
"juillet",
|
||||
"août",
|
||||
"septembre",
|
||||
"octobre",
|
||||
"novembre",
|
||||
"décembre",
|
||||
]
|
||||
|
||||
|
||||
def format_etud_ident(etud):
|
||||
"""Format identite de l'étudiant (modifié en place)
|
||||
|
@ -194,7 +194,7 @@ def _formsemestre_enrich(sem):
|
||||
sem["titreannee"] += "-" + annee_fin
|
||||
sem["annee"] += "-" + annee_fin
|
||||
# et les dates sous la forme "oct 2007 - fev 2008"
|
||||
months = sco_etud.MONTH_NAMES_ABBREV
|
||||
months = scu.MONTH_NAMES_ABBREV
|
||||
if mois_debut:
|
||||
mois_debut = months[int(mois_debut) - 1]
|
||||
if mois_fin:
|
||||
@ -470,7 +470,7 @@ def sem_une_annee(sem):
|
||||
return debut == fin
|
||||
|
||||
|
||||
def sem_est_courant(sem):
|
||||
def sem_est_courant(sem): # -> FormSemestre.est_courant
|
||||
"""Vrai si la date actuelle (now) est dans le semestre (les dates de début et fin sont incluses)"""
|
||||
now = time.strftime("%Y-%m-%d")
|
||||
debut = ndb.DateDMYtoISO(sem["date_debut"])
|
||||
|
@ -1621,28 +1621,14 @@ def formsemestre_edit_uecoefs(formsemestre_id, err_ue_id=None):
|
||||
# ----- identification externe des sessions (pour SOJA et autres logiciels)
|
||||
def get_formsemestre_session_id(sem, F, parcours):
|
||||
"""Identifiant de session pour ce semestre
|
||||
Exemple: RT-DUT-FI-S1-ANNEE
|
||||
|
||||
DEPT-TYPE-MODALITE+-S?|SPECIALITE
|
||||
|
||||
TYPE=DUT|LP*|M*
|
||||
MODALITE=FC|FI|FA (si plusieurs, en inverse alpha)
|
||||
|
||||
SPECIALITE=[A-Z]+ EON,ASSUR, ... (si pas Sn ou SnD)
|
||||
|
||||
ANNEE=annee universitaire de debut (exemple: un S2 de 2013-2014 sera S2-2013)
|
||||
|
||||
Obsolete: vooir FormSemestre.session_id() #sco7
|
||||
"""
|
||||
# sem = sco_formsemestre.get_formsemestre( formsemestre_id)
|
||||
# F = sco_formations.formation_list( args={ 'formation_id' : sem['formation_id'] } )[0]
|
||||
# parcours = sco_codes_parcours.get_parcours_from_code(F['type_parcours'])
|
||||
|
||||
ImputationDept = sco_preferences.get_preference(
|
||||
imputation_dept = sco_preferences.get_preference(
|
||||
"ImputationDept", sem["formsemestre_id"]
|
||||
)
|
||||
if not ImputationDept:
|
||||
ImputationDept = sco_preferences.get_preference("DeptName")
|
||||
ImputationDept = ImputationDept.upper()
|
||||
if not imputation_dept:
|
||||
imputation_dept = sco_preferences.get_preference("DeptName")
|
||||
imputation_dept = imputation_dept.upper()
|
||||
parcours_type = parcours.NAME
|
||||
modalite = sem["modalite"]
|
||||
modalite = (
|
||||
@ -1656,5 +1642,5 @@ def get_formsemestre_session_id(sem, F, parcours):
|
||||
annee_sco = str(scu.annee_scolaire_debut(sem["annee_debut"], sem["mois_debut_ord"]))
|
||||
|
||||
return scu.sanitize_string(
|
||||
"-".join((ImputationDept, parcours_type, modalite, semestre_id, annee_sco))
|
||||
"-".join((imputation_dept, parcours_type, modalite, semestre_id, annee_sco))
|
||||
)
|
||||
|
@ -151,7 +151,7 @@ def scolar_news_summary(n=5):
|
||||
n[k] = _scolar_news_editor.output_formators[k](n[k])
|
||||
# date resumee
|
||||
j, m = n["date"].split("/")[:2]
|
||||
mois = sco_etud.MONTH_NAMES_ABBREV[int(m) - 1]
|
||||
mois = scu.MONTH_NAMES_ABBREV[int(m) - 1]
|
||||
n["formatted_date"] = "%s %s %s" % (j, mois, n["hm"])
|
||||
# indication semestre si ajout notes:
|
||||
infos = _get_formsemestre_infos_from_news(n)
|
||||
|
@ -212,7 +212,7 @@ def placement_eval_selectetuds(evaluation_id):
|
||||
)
|
||||
return runner.exec_placement() # calcul et generation du fichier
|
||||
htmls = [
|
||||
html_sco_header.sco_header(init_jquery_ui=True),
|
||||
html_sco_header.sco_header(),
|
||||
sco_evaluations.evaluation_describe(evaluation_id=evaluation_id),
|
||||
"<h3>Placement et émargement des étudiants</h3>",
|
||||
render_template("scodoc/forms/placement.html", form=form),
|
||||
|
@ -127,6 +127,36 @@ EVALUATION_NORMALE = 0
|
||||
EVALUATION_RATTRAPAGE = 1
|
||||
EVALUATION_SESSION2 = 2
|
||||
|
||||
MONTH_NAMES_ABBREV = (
|
||||
"Jan ",
|
||||
"Fév ",
|
||||
"Mars",
|
||||
"Avr ",
|
||||
"Mai ",
|
||||
"Juin",
|
||||
"Jul ",
|
||||
"Août",
|
||||
"Sept",
|
||||
"Oct ",
|
||||
"Nov ",
|
||||
"Déc ",
|
||||
)
|
||||
|
||||
MONTH_NAMES = (
|
||||
"janvier",
|
||||
"février",
|
||||
"mars",
|
||||
"avril",
|
||||
"mai",
|
||||
"juin",
|
||||
"juillet",
|
||||
"août",
|
||||
"septembre",
|
||||
"octobre",
|
||||
"novembre",
|
||||
"décembre",
|
||||
)
|
||||
|
||||
|
||||
def fmt_note(val, note_max=None, keep_numeric=False):
|
||||
"""conversion note en str pour affichage dans tables HTML ou PDF.
|
||||
|
Loading…
Reference in New Issue
Block a user