forked from ScoDoc/ScoDoc
Améliore code gestion civilité. Tests unitaires étudiants et import excel. Diverses corrections.
This commit is contained in:
parent
194e58419e
commit
e87bb9a8db
@ -91,8 +91,8 @@ class Identite(db.Model, models.ScoDocModel):
|
||||
unique=True,
|
||||
postgresql_where=(code_ine.isnot(None)),
|
||||
),
|
||||
db.CheckConstraint("civilite IN ('M', 'F', 'X')"),
|
||||
db.CheckConstraint("civilite_etat_civil IN ('M', 'F', 'X')"),
|
||||
db.CheckConstraint("civilite IN ('M', 'F', 'X')"), # non nullable
|
||||
db.CheckConstraint("civilite_etat_civil IN ('M', 'F', 'X')"), # nullable
|
||||
)
|
||||
# ----- Relations
|
||||
adresses = db.relationship(
|
||||
@ -213,33 +213,40 @@ class Identite(db.Model, models.ScoDocModel):
|
||||
return etud
|
||||
|
||||
@property
|
||||
def civilite_str(self):
|
||||
"""returns 'M.' ou 'Mme' ou '' (pour le genre neutre,
|
||||
def civilite_str(self) -> str:
|
||||
"""returns civilité usuelle: 'M.' ou 'Mme' ou '' (pour le genre neutre,
|
||||
personnes ne souhaitant pas d'affichage).
|
||||
"""
|
||||
return {"M": "M.", "F": "Mme", "X": ""}[self.civilite]
|
||||
|
||||
@property
|
||||
def civilite_etat_civil_str(self):
|
||||
"""returns 'M.' ou 'Mme' ou '' (pour le genre neutre,
|
||||
personnes ne souhaitant pas d'affichage).
|
||||
def civilite_etat_civil_str(self) -> str:
|
||||
"""returns 'M.' ou 'Mme', selon état civil officiel.
|
||||
La France ne reconnait pas le genre neutre dans l'état civil:
|
||||
si cette donnée état civil est précisée, elle est utilisée,
|
||||
sinon on renvoie la civilité usuelle.
|
||||
"""
|
||||
return {"M": "M.", "F": "Mme", "X": ""}[self.civilite_etat_civil]
|
||||
return (
|
||||
{"M": "M.", "F": "Mme"}.get(self.civilite_etat_civil, "")
|
||||
if self.civilite_etat_civil
|
||||
else self.civilite_str
|
||||
)
|
||||
|
||||
def sex_nom(self, no_accents=False) -> str:
|
||||
"'M. DUPONTÉ', ou si no_accents, 'M. DUPONTE'"
|
||||
"'M. DUPONTÉ', ou si no_accents, 'M. DUPONTE'. Civilité usuelle."
|
||||
s = f"{self.civilite_str} {(self.nom_usuel or self.nom).upper()}"
|
||||
if no_accents:
|
||||
return scu.suppress_accents(s)
|
||||
return s
|
||||
|
||||
@property
|
||||
def e(self):
|
||||
"terminaison en français: 'ne', '', 'ou '(e)'"
|
||||
def e(self) -> str:
|
||||
"terminaison en français: 'ne', '', 'ou '(e)', selon la civilité usuelle"
|
||||
return {"M": "", "F": "e"}.get(self.civilite, "(e)")
|
||||
|
||||
def nom_disp(self) -> str:
|
||||
"Nom à afficher"
|
||||
"""Nom à afficher.
|
||||
Note: le nom est stocké en base en majuscules."""
|
||||
if self.nom_usuel:
|
||||
return (
|
||||
(self.nom_usuel + " (" + self.nom + ")") if self.nom else self.nom_usuel
|
||||
@ -273,7 +280,8 @@ class Identite(db.Model, models.ScoDocModel):
|
||||
return " ".join(r)
|
||||
|
||||
@property
|
||||
def etat_civil(self):
|
||||
def etat_civil(self) -> str:
|
||||
"M. Prénom NOM, utilisant les données état civil si présentes, usuelles sinon."
|
||||
if self.prenom_etat_civil:
|
||||
civ = {"M": "M.", "F": "Mme", "X": ""}[self.civilite_etat_civil]
|
||||
return f"{civ} {self.prenom_etat_civil} {self.nom}"
|
||||
@ -343,7 +351,7 @@ class Identite(db.Model, models.ScoDocModel):
|
||||
if key == "civilite": # requis
|
||||
value = input_civilite(value)
|
||||
elif key == "civilite_etat_civil":
|
||||
value = input_civilite(value) if value else None
|
||||
value = input_civilite_etat_civil(value)
|
||||
elif key == "boursier":
|
||||
value = bool(value)
|
||||
elif key == "date_naissance":
|
||||
@ -375,7 +383,7 @@ class Identite(db.Model, models.ScoDocModel):
|
||||
e_dict.pop("_sa_instance_state", None)
|
||||
# ScoDoc7 output_formators: (backward compat)
|
||||
e_dict["etudid"] = self.id
|
||||
e_dict["date_naissance"] = ndb.DateISOtoDMY(e_dict["date_naissance"])
|
||||
e_dict["date_naissance"] = ndb.DateISOtoDMY(e_dict.get("date_naissance", ""))
|
||||
e_dict["ne"] = self.e
|
||||
e_dict["nomprenom"] = self.nomprenom
|
||||
adresse = self.adresses.first()
|
||||
@ -711,6 +719,11 @@ def input_civilite(s: str) -> str:
|
||||
raise ScoValueError(f"valeur invalide pour la civilité: {s}")
|
||||
|
||||
|
||||
def input_civilite_etat_civil(s: str) -> str | None:
|
||||
"""Same as input_civilite, but empty gives None (null)"""
|
||||
return input_civilite(s) if s and s.strip() else None
|
||||
|
||||
|
||||
PIVOT_YEAR = 70
|
||||
|
||||
|
||||
@ -786,9 +799,9 @@ class Admission(db.Model, models.ScoDocModel):
|
||||
specialite = db.Column(db.Text)
|
||||
annee_bac = db.Column(db.Integer)
|
||||
math = db.Column(db.Text)
|
||||
physique = db.Column(db.Float)
|
||||
anglais = db.Column(db.Float)
|
||||
francais = db.Column(db.Float)
|
||||
physique = db.Column(db.Text)
|
||||
anglais = db.Column(db.Text)
|
||||
francais = db.Column(db.Text)
|
||||
# Rang dans les voeux du candidat (inconnu avec APB et PS)
|
||||
rang = db.Column(db.Integer)
|
||||
# Qualité et décision du jury d'admission (ou de l'examinateur)
|
||||
@ -852,8 +865,6 @@ class Admission(db.Model, models.ScoDocModel):
|
||||
value = None
|
||||
if key in fs_uppercase and value:
|
||||
value = value.upper()
|
||||
if key == "civilite" or key == "civilite_etat_civil":
|
||||
value = input_civilite(value)
|
||||
elif key == "annee" or key == "annee_bac":
|
||||
value = pivot_year(value)
|
||||
elif key == "classement" or key == "apb_classement_gr":
|
||||
|
@ -38,7 +38,12 @@ from flask import url_for, g
|
||||
from app import db, email
|
||||
from app import log
|
||||
from app.models import Admission, Identite
|
||||
from app.models.etudiants import input_civilite, make_etud_args, pivot_year
|
||||
from app.models.etudiants import (
|
||||
input_civilite,
|
||||
input_civilite_etat_civil,
|
||||
make_etud_args,
|
||||
pivot_year,
|
||||
)
|
||||
import app.scodoc.sco_utils as scu
|
||||
import app.scodoc.notesdb as ndb
|
||||
from app.scodoc.sco_exceptions import ScoGenError, ScoValueError
|
||||
@ -47,9 +52,13 @@ from app.scodoc import sco_preferences
|
||||
from app.scodoc.scolog import logdb
|
||||
|
||||
|
||||
def format_etud_ident(etud):
|
||||
def format_etud_ident(etud: dict):
|
||||
"""Format identite de l'étudiant (modifié en place)
|
||||
nom, prénom et formes associees
|
||||
nom, prénom et formes associees.
|
||||
|
||||
Note: par rapport à Identite.to_dict_bul(),
|
||||
ajoute les champs:
|
||||
'email_default', 'nom_disp', 'nom_usuel', 'civilite_etat_civil_str', 'ne', 'civilite_str'
|
||||
"""
|
||||
etud["nom"] = format_nom(etud["nom"])
|
||||
if "nom_usuel" in etud:
|
||||
@ -65,7 +74,7 @@ def format_etud_ident(etud):
|
||||
etud["civilite_etat_civil_str"] = (
|
||||
format_civilite(etud["civilite_etat_civil"])
|
||||
if etud["civilite_etat_civil"]
|
||||
else ""
|
||||
else etud["civilite_str"]
|
||||
)
|
||||
# Nom à afficher:
|
||||
if etud["nom_usuel"]:
|
||||
@ -76,7 +85,7 @@ def format_etud_ident(etud):
|
||||
etud["nom_disp"] = etud["nom"]
|
||||
|
||||
etud["nomprenom"] = format_nomprenom(etud) # M. Pierre DUPONT
|
||||
etud["etat_civil"] = format_etat_civil(etud)
|
||||
etud["etat_civil"] = _format_etat_civil(etud)
|
||||
if etud["civilite"] == "M":
|
||||
etud["ne"] = ""
|
||||
elif etud["civilite"] == "F":
|
||||
@ -147,11 +156,12 @@ def format_civilite(civilite):
|
||||
raise ScoValueError(f"valeur invalide pour la civilité: {civilite}") from exc
|
||||
|
||||
|
||||
def format_etat_civil(etud: dict):
|
||||
if etud["prenom_etat_civil"]:
|
||||
civ = {"M": "M.", "F": "Mme", "X": ""}[etud.get("civilite_etat_civil", "X")]
|
||||
return f'{civ} {etud["prenom_etat_civil"]} {etud["nom"]}'
|
||||
else:
|
||||
def _format_etat_civil(etud: dict) -> str:
|
||||
"Mme Béatrice DUPONT, en utilisant les données d'état civil si indiquées."
|
||||
if etud["prenom_etat_civil"] or etud["civilite_etat_civil"]:
|
||||
return f"""{etud["civilite_etat_civil_str"]} {
|
||||
etud["prenom_etat_civil"] or etud["prenom"]
|
||||
} {etud["nom"]}"""
|
||||
return etud["nomprenom"]
|
||||
|
||||
|
||||
@ -237,7 +247,7 @@ _identiteEditor = ndb.EditableTable(
|
||||
"prenom": force_uppercase,
|
||||
"prenom_etat_civil": force_uppercase,
|
||||
"civilite": input_civilite,
|
||||
"civilite_etat_civil": input_civilite,
|
||||
"civilite_etat_civil": input_civilite_etat_civil,
|
||||
"date_naissance": ndb.DateDMYtoISO,
|
||||
"boursier": bool,
|
||||
},
|
||||
@ -300,7 +310,9 @@ def check_nom_prenom_homonyms(
|
||||
|
||||
|
||||
def _check_duplicate_code(cnx, args, code_name, disable_notify=False, edit=True):
|
||||
"""Vérifie que le code n'est pas dupliqué"""
|
||||
"""Vérifie que le code n'est pas dupliqué.
|
||||
Raises ScoGenError si problème.
|
||||
"""
|
||||
etudid = args.get("etudid", None)
|
||||
if args.get(code_name, None):
|
||||
etuds = identite_list(cnx, {code_name: str(args[code_name])})
|
||||
@ -355,11 +367,6 @@ def _check_duplicate_code(cnx, args, code_name, disable_notify=False, edit=True)
|
||||
raise ScoGenError(err_page)
|
||||
|
||||
|
||||
def _check_civilite(args):
|
||||
civilite = args.get("civilite", "X") or "X"
|
||||
args["civilite"] = input_civilite(civilite) # TODO: A faire valider
|
||||
|
||||
|
||||
def identite_edit(cnx, args, disable_notify=False):
|
||||
"""Modifie l'identite d'un étudiant.
|
||||
Si pref notification et difference, envoie message notification, sauf si disable_notify
|
||||
@ -400,7 +407,6 @@ def identite_create(cnx, args):
|
||||
"check unique etudid, then create"
|
||||
_check_duplicate_code(cnx, args, "code_nip", edit=False)
|
||||
_check_duplicate_code(cnx, args, "code_ine", edit=False)
|
||||
_check_civilite(args)
|
||||
|
||||
if "etudid" in args:
|
||||
etudid = args["etudid"]
|
||||
@ -915,12 +921,12 @@ def etud_inscriptions_infos(etudid: int, ne="") -> dict:
|
||||
from app.scodoc import sco_formsemestre
|
||||
from app.scodoc import sco_formsemestre_inscriptions
|
||||
|
||||
etud = {}
|
||||
infos = {}
|
||||
# Semestres dans lesquel il est inscrit
|
||||
ins = sco_formsemestre_inscriptions.do_formsemestre_inscription_list(
|
||||
{"etudid": etudid}
|
||||
)
|
||||
etud["ins"] = ins
|
||||
infos["ins"] = ins
|
||||
sems = []
|
||||
cursem = None # semestre "courant" ou il est inscrit
|
||||
for i in ins:
|
||||
@ -933,29 +939,31 @@ def etud_inscriptions_infos(etudid: int, ne="") -> dict:
|
||||
# trie les semestres par date de debut, le plus recent d'abord
|
||||
# (important, ne pas changer (suivi cohortes))
|
||||
sems.sort(key=itemgetter("dateord"), reverse=True)
|
||||
etud["sems"] = sems
|
||||
etud["cursem"] = cursem
|
||||
infos["sems"] = sems
|
||||
infos["cursem"] = cursem
|
||||
if cursem:
|
||||
etud["inscription"] = cursem["titremois"]
|
||||
etud["inscriptionstr"] = "Inscrit en " + cursem["titremois"]
|
||||
etud["inscription_formsemestre_id"] = cursem["formsemestre_id"]
|
||||
etud["etatincursem"] = curi["etat"]
|
||||
etud["situation"] = descr_situation_etud(etudid, ne)
|
||||
infos["inscription"] = cursem["titremois"]
|
||||
infos["inscriptionstr"] = "Inscrit en " + cursem["titremois"]
|
||||
infos["inscription_formsemestre_id"] = cursem["formsemestre_id"]
|
||||
infos["etatincursem"] = curi["etat"]
|
||||
infos["situation"] = descr_situation_etud(etudid, ne)
|
||||
else:
|
||||
if etud["sems"]:
|
||||
if etud["sems"][0]["dateord"] > time.strftime("%Y-%m-%d", time.localtime()):
|
||||
etud["inscription"] = "futur"
|
||||
etud["situation"] = "futur élève"
|
||||
if infos["sems"]:
|
||||
if infos["sems"][0]["dateord"] > time.strftime(
|
||||
"%Y-%m-%d", time.localtime()
|
||||
):
|
||||
infos["inscription"] = "futur"
|
||||
infos["situation"] = "futur élève"
|
||||
else:
|
||||
etud["inscription"] = "ancien"
|
||||
etud["situation"] = "ancien élève"
|
||||
infos["inscription"] = "ancien"
|
||||
infos["situation"] = "ancien élève"
|
||||
else:
|
||||
etud["inscription"] = "non inscrit"
|
||||
etud["situation"] = etud["inscription"]
|
||||
etud["inscriptionstr"] = etud["inscription"]
|
||||
etud["inscription_formsemestre_id"] = None
|
||||
etud["etatincursem"] = "?"
|
||||
return etud
|
||||
infos["inscription"] = "non inscrit"
|
||||
infos["situation"] = infos["inscription"]
|
||||
infos["inscriptionstr"] = infos["inscription"]
|
||||
infos["inscription_formsemestre_id"] = None
|
||||
infos["etatincursem"] = "?"
|
||||
return infos
|
||||
|
||||
|
||||
def descr_situation_etud(etudid: int, ne="") -> str:
|
||||
|
@ -38,18 +38,14 @@ from flask import g, url_for
|
||||
|
||||
from app import db, log
|
||||
from app.models import Identite, GroupDescr, ScolarNews
|
||||
from app.models.etudiants import input_civilite
|
||||
from app.models.etudiants import input_civilite, input_civilite_etat_civil
|
||||
|
||||
from app.scodoc.gen_tables import GenTable
|
||||
from app.scodoc.sco_excel import COLORS
|
||||
from app.scodoc.sco_exceptions import (
|
||||
AccessDenied,
|
||||
ScoFormatError,
|
||||
ScoException,
|
||||
ScoValueError,
|
||||
ScoInvalidDateError,
|
||||
ScoLockedFormError,
|
||||
ScoGenError,
|
||||
)
|
||||
from app.scodoc import html_sco_header
|
||||
from app.scodoc import sco_cache
|
||||
@ -375,6 +371,15 @@ def scolars_import_excel_file(
|
||||
(doit etre 'M', 'F', ou 'MME', 'H', 'X' mais pas '{
|
||||
val}') ligne {linenum}, colonne {titleslist[i]}"""
|
||||
) from exc
|
||||
if titleslist[i].lower() == "civilite_etat_civil":
|
||||
try:
|
||||
val = input_civilite_etat_civil(val)
|
||||
except ScoValueError as exc:
|
||||
raise ScoValueError(
|
||||
f"""valeur invalide pour 'civilite'
|
||||
(doit etre 'M', 'F', vide ou 'MME', 'H', 'X' mais pas '{
|
||||
val}') ligne {linenum}, colonne {titleslist[i]}"""
|
||||
) from exc
|
||||
|
||||
# Excel date conversion:
|
||||
if titleslist[i].lower() == "date_naissance":
|
||||
|
@ -79,6 +79,12 @@ STATIC_DIR = (
|
||||
# Attention: suppose que la timezone utilisée par postgresql soit la même !
|
||||
TIME_ZONE = timezone("/".join(os.path.realpath("/etc/localtime").split("/")[-2:]))
|
||||
|
||||
# ----- CIVILITE ETUDIANTS
|
||||
CIVILITES = {"M": "M.", "F": "Mme", "X": ""}
|
||||
CIVILITES_ETAT_CIVIL = {"M": "M.", "F": "Mme"}
|
||||
# Si l'état civil reconnait le genre neutre (X),:
|
||||
# CIVILITES_ETAT_CIVIL = CIVILITES
|
||||
|
||||
# ----- CALCUL ET PRESENTATION DES NOTES
|
||||
NOTES_PRECISION = 1e-4 # evite eventuelles erreurs d'arrondis
|
||||
NOTES_MIN = 0.0 # valeur minimale admise pour une note (sauf malus, dans [-20, 20])
|
||||
|
@ -1542,7 +1542,6 @@ def _etudident_create_or_edit_form(edit):
|
||||
"math",
|
||||
{
|
||||
"size": 3,
|
||||
"type": "float",
|
||||
"title": "Note de mathématiques",
|
||||
"explanation": "note sur 20 en terminale",
|
||||
},
|
||||
@ -1551,7 +1550,6 @@ def _etudident_create_or_edit_form(edit):
|
||||
"physique",
|
||||
{
|
||||
"size": 3,
|
||||
"type": "float",
|
||||
"title": "Note de physique",
|
||||
"explanation": "note sur 20 en terminale",
|
||||
},
|
||||
@ -1560,7 +1558,6 @@ def _etudident_create_or_edit_form(edit):
|
||||
"anglais",
|
||||
{
|
||||
"size": 3,
|
||||
"type": "float",
|
||||
"title": "Note d'anglais",
|
||||
"explanation": "note sur 20 en terminale",
|
||||
},
|
||||
@ -1569,7 +1566,6 @@ def _etudident_create_or_edit_form(edit):
|
||||
"francais",
|
||||
{
|
||||
"size": 3,
|
||||
"type": "float",
|
||||
"title": "Note de français",
|
||||
"explanation": "note sur 20 obtenue au bac",
|
||||
},
|
||||
|
@ -122,6 +122,24 @@ def upgrade():
|
||||
|
||||
with op.batch_alter_table("admissions", schema=None) as batch_op:
|
||||
batch_op.drop_constraint("admissions_etudid_fkey", type_="foreignkey")
|
||||
batch_op.alter_column(
|
||||
"physique",
|
||||
existing_type=sa.DOUBLE_PRECISION(precision=53),
|
||||
type_=sa.Text(),
|
||||
existing_nullable=True,
|
||||
)
|
||||
batch_op.alter_column(
|
||||
"anglais",
|
||||
existing_type=sa.DOUBLE_PRECISION(precision=53),
|
||||
type_=sa.Text(),
|
||||
existing_nullable=True,
|
||||
)
|
||||
batch_op.alter_column(
|
||||
"francais",
|
||||
existing_type=sa.DOUBLE_PRECISION(precision=53),
|
||||
type_=sa.Text(),
|
||||
existing_nullable=True,
|
||||
)
|
||||
# laisse l'ancienne colonne pour downgrade (tests)
|
||||
# batch_op.drop_column('etudid')
|
||||
|
||||
@ -160,6 +178,24 @@ def downgrade():
|
||||
batch_op.create_foreign_key(
|
||||
"admissions_etudid_fkey", "identite", ["etudid"], ["id"], ondelete="CASCADE"
|
||||
)
|
||||
batch_op.alter_column(
|
||||
"francais",
|
||||
existing_type=sa.Text(),
|
||||
type_=sa.DOUBLE_PRECISION(precision=53),
|
||||
existing_nullable=True,
|
||||
)
|
||||
batch_op.alter_column(
|
||||
"anglais",
|
||||
existing_type=sa.Text(),
|
||||
type_=sa.DOUBLE_PRECISION(precision=53),
|
||||
existing_nullable=True,
|
||||
)
|
||||
batch_op.alter_column(
|
||||
"physique",
|
||||
existing_type=sa.Text(),
|
||||
type_=sa.DOUBLE_PRECISION(precision=53),
|
||||
existing_nullable=True,
|
||||
)
|
||||
|
||||
with op.batch_alter_table("adresse", schema=None) as batch_op:
|
||||
batch_op.drop_constraint("adresse_etudid_fkey", type_="foreignkey")
|
||||
|
BIN
tests/ressources/misc/ImportEtudiants.xlsx
Normal file
BIN
tests/ressources/misc/ImportEtudiants.xlsx
Normal file
Binary file not shown.
@ -4,6 +4,7 @@ Quelques fonctions d'initialisation pour tests unitaires
|
||||
import datetime
|
||||
|
||||
from app import db, models
|
||||
from app.models import Formation
|
||||
import app.scodoc.sco_utils as scu
|
||||
from app.scodoc import codes_cursus
|
||||
|
||||
@ -16,16 +17,34 @@ from tests.unit import sco_fake_gen
|
||||
|
||||
|
||||
def build_formation_test(
|
||||
nb_mods=1, parcours=codes_cursus.CursusBUT, with_ue_sport=False
|
||||
):
|
||||
nb_mods=1,
|
||||
parcours=codes_cursus.CursusBUT,
|
||||
with_ue_sport=False,
|
||||
acronyme="F3",
|
||||
titre="Formation 2",
|
||||
) -> tuple[sco_fake_gen.ScoFake, int, list[int], list[int]]:
|
||||
"""Crée une formation simple pour les tests.
|
||||
Création à partir de zéro (n'importe pas un fichier xml).
|
||||
Avec 3 UEs en S2 et une UE en S4.
|
||||
"""
|
||||
G = sco_fake_gen.ScoFake(verbose=False)
|
||||
# If already exists, just use it
|
||||
formation = Formation.query.filter_by(
|
||||
dept_id=G.dept.id,
|
||||
acronyme=acronyme,
|
||||
titre=titre,
|
||||
version=1,
|
||||
).first()
|
||||
if formation is not None:
|
||||
return (
|
||||
G,
|
||||
formation.id,
|
||||
[ue.id for ue in formation.ues],
|
||||
[m.id for m in formation.modules],
|
||||
)
|
||||
formation_id = G.create_formation(
|
||||
acronyme="F3",
|
||||
titre="Formation 2",
|
||||
acronyme=acronyme,
|
||||
titre=titre,
|
||||
titre_officiel="Titre officiel 2",
|
||||
type_parcours=parcours.TYPE_CURSUS,
|
||||
)
|
||||
|
187
tests/unit/test_etudiants.py
Normal file
187
tests/unit/test_etudiants.py
Normal file
@ -0,0 +1,187 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""Test modèle étudiant (identite)
|
||||
|
||||
|
||||
Utiliser comme:
|
||||
pytest tests/unit/test_etudiants.py
|
||||
|
||||
"""
|
||||
import datetime
|
||||
from pathlib import Path
|
||||
|
||||
from flask import current_app
|
||||
|
||||
from app import db
|
||||
from app.models import Admission, Adresse, Departement, FormSemestre, Identite
|
||||
from app.scodoc import sco_etud
|
||||
from app.scodoc import sco_import_etuds
|
||||
|
||||
from tests.unit import setup
|
||||
|
||||
|
||||
def test_identite(test_client):
|
||||
"Test de base du modèle identité: création, clonage, ..."
|
||||
args = {
|
||||
"civilite": "X",
|
||||
"code_ine": "code_ine",
|
||||
"code_nip": "code_nip",
|
||||
"date_naissance": datetime.date(2000, 1, 2),
|
||||
"dept_id": 1,
|
||||
"dept_naissance": "dept_naissance",
|
||||
"lieu_naissance": "lieu_naissance",
|
||||
"nationalite": "nationalite",
|
||||
"nom_usuel": "nom_usuel",
|
||||
"nom": "nom",
|
||||
"prenom_etat_civil": "prenom_etat_civil",
|
||||
"prenom": "prenom",
|
||||
}
|
||||
e = Identite.create_etud(**args)
|
||||
db.session.add(e)
|
||||
db.session.flush()
|
||||
admission_id = e.admission_id
|
||||
admission = db.session.get(Admission, admission_id)
|
||||
assert admission is not None
|
||||
assert e.boursier is False
|
||||
assert e.adresses.count() == 1
|
||||
adresses_ids = [a.id for a in e.adresses]
|
||||
# --- Teste cascade admission:
|
||||
db.session.delete(e)
|
||||
db.session.flush()
|
||||
assert db.session.get(Admission, admission_id) is None
|
||||
assert db.session.get(Departement, 1) is not None
|
||||
# --- Teste cascade adresses
|
||||
for adresse_id in adresses_ids:
|
||||
assert db.session.get(Adresse, adresse_id) is None
|
||||
# --- Test cascade département
|
||||
dept = Departement(acronym="test_identite")
|
||||
db.session.add(dept)
|
||||
db.session.flush()
|
||||
args1 = args | {"dept_id": dept.id}
|
||||
e = Identite.create_etud(**args1)
|
||||
db.session.add(e)
|
||||
db.session.flush()
|
||||
etudid = e.id
|
||||
db.session.delete(dept)
|
||||
db.session.flush()
|
||||
assert db.session.get(Identite, etudid) is None
|
||||
|
||||
|
||||
def test_etat_civil(test_client):
|
||||
"Test des attributs état civil"
|
||||
dept = Departement.query.first()
|
||||
args = {"nom": "nom", "prenom": "prénom", "civilite": "M", "dept_id": dept.id}
|
||||
# Homme
|
||||
e = Identite(**args)
|
||||
db.session.add(e)
|
||||
db.session.flush()
|
||||
assert e.civilite_etat_civil_str == "M."
|
||||
assert e.e == ""
|
||||
# Femme
|
||||
e = Identite(**args | {"civilite": "F"})
|
||||
db.session.add(e)
|
||||
db.session.flush()
|
||||
assert e.civilite_etat_civil_str == "Mme"
|
||||
assert e.e == "e"
|
||||
# Homme devenu femme
|
||||
e = Identite(**(args | {"civilite_etat_civil": "F"}))
|
||||
db.session.add(e)
|
||||
db.session.flush()
|
||||
assert e.civilite_etat_civil_str == "Mme"
|
||||
assert e.civilite_str == "M."
|
||||
assert e.e == ""
|
||||
# Femme devenue neutre
|
||||
e = Identite(**(args | {"civilite": "X", "civilite_etat_civil": "F"}))
|
||||
db.session.add(e)
|
||||
db.session.flush()
|
||||
assert e.civilite_etat_civil_str == "Mme"
|
||||
assert e.civilite_str == ""
|
||||
assert e.e == "(e)"
|
||||
assert e.prenom_etat_civil is None
|
||||
# La version dict
|
||||
e_d = e.to_dict_scodoc7()
|
||||
assert e_d["civilite"] == "X"
|
||||
assert e_d["civilite_etat_civil"] == "F"
|
||||
assert e_d["ne"] == "(e)"
|
||||
|
||||
|
||||
def test_etud_legacy(test_client):
|
||||
"Test certaines fonctions scodoc7 (sco_etud)"
|
||||
dept = Departement.query.first()
|
||||
args = {"nom": "nom", "prenom": "prénom", "civilite": "M", "dept_id": dept.id}
|
||||
# Prénom état civil
|
||||
e = Identite(**(args))
|
||||
db.session.add(e)
|
||||
db.session.flush()
|
||||
e_dict = e.to_dict_bul()
|
||||
sco_etud.format_etud_ident(e_dict)
|
||||
assert e_dict["nom_disp"] == "NOM"
|
||||
assert e_dict["prenom_etat_civil"] == ""
|
||||
|
||||
|
||||
def test_import_etuds_xlsx(test_client):
|
||||
"test import étudiant depuis xlsx"
|
||||
G, formation_id, (ue1_id, ue2_id, ue3_id), module_ids = setup.build_formation_test(
|
||||
acronyme="IMPXLSX"
|
||||
)
|
||||
formsemestre_id = G.create_formsemestre(
|
||||
formation_id=formation_id,
|
||||
semestre_id=1,
|
||||
date_debut="01/01/2021",
|
||||
date_fin="30/06/2021",
|
||||
)
|
||||
filename = (
|
||||
Path(current_app.config["SCODOC_DIR"])
|
||||
/ "tests/ressources/misc/ImportEtudiants.xlsx"
|
||||
)
|
||||
with open(filename, mode="rb") as f:
|
||||
sco_import_etuds.scolars_import_excel_file(
|
||||
f, formsemestre_id=formsemestre_id, exclude_cols=["photo_filename"]
|
||||
)
|
||||
formsemestre = db.session.get(FormSemestre, formsemestre_id)
|
||||
# Vérifie tous les champs du premier étudiant
|
||||
etud = formsemestre.etuds.first()
|
||||
assert etud.code_nip == "nip1"
|
||||
assert etud.code_ine == "ine1"
|
||||
assert etud.nom == "NOM1"
|
||||
assert etud.nom_usuel == "nom_usuel1"
|
||||
assert etud.prenom == "PRÉNOM1"
|
||||
assert etud.civilite == "M"
|
||||
assert etud.prenom_etat_civil == "PRÉNOM_CIVIL1"
|
||||
assert etud.civilite_etat_civil == "M"
|
||||
assert etud.date_naissance == datetime.date(2001, 5, 1)
|
||||
assert etud.lieu_naissance == "Paris"
|
||||
assert etud.nationalite == "Belge"
|
||||
assert etud.boursier is True
|
||||
# Admission
|
||||
adm = etud.admission
|
||||
assert adm.bac == "C"
|
||||
assert adm.specialite == "SPÉ"
|
||||
assert adm.annee_bac == 2023
|
||||
assert adm.math == "11.0" # deprecated field
|
||||
assert adm.physique == "12.0" # deprecated field
|
||||
assert adm.anglais == "13.0" # deprecated field
|
||||
assert adm.francais == "14.0" # deprecated field
|
||||
assert adm.boursier_prec is False
|
||||
assert adm.qualite == 10
|
||||
assert adm.rapporteur == "xx"
|
||||
assert adm.score == 5
|
||||
assert adm.classement == 111
|
||||
assert adm.nomlycee == "nomlycée"
|
||||
assert adm.codepostallycee == "75005"
|
||||
# Adresse
|
||||
adresse: Adresse = etud.adresses.first()
|
||||
assert adresse.email == "etud1@etud.no"
|
||||
assert adresse.emailperso == "etud1@perso.no"
|
||||
assert adresse.domicile == "1 rue A"
|
||||
assert adresse.codepostaldomicile == "12345"
|
||||
assert adresse.villedomicile == "Lima"
|
||||
assert adresse.paysdomicile == "Pérou"
|
||||
assert adresse.telephone == "102030405"
|
||||
assert adresse.telephonemobile == "605040302"
|
||||
#
|
||||
|
||||
|
||||
# mapp.set_sco_dept("TEST_")
|
||||
# ctx.push()
|
||||
# login_user(User.query.filter_by(user_name="admin").first())
|
@ -10,7 +10,7 @@ nom_usuel; text; identite; 1; nom usuel (si different);
|
||||
prenom; text; identite; 0; prénom de l'etudiant
|
||||
civilite; text; identite; 0; sexe ('M', 'F', 'X');sexe;genre
|
||||
prenom_etat_civil; text; identite; 1; prénom à l'état-civil (si différent);prenom_etat_civil
|
||||
civilite_etat_civil; text; identite; 1; sexe ('M', 'F', 'X') à l'état civil;civilite_etat_civil
|
||||
civilite_etat_civil; text; identite; 1; sexe ('M', 'F', 'X', '') à l'état civil;civilite_etat_civil
|
||||
date_naissance;text;identite; 1; date de naissance (jj/mm/aaaa)
|
||||
lieu_naissance;text;identite; 1; lieu de naissance
|
||||
nationalite; text; identite; 1; nationalite
|
||||
@ -53,6 +53,3 @@ paysdomicile; text; adresse; 1; pays domicile
|
||||
telephone; text; adresse; 1; num. telephone (fixe)
|
||||
telephonemobile; text; adresse; 1; num. telephone (mobile)
|
||||
#
|
||||
# Pas tout à fait admission:
|
||||
debouche;text; admissions;1;(OBSOLETE, ne plus utiliser) situation APRES être passé par chez nous;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user