diff --git a/app/models/etudiants.py b/app/models/etudiants.py index 79454226..fb20313f 100644 --- a/app/models/etudiants.py +++ b/app/models/etudiants.py @@ -242,6 +242,8 @@ class Identite(db.Model): 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) + args_dict.pop("id", None) + args_dict.pop("etudid", None) for key, value in args_dict.items(): if hasattr(self, key): setattr(self, key, value) @@ -601,7 +603,23 @@ def input_civilite(s): return "F" elif s == "X" or not s: return "X" - raise ScoValueError("valeur invalide pour la civilité: %s" % s) + raise ScoValueError(f"valeur invalide pour la civilité: {s}") + + +PIVOT_YEAR = 70 + + +def pivot_year(y) -> int: + "converti et calcule l'année si saisie à deux chiffres" + if y == "" or y is None: + return None + y = int(round(float(y))) + if y >= 0 and y < 100: + if y < PIVOT_YEAR: + y = y + 2000 + else: + y = y + 1900 + return y class Adresse(db.Model): @@ -697,19 +715,51 @@ class Admission(db.Model): d = dict(self.__dict__) d.pop("_sa_instance_state", None) if no_nulls: - for k in d.keys(): - if d[k] is None: + for key, value in d.items(): + if value is None: col_type = getattr( - sqlalchemy.inspect(models.Admission).columns, "apb_groupe" + sqlalchemy.inspect(models.Admission).columns, key ).expression.type if isinstance(col_type, sqlalchemy.Text): - d[k] = "" + d[key] = "" elif isinstance(col_type, sqlalchemy.Integer): - d[k] = 0 + d[key] = 0 elif isinstance(col_type, sqlalchemy.Boolean): - d[k] = False + d[key] = False return d + @classmethod + def convert_dict_fields(cls, args: dict) -> dict: + "Convert fields in the given dict. No other side effect" + fs_uppercase = {"bac", "specialite"} + args_dict = {} + for key, value in args.items(): + if hasattr(cls, key): + if ( + value == "" + ): # les chaines vides donne des NULLS (scodoc7 convention) + 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": + value = ndb.int_null_is_null(value) + args_dict[key] = value + return args_dict + + def from_dict(self, args: dict): # TODO à refactoriser dans une super-classe + "update fields given in dict. Add to session but don't commit." + args_dict = Admission.convert_dict_fields(args) + args_dict.pop("adm_id", None) + args_dict.pop("id", None) + for key, value in args_dict.items(): + if hasattr(self, key): + setattr(self, key, value) + db.session.add(self) + # Suivi scolarité / débouchés class ItemSuivi(db.Model): diff --git a/app/scodoc/sco_etud.py b/app/scodoc/sco_etud.py index 2176b26b..7cdb19a0 100644 --- a/app/scodoc/sco_etud.py +++ b/app/scodoc/sco_etud.py @@ -38,7 +38,7 @@ 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 +from app.models.etudiants import input_civilite, 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 @@ -189,21 +189,6 @@ def format_pays(s): return "" -PIVOT_YEAR = 70 - - -def pivot_year(y): - if y == "" or y is None: - return None - y = int(round(float(y))) - if y >= 0 and y < 100: - if y < PIVOT_YEAR: - y = y + 2000 - else: - y = y + 1900 - return y - - def etud_sort_key(etud: dict) -> tuple: """Clé de tri pour les étudiants représentés par des dict (anciens codes). Equivalent moderne: identite.sort_key @@ -637,19 +622,6 @@ def get_etud_info(etudid=False, code_nip=False, filled=False) -> list[dict]: return etud -# Optim par cache local, utilité non prouvée mais -# on s'oriente vers un cahce persistent dans Redis ou bien l'utilisation de NT -# def get_etud_info_filled_by_etudid(etudid, cnx=None) -> dict: -# """Infos sur un étudiant, avec cache local à la requête""" -# if etudid in g.stored_etud_info: -# return g.stored_etud_info[etudid] -# cnx = cnx or ndb.GetDBConnexion() -# etud = etudident_list(cnx, args={"etudid": etudid}) -# fill_etuds_info(etud) -# g.stored_etud_info[etudid] = etud[0] -# return etud[0] - - def create_etud(cnx, args: dict = None): """Création d'un étudiant. Génère aussi évenement et "news". @@ -667,6 +639,10 @@ def create_etud(cnx, args: dict = None): etud = Identite.create_etud(**args_dict) db.session.add(etud) db.session.commit() + admission = etud.admission.first() + admission.from_dict(args) + db.session.add(admission) + db.session.commit() etudid = etud.id # event diff --git a/app/views/scolar.py b/app/views/scolar.py index 44084b50..a53df3f3 100644 --- a/app/views/scolar.py +++ b/app/views/scolar.py @@ -1742,9 +1742,12 @@ def _etudident_create_or_edit_form(edit): etudid = etud["etudid"] else: # modif d'un etudiant - args_dict = Identite.convert_dict_fields(tf[2]) - etud_o = Identite.create_etud(**args_dict) + etud_o = Identite.query.get(tf[2]["etudid"]) + etud_o.from_dict(tf[2]) db.session.add(etud_o) + admission = etud_o.admission.first() + admission.from_dict(tf[2]) + db.session.add(admission) db.session.commit() etud = sco_etud.etudident_list(cnx, {"etudid": etud_o.id})[0]