Modification création/édition étudiants

This commit is contained in:
Emmanuel Viennet 2023-05-15 19:50:11 +02:00
parent 3de9286e61
commit 2f16a2f4df
5 changed files with 84 additions and 40 deletions

View File

@ -18,7 +18,7 @@ from app import models
from app.scodoc import notesdb as ndb from app.scodoc import notesdb as ndb
from app.scodoc.sco_bac import Baccalaureat from app.scodoc.sco_bac import Baccalaureat
from app.scodoc.sco_exceptions import ScoInvalidParamError from app.scodoc.sco_exceptions import ScoInvalidParamError, ScoValueError
import app.scodoc.sco_utils as scu import app.scodoc.sco_utils as scu
@ -100,7 +100,7 @@ class Identite(db.Model):
def create_etud(cls, **args): def create_etud(cls, **args):
"Crée un étudiant, avec admission et adresse vides." "Crée un étudiant, avec admission et adresse vides."
etud: Identite = cls(**args) etud: Identite = cls(**args)
etud.adresses.append(Adresse()) etud.adresses.append(Adresse(typeadresse="domicile"))
etud.admission.append(Admission()) etud.admission.append(Admission())
return etud return etud
@ -201,6 +201,48 @@ class Identite(db.Model):
reverse=True, reverse=True,
) )
@classmethod
def convert_dict_fields(cls, args: dict) -> dict:
"Convert fields in the given dict. No other side effect"
fs_uppercase = {"nom", "prenom", "prenom_etat_civil"}
fs_empty_stored_as_nulls = {
"nom",
"prenom",
"nom_usuel",
"date_naissance",
"lieu_naissance",
"dept_naissance",
"nationalite",
"statut",
"photo_filename",
"code_nip",
"code_ine",
}
args_dict = {}
for key, value in args.items():
if hasattr(cls, key):
# compat scodoc7 (mauvaise idée de l'époque)
if key in fs_empty_stored_as_nulls and value == "":
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 == "boursier":
value = bool(value)
elif key == "date_naissance":
value = ndb.DateDMYtoISO(value)
args_dict[key] = value
return args_dict
def from_dict(self, args: dict):
"update fields given in dict. Add to session but don't commit."
args_dict = Identite.convert_dict_fields(args)
for key, value in args_dict.items():
if hasattr(self, key):
setattr(self, key, value)
db.session.add(self)
def to_dict_short(self) -> dict: def to_dict_short(self) -> dict:
"""Les champs essentiels""" """Les champs essentiels"""
return { return {
@ -543,6 +585,21 @@ def make_etud_args(
return args return args
def input_civilite(s):
"""Converts external representation of civilite to internal:
'M', 'F', or 'X' (and nothing else).
Raises ScoValueError if conversion fails.
"""
s = s.upper().strip()
if s in ("M", "M.", "MR", "H"):
return "M"
elif s in ("F", "MLLE", "MLLE.", "MELLE", "MME"):
return "F"
elif s == "X" or not s:
return "X"
raise ScoValueError("valeur invalide pour la civilité: %s" % s)
class Adresse(db.Model): class Adresse(db.Model):
"""Adresse d'un étudiant """Adresse d'un étudiant
(le modèle permet plusieurs adresses, mais l'UI n'en gère qu'une seule) (le modèle permet plusieurs adresses, mais l'UI n'en gère qu'une seule)

View File

@ -186,7 +186,7 @@ def DBSelectArgs(
cond = "" cond = ""
i = 1 i = 1
cl = [] cl = []
for (_, aux_id) in aux_tables: for _, aux_id in aux_tables:
cl.append("T0.%s = T%d.%s" % (id_name, i, aux_id)) cl.append("T0.%s = T%d.%s" % (id_name, i, aux_id))
i = i + 1 i = i + 1
cond += " and ".join(cl) cond += " and ".join(cl)
@ -403,7 +403,7 @@ class EditableTable(object):
def format_output(self, r, disable_formatting=False): def format_output(self, r, disable_formatting=False):
"Format dict using provided output_formators" "Format dict using provided output_formators"
for (k, v) in r.items(): for k, v in r.items():
if v is None and self.convert_null_outputs_to_empty: if v is None and self.convert_null_outputs_to_empty:
v = "" v = ""
# format value # format value

View File

@ -35,10 +35,10 @@ from operator import itemgetter
from flask import url_for, g from flask import url_for, g
from app import email from app import db, email
from app import log from app import log
from app.models import Admission from app.models import Admission, Identite
from app.models.etudiants import make_etud_args from app.models.etudiants import input_civilite, make_etud_args
import app.scodoc.sco_utils as scu import app.scodoc.sco_utils as scu
import app.scodoc.notesdb as ndb import app.scodoc.notesdb as ndb
from app.scodoc.sco_exceptions import ScoGenError, ScoValueError from app.scodoc.sco_exceptions import ScoGenError, ScoValueError
@ -127,21 +127,6 @@ def format_nom(s, uppercase=True):
return format_prenom(s) return format_prenom(s)
def input_civilite(s):
"""Converts external representation of civilite to internal:
'M', 'F', or 'X' (and nothing else).
Raises ScoValueError if conversion fails.
"""
s = s.upper().strip()
if s in ("M", "M.", "MR", "H"):
return "M"
elif s in ("F", "MLLE", "MLLE.", "MELLE", "MME"):
return "F"
elif s == "X" or not s:
return "X"
raise ScoValueError("valeur invalide pour la civilité: %s" % s)
def format_civilite(civilite): def format_civilite(civilite):
"""returns 'M.' ou 'Mme' ou '' (pour le genre neutre, """returns 'M.' ou 'Mme' ou '' (pour le genre neutre,
personne ne souhaitant pas d'affichage). personne ne souhaitant pas d'affichage).
@ -281,7 +266,9 @@ def identite_list(cnx, *a, **kw):
def identite_edit_nocheck(cnx, args): def identite_edit_nocheck(cnx, args):
"""Modifie les champs mentionnes dans args, sans verification ni notification.""" """Modifie les champs mentionnes dans args, sans verification ni notification."""
_identiteEditor.edit(cnx, args) etud = Identite.query.get(args["etudid"])
etud.from_dict(args)
db.session.commit()
def check_nom_prenom(cnx, nom="", prenom="", etudid=None): def check_nom_prenom(cnx, nom="", prenom="", etudid=None):
@ -572,6 +559,7 @@ admission_delete = _admissionEditor.delete
admission_list = _admissionEditor.list admission_list = _admissionEditor.list
admission_edit = _admissionEditor.edit admission_edit = _admissionEditor.edit
# Edition simultanee de identite et admission # Edition simultanee de identite et admission
class EtudIdentEditor(object): class EtudIdentEditor(object):
def create(self, cnx, args): def create(self, cnx, args):
@ -615,7 +603,6 @@ class EtudIdentEditor(object):
_etudidentEditor = EtudIdentEditor() _etudidentEditor = EtudIdentEditor()
etudident_list = _etudidentEditor.list etudident_list = _etudidentEditor.list
etudident_edit = _etudidentEditor.edit etudident_edit = _etudidentEditor.edit
etudident_create = _etudidentEditor.create
def log_unknown_etud(): def log_unknown_etud():
@ -654,8 +641,8 @@ def get_etud_info(etudid=False, code_nip=False, filled=False) -> list[dict]:
# return etud[0] # return etud[0]
def create_etud(cnx, args={}): def create_etud(cnx, args: dict = None):
"""Creation d'un étudiant. génère aussi évenement et "news". """Création d'un étudiant. Génère aussi évenement et "news".
Args: Args:
args: dict avec les attributs de l'étudiant args: dict avec les attributs de l'étudiant
@ -666,16 +653,12 @@ def create_etud(cnx, args={}):
from app.models import ScolarNews from app.models import ScolarNews
# creation d'un etudiant # creation d'un etudiant
etudid = etudident_create(cnx, args) args_dict = Identite.convert_dict_fields(args)
# crée une adresse vide (chaque etudiant doit etre dans la table "adresse" !) args_dict["dept_id"] = g.scodoc_dept_id
_ = adresse_create( etud = Identite.create_etud(**args_dict)
cnx, db.session.add(etud)
{ db.session.commit()
"etudid": etudid, etudid = etud.id
"typeadresse": "domicile",
"description": "(creation individuelle)",
},
)
# event # event
scolar_events_create( scolar_events_create(

View File

@ -40,7 +40,7 @@ import app.scodoc.sco_utils as scu
import app.scodoc.notesdb as ndb import app.scodoc.notesdb as ndb
from app import log from app import log
from app.models import ScolarNews, GroupDescr from app.models import ScolarNews, GroupDescr
from app.models.etudiants import input_civilite
from app.scodoc.sco_excel import COLORS from app.scodoc.sco_excel import COLORS
from app.scodoc.sco_formsemestre_inscriptions import ( from app.scodoc.sco_formsemestre_inscriptions import (
do_formsemestre_inscription_with_modules, do_formsemestre_inscription_with_modules,
@ -370,7 +370,7 @@ def scolars_import_excel_file(
# xxx Ad-hoc checks (should be in format description) # xxx Ad-hoc checks (should be in format description)
if titleslist[i].lower() == "sexe": if titleslist[i].lower() == "sexe":
try: try:
val = sco_etud.input_civilite(val) val = input_civilite(val)
except: except:
raise ScoValueError( raise ScoValueError(
"valeur invalide pour 'SEXE' (doit etre 'M', 'F', ou 'MME', 'H', 'X' ou vide, mais pas '%s') ligne %d, colonne %s" "valeur invalide pour 'SEXE' (doit etre 'M', 'F', ou 'MME', 'H', 'X' ou vide, mais pas '%s') ligne %d, colonne %s"

View File

@ -1742,8 +1742,12 @@ def _etudident_create_or_edit_form(edit):
etudid = etud["etudid"] etudid = etud["etudid"]
else: else:
# modif d'un etudiant # modif d'un etudiant
sco_etud.etudident_edit(cnx, tf[2]) args_dict = Identite.convert_dict_fields(tf[2])
etud = sco_etud.etudident_list(cnx, {"etudid": etudid})[0] etud_o = Identite.create_etud(**args_dict)
db.session.add(etud_o)
db.session.commit()
etud = sco_etud.etudident_list(cnx, {"etudid": etud_o.id})[0]
sco_etud.fill_etuds_info([etud]) sco_etud.fill_etuds_info([etud])
# Inval semesters with this student: # Inval semesters with this student:
to_inval = [s["formsemestre_id"] for s in etud["sems"]] to_inval = [s["formsemestre_id"] for s in etud["sems"]]