From 2f16a2f4dfeaf6d4784b745d9a2f3f1cfca9b508 Mon Sep 17 00:00:00 2001 From: Emmanuel Viennet Date: Mon, 15 May 2023 19:50:11 +0200 Subject: [PATCH] =?UTF-8?q?Modification=20cr=C3=A9ation/=C3=A9dition=20?= =?UTF-8?q?=C3=A9tudiants?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/etudiants.py | 61 ++++++++++++++++++++++++++++++++-- app/scodoc/notesdb.py | 4 +-- app/scodoc/sco_etud.py | 47 +++++++++----------------- app/scodoc/sco_import_etuds.py | 4 +-- app/views/scolar.py | 8 +++-- 5 files changed, 84 insertions(+), 40 deletions(-) diff --git a/app/models/etudiants.py b/app/models/etudiants.py index 61f34296b..9b2c164c2 100644 --- a/app/models/etudiants.py +++ b/app/models/etudiants.py @@ -18,7 +18,7 @@ from app import models from app.scodoc import notesdb as ndb 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 @@ -100,7 +100,7 @@ class Identite(db.Model): def create_etud(cls, **args): "Crée un étudiant, avec admission et adresse vides." etud: Identite = cls(**args) - etud.adresses.append(Adresse()) + etud.adresses.append(Adresse(typeadresse="domicile")) etud.admission.append(Admission()) return etud @@ -201,6 +201,48 @@ class Identite(db.Model): 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: """Les champs essentiels""" return { @@ -543,6 +585,21 @@ def make_etud_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): """Adresse d'un étudiant (le modèle permet plusieurs adresses, mais l'UI n'en gère qu'une seule) diff --git a/app/scodoc/notesdb.py b/app/scodoc/notesdb.py index e2cb304e3..4d9b6aa2a 100644 --- a/app/scodoc/notesdb.py +++ b/app/scodoc/notesdb.py @@ -186,7 +186,7 @@ def DBSelectArgs( cond = "" i = 1 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)) i = i + 1 cond += " and ".join(cl) @@ -403,7 +403,7 @@ class EditableTable(object): def format_output(self, r, disable_formatting=False): "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: v = "" # format value diff --git a/app/scodoc/sco_etud.py b/app/scodoc/sco_etud.py index 70b7b1636..4c88f5302 100644 --- a/app/scodoc/sco_etud.py +++ b/app/scodoc/sco_etud.py @@ -35,10 +35,10 @@ from operator import itemgetter from flask import url_for, g -from app import email +from app import db, email from app import log -from app.models import Admission -from app.models.etudiants import make_etud_args +from app.models import Admission, Identite +from app.models.etudiants import input_civilite, make_etud_args import app.scodoc.sco_utils as scu import app.scodoc.notesdb as ndb from app.scodoc.sco_exceptions import ScoGenError, ScoValueError @@ -127,21 +127,6 @@ def format_nom(s, uppercase=True): 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): """returns 'M.' ou 'Mme' ou '' (pour le genre neutre, personne ne souhaitant pas d'affichage). @@ -281,7 +266,9 @@ def identite_list(cnx, *a, **kw): def identite_edit_nocheck(cnx, args): """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): @@ -572,6 +559,7 @@ admission_delete = _admissionEditor.delete admission_list = _admissionEditor.list admission_edit = _admissionEditor.edit + # Edition simultanee de identite et admission class EtudIdentEditor(object): def create(self, cnx, args): @@ -615,7 +603,6 @@ class EtudIdentEditor(object): _etudidentEditor = EtudIdentEditor() etudident_list = _etudidentEditor.list etudident_edit = _etudidentEditor.edit -etudident_create = _etudidentEditor.create def log_unknown_etud(): @@ -654,8 +641,8 @@ def get_etud_info(etudid=False, code_nip=False, filled=False) -> list[dict]: # return etud[0] -def create_etud(cnx, args={}): - """Creation d'un étudiant. génère aussi évenement et "news". +def create_etud(cnx, args: dict = None): + """Création d'un étudiant. Génère aussi évenement et "news". Args: args: dict avec les attributs de l'étudiant @@ -666,16 +653,12 @@ def create_etud(cnx, args={}): from app.models import ScolarNews # creation d'un etudiant - etudid = etudident_create(cnx, args) - # crée une adresse vide (chaque etudiant doit etre dans la table "adresse" !) - _ = adresse_create( - cnx, - { - "etudid": etudid, - "typeadresse": "domicile", - "description": "(creation individuelle)", - }, - ) + args_dict = Identite.convert_dict_fields(args) + args_dict["dept_id"] = g.scodoc_dept_id + etud = Identite.create_etud(**args_dict) + db.session.add(etud) + db.session.commit() + etudid = etud.id # event scolar_events_create( diff --git a/app/scodoc/sco_import_etuds.py b/app/scodoc/sco_import_etuds.py index 2d67c08cd..736d60212 100644 --- a/app/scodoc/sco_import_etuds.py +++ b/app/scodoc/sco_import_etuds.py @@ -40,7 +40,7 @@ import app.scodoc.sco_utils as scu import app.scodoc.notesdb as ndb from app import log from app.models import ScolarNews, GroupDescr - +from app.models.etudiants import input_civilite from app.scodoc.sco_excel import COLORS from app.scodoc.sco_formsemestre_inscriptions import ( do_formsemestre_inscription_with_modules, @@ -370,7 +370,7 @@ def scolars_import_excel_file( # xxx Ad-hoc checks (should be in format description) if titleslist[i].lower() == "sexe": try: - val = sco_etud.input_civilite(val) + val = input_civilite(val) except: raise ScoValueError( "valeur invalide pour 'SEXE' (doit etre 'M', 'F', ou 'MME', 'H', 'X' ou vide, mais pas '%s') ligne %d, colonne %s" diff --git a/app/views/scolar.py b/app/views/scolar.py index 390ba2396..44084b501 100644 --- a/app/views/scolar.py +++ b/app/views/scolar.py @@ -1742,8 +1742,12 @@ def _etudident_create_or_edit_form(edit): etudid = etud["etudid"] else: # modif d'un etudiant - sco_etud.etudident_edit(cnx, tf[2]) - etud = sco_etud.etudident_list(cnx, {"etudid": etudid})[0] + args_dict = Identite.convert_dict_fields(tf[2]) + 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]) # Inval semesters with this student: to_inval = [s["formsemestre_id"] for s in etud["sems"]]