préparatifs/refactoring
This commit is contained in:
parent
c455f6261f
commit
b1bc8b3f41
@ -49,6 +49,32 @@ class Identite(db.Model):
|
|||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"<Etud {self.id} {self.nom} {self.prenom}>"
|
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):
|
class Adresse(db.Model):
|
||||||
"""Adresse d'un étudiant
|
"""Adresse d'un étudiant
|
||||||
|
@ -241,7 +241,7 @@ class Module(db.Model):
|
|||||||
|
|
||||||
def is_apc(self):
|
def is_apc(self):
|
||||||
"True si module SAÉ ou Ressource"
|
"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.RESSOURCE,
|
||||||
scu.ModuleType.SAE,
|
scu.ModuleType.SAE,
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
"""ScoDoc models: formsemestre
|
"""ScoDoc models: formsemestre
|
||||||
"""
|
"""
|
||||||
|
import datetime
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
import flask_sqlalchemy
|
import flask_sqlalchemy
|
||||||
@ -13,11 +14,14 @@ from app.models import CODE_STR_LEN
|
|||||||
from app.models import UniteEns
|
from app.models import UniteEns
|
||||||
|
|
||||||
import app.scodoc.notesdb as ndb
|
import app.scodoc.notesdb as ndb
|
||||||
|
import app.scodoc.sco_utils as scu
|
||||||
from app.scodoc import sco_evaluation_db
|
from app.scodoc import sco_evaluation_db
|
||||||
from app.models.formations import UniteEns, Module
|
from app.models.formations import UniteEns, Module
|
||||||
from app.models.moduleimpls import ModuleImpl
|
from app.models.moduleimpls import ModuleImpl
|
||||||
from app.models.etudiants import Identite
|
from app.models.etudiants import Identite
|
||||||
from app.scodoc import sco_codes_parcours
|
from app.scodoc import sco_codes_parcours
|
||||||
|
from app.scodoc import sco_preferences
|
||||||
|
from app.scodoc.sco_vdi import ApoEtapeVDI
|
||||||
|
|
||||||
|
|
||||||
class FormSemestre(db.Model):
|
class FormSemestre(db.Model):
|
||||||
@ -40,7 +44,7 @@ class FormSemestre(db.Model):
|
|||||||
) # False si verrouillé
|
) # False si verrouillé
|
||||||
modalite = db.Column(
|
modalite = db.Column(
|
||||||
db.String(SHORT_STR_LEN), db.ForeignKey("notes_form_modalites.modalite")
|
db.String(SHORT_STR_LEN), db.ForeignKey("notes_form_modalites.modalite")
|
||||||
)
|
) # "FI", "FAP", "FC", ...
|
||||||
# gestion compensation sem DUT:
|
# gestion compensation sem DUT:
|
||||||
gestion_compensation = db.Column(
|
gestion_compensation = db.Column(
|
||||||
db.Boolean(), nullable=False, default=False, server_default="false"
|
db.Boolean(), nullable=False, default=False, server_default="false"
|
||||||
@ -89,7 +93,12 @@ class FormSemestre(db.Model):
|
|||||||
viewonly=True,
|
viewonly=True,
|
||||||
lazy="dynamic",
|
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
|
# Ancien id ScoDoc7 pour les migrations de bases anciennes
|
||||||
# ne pas utiliser après migrate_scodoc7_dept_archives
|
# ne pas utiliser après migrate_scodoc7_dept_archives
|
||||||
scodoc7_id = db.Column(db.Text(), nullable=True)
|
scodoc7_id = db.Column(db.Text(), nullable=True)
|
||||||
@ -99,6 +108,18 @@ class FormSemestre(db.Model):
|
|||||||
if self.modalite is None:
|
if self.modalite is None:
|
||||||
self.modalite = FormationModalite.DEFAULT_MODALITE
|
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:
|
def query_ues(self, with_sport=False) -> flask_sqlalchemy.BaseQuery:
|
||||||
"""UE des modules de ce semestre.
|
"""UE des modules de ce semestre.
|
||||||
- Formations classiques: les UEs auxquelles appartiennent
|
- 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)
|
sem_ues = sem_ues.filter(UniteEns.type != sco_codes_parcours.UE_SPORT)
|
||||||
return sem_ues
|
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
|
# Association id des utilisateurs responsables (aka directeurs des etudes) du semestre
|
||||||
notes_formsemestre_responsables = db.Table(
|
notes_formsemestre_responsables = db.Table(
|
||||||
@ -144,6 +235,12 @@ class FormsemestreEtape(db.Model):
|
|||||||
)
|
)
|
||||||
etape_apo = db.Column(db.String(APO_CODE_STR_LEN))
|
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):
|
class FormationModalite(db.Model):
|
||||||
"""Modalités de formation, utilisées pour la présentation
|
"""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)
|
tuple (nb abs non justifiées, nb abs justifiées)
|
||||||
Utilise un cache.
|
Utilise un cache.
|
||||||
"""
|
"""
|
||||||
date_debut = sem["date_debut_iso"]
|
return get_abs_count_in_interval(etudid, sem["date_debut_iso"], sem["date_fin_iso"])
|
||||||
date_fin = sem["date_fin_iso"]
|
|
||||||
key = str(etudid) + "_" + date_debut + "_" + date_fin
|
|
||||||
|
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)
|
r = sco_cache.AbsSemEtudCache.get(key)
|
||||||
if not r:
|
if not r:
|
||||||
nb_abs = count_abs( # was CountAbs XXX
|
nb_abs = count_abs(
|
||||||
etudid=etudid,
|
etudid=etudid,
|
||||||
debut=date_debut,
|
debut=date_debut_iso,
|
||||||
fin=date_fin,
|
fin=date_fin_iso,
|
||||||
)
|
)
|
||||||
nb_abs_just = count_abs_just( # XXX was CountAbsJust
|
nb_abs_just = count_abs_just(
|
||||||
etudid=etudid,
|
etudid=etudid,
|
||||||
debut=date_debut,
|
debut=date_debut_iso,
|
||||||
fin=date_fin,
|
fin=date_fin_iso,
|
||||||
)
|
)
|
||||||
r = (nb_abs, nb_abs_just)
|
r = (nb_abs, nb_abs_just)
|
||||||
ans = sco_cache.AbsSemEtudCache.set(key, r)
|
ans = sco_cache.AbsSemEtudCache.set(key, r)
|
||||||
|
@ -584,7 +584,7 @@ du programme" (menu "Semestre") si vous avez un semestre en cours);
|
|||||||
H.append(
|
H.append(
|
||||||
f"""
|
f"""
|
||||||
<ul>
|
<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)
|
scodoc_dept=g.scodoc_dept, formation_id=formation_id)
|
||||||
}">{msg_refcomp}</a>
|
}">{msg_refcomp}</a>
|
||||||
</li>
|
</li>
|
||||||
|
@ -47,36 +47,6 @@ from app.scodoc import sco_preferences
|
|||||||
from app.scodoc.scolog import logdb
|
from app.scodoc.scolog import logdb
|
||||||
from app.scodoc.TrivialFormulator import TrivialFormulator
|
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):
|
def format_etud_ident(etud):
|
||||||
"""Format identite de l'étudiant (modifié en place)
|
"""Format identite de l'étudiant (modifié en place)
|
||||||
|
@ -194,7 +194,7 @@ def _formsemestre_enrich(sem):
|
|||||||
sem["titreannee"] += "-" + annee_fin
|
sem["titreannee"] += "-" + annee_fin
|
||||||
sem["annee"] += "-" + annee_fin
|
sem["annee"] += "-" + annee_fin
|
||||||
# et les dates sous la forme "oct 2007 - fev 2008"
|
# et les dates sous la forme "oct 2007 - fev 2008"
|
||||||
months = sco_etud.MONTH_NAMES_ABBREV
|
months = scu.MONTH_NAMES_ABBREV
|
||||||
if mois_debut:
|
if mois_debut:
|
||||||
mois_debut = months[int(mois_debut) - 1]
|
mois_debut = months[int(mois_debut) - 1]
|
||||||
if mois_fin:
|
if mois_fin:
|
||||||
@ -470,7 +470,7 @@ def sem_une_annee(sem):
|
|||||||
return debut == fin
|
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)"""
|
"""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")
|
now = time.strftime("%Y-%m-%d")
|
||||||
debut = ndb.DateDMYtoISO(sem["date_debut"])
|
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)
|
# ----- identification externe des sessions (pour SOJA et autres logiciels)
|
||||||
def get_formsemestre_session_id(sem, F, parcours):
|
def get_formsemestre_session_id(sem, F, parcours):
|
||||||
"""Identifiant de session pour ce semestre
|
"""Identifiant de session pour ce semestre
|
||||||
Exemple: RT-DUT-FI-S1-ANNEE
|
Obsolete: vooir FormSemestre.session_id() #sco7
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
# sem = sco_formsemestre.get_formsemestre( formsemestre_id)
|
imputation_dept = sco_preferences.get_preference(
|
||||||
# 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(
|
|
||||||
"ImputationDept", sem["formsemestre_id"]
|
"ImputationDept", sem["formsemestre_id"]
|
||||||
)
|
)
|
||||||
if not ImputationDept:
|
if not imputation_dept:
|
||||||
ImputationDept = sco_preferences.get_preference("DeptName")
|
imputation_dept = sco_preferences.get_preference("DeptName")
|
||||||
ImputationDept = ImputationDept.upper()
|
imputation_dept = imputation_dept.upper()
|
||||||
parcours_type = parcours.NAME
|
parcours_type = parcours.NAME
|
||||||
modalite = sem["modalite"]
|
modalite = sem["modalite"]
|
||||||
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"]))
|
annee_sco = str(scu.annee_scolaire_debut(sem["annee_debut"], sem["mois_debut_ord"]))
|
||||||
|
|
||||||
return scu.sanitize_string(
|
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])
|
n[k] = _scolar_news_editor.output_formators[k](n[k])
|
||||||
# date resumee
|
# date resumee
|
||||||
j, m = n["date"].split("/")[:2]
|
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"])
|
n["formatted_date"] = "%s %s %s" % (j, mois, n["hm"])
|
||||||
# indication semestre si ajout notes:
|
# indication semestre si ajout notes:
|
||||||
infos = _get_formsemestre_infos_from_news(n)
|
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
|
return runner.exec_placement() # calcul et generation du fichier
|
||||||
htmls = [
|
htmls = [
|
||||||
html_sco_header.sco_header(init_jquery_ui=True),
|
html_sco_header.sco_header(),
|
||||||
sco_evaluations.evaluation_describe(evaluation_id=evaluation_id),
|
sco_evaluations.evaluation_describe(evaluation_id=evaluation_id),
|
||||||
"<h3>Placement et émargement des étudiants</h3>",
|
"<h3>Placement et émargement des étudiants</h3>",
|
||||||
render_template("scodoc/forms/placement.html", form=form),
|
render_template("scodoc/forms/placement.html", form=form),
|
||||||
|
@ -127,6 +127,36 @@ EVALUATION_NORMALE = 0
|
|||||||
EVALUATION_RATTRAPAGE = 1
|
EVALUATION_RATTRAPAGE = 1
|
||||||
EVALUATION_SESSION2 = 2
|
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):
|
def fmt_note(val, note_max=None, keep_numeric=False):
|
||||||
"""conversion note en str pour affichage dans tables HTML ou PDF.
|
"""conversion note en str pour affichage dans tables HTML ou PDF.
|
||||||
|
Loading…
Reference in New Issue
Block a user