Clonage formation: conserve ue_code, même si vide
This commit is contained in:
parent
431dd20911
commit
79f07deac0
@ -5,6 +5,7 @@ from flask import g
|
||||
import pandas as pd
|
||||
|
||||
from app import db, log
|
||||
from app import models
|
||||
from app.models import APO_CODE_STR_LEN
|
||||
from app.models import SHORT_STR_LEN
|
||||
from app.models.but_refcomp import ApcNiveau, ApcParcours
|
||||
@ -12,7 +13,7 @@ from app.models.modules import Module
|
||||
from app.scodoc import sco_utils as scu
|
||||
|
||||
|
||||
class UniteEns(db.Model):
|
||||
class UniteEns(models.ScoDocModel):
|
||||
"""Unité d'Enseignement (UE)"""
|
||||
|
||||
__tablename__ = "notes_ue"
|
||||
@ -81,7 +82,7 @@ class UniteEns(db.Model):
|
||||
'EXTERNE' if self.is_external else ''})>"""
|
||||
|
||||
def clone(self):
|
||||
"""Create a new copy of this ue.
|
||||
"""Create a new copy of this ue, add to session.
|
||||
Ne copie pas le code, ni le code Apogée, ni les liens au réf. de comp.
|
||||
(parcours et niveau).
|
||||
"""
|
||||
@ -100,8 +101,26 @@ class UniteEns(db.Model):
|
||||
coef_rcue=self.coef_rcue,
|
||||
color=self.color,
|
||||
)
|
||||
db.session.add(ue)
|
||||
return ue
|
||||
|
||||
@classmethod
|
||||
def convert_dict_fields(cls, args: dict) -> dict:
|
||||
"""Convert fields from the given dict to model's attributes values. No side effect.
|
||||
|
||||
args: dict with args in application.
|
||||
returns: dict to store in model's db.
|
||||
"""
|
||||
args = args.copy()
|
||||
if "type" in args:
|
||||
args["type"] = int(args["type"] or 0)
|
||||
if "is_external" in args:
|
||||
args["is_external"] = scu.to_bool(args["is_external"])
|
||||
if "ects" in args:
|
||||
args["ects"] = float(args["ects"])
|
||||
|
||||
return args
|
||||
|
||||
def to_dict(self, convert_objects=False, with_module_ue_coefs=True):
|
||||
"""as a dict, with the same conversions as in ScoDoc7.
|
||||
If convert_objects, convert all attributes to native types
|
||||
|
@ -300,6 +300,7 @@ class EditableTable(object):
|
||||
output_formators={},
|
||||
input_formators={},
|
||||
aux_tables=[],
|
||||
convert_empty_to_nulls=True, # les arguments vides sont traduits en NULL
|
||||
convert_null_outputs_to_empty=True,
|
||||
html_quote=False, # changed in 9.0.10
|
||||
fields_creators={}, # { field : [ sql_command_to_create_it ] }
|
||||
@ -321,6 +322,7 @@ class EditableTable(object):
|
||||
self.output_formators = output_formators
|
||||
self.input_formators = input_formators
|
||||
self.convert_null_outputs_to_empty = convert_null_outputs_to_empty
|
||||
self.convert_empty_to_nulls = convert_empty_to_nulls
|
||||
self.html_quote = html_quote
|
||||
self.fields_creators = fields_creators
|
||||
self.filter_nulls = filter_nulls
|
||||
@ -351,6 +353,7 @@ class EditableTable(object):
|
||||
self.table_name,
|
||||
vals,
|
||||
commit=True,
|
||||
convert_empty_to_nulls=self.convert_empty_to_nulls,
|
||||
return_id=(self.id_name is not None),
|
||||
ignore_conflicts=self.insert_ignore_conflicts,
|
||||
)
|
||||
@ -444,7 +447,7 @@ def dictfilter(d, fields, filter_nulls=True):
|
||||
"""returns a copy of d with only keys listed in "fields" and non null values"""
|
||||
r = {}
|
||||
for f in fields:
|
||||
if f in d and (d[f] != None or not filter_nulls):
|
||||
if f in d and (d[f] is not None or not filter_nulls):
|
||||
try:
|
||||
val = d[f].strip()
|
||||
except:
|
||||
|
@ -89,6 +89,7 @@ _ueEditor = ndb.EditableTable(
|
||||
"color",
|
||||
"niveau_competence_id",
|
||||
),
|
||||
convert_empty_to_nulls=False, # necessaire pour ue_code == ""
|
||||
sortkey="numero",
|
||||
input_formators={
|
||||
"type": ndb.int_null_is_zero,
|
||||
@ -110,7 +111,7 @@ def ue_list(*args, **kw):
|
||||
return _ueEditor.list(cnx, *args, **kw)
|
||||
|
||||
|
||||
def do_ue_create(args):
|
||||
def do_ue_create(args, allow_empty_ue_code=False):
|
||||
"create an ue"
|
||||
cnx = ndb.GetDBConnexion()
|
||||
# check duplicates
|
||||
@ -120,18 +121,18 @@ def do_ue_create(args):
|
||||
f"""Acronyme d'UE "{args['acronyme']}" déjà utilisé !
|
||||
(chaque UE doit avoir un acronyme unique dans la formation)"""
|
||||
)
|
||||
if (
|
||||
(not "ue_code" in args)
|
||||
or (args["ue_code"] is None)
|
||||
or (not args["ue_code"].strip())
|
||||
):
|
||||
# évite les conflits de code
|
||||
while True:
|
||||
cursor = db.session.execute(sa.text("select notes_newid_ucod();"))
|
||||
code = cursor.fetchone()[0]
|
||||
if UniteEns.query.filter_by(ue_code=code).count() == 0:
|
||||
break
|
||||
args["ue_code"] = code
|
||||
if "ue_code" not in args or args["ue_code"] is None or not args["ue_code"].strip():
|
||||
if allow_empty_ue_code:
|
||||
args["ue_code"] = ""
|
||||
else:
|
||||
# évite les conflits: génère nouveau ue_code
|
||||
while True:
|
||||
cursor = db.session.execute(sa.text("select notes_newid_ucod();"))
|
||||
code = cursor.fetchone()[0]
|
||||
if UniteEns.query.filter_by(ue_code=code).count() == 0:
|
||||
break
|
||||
args["ue_code"] = code
|
||||
|
||||
# create
|
||||
ue_id = _ueEditor.create(cnx, args)
|
||||
log(f"do_ue_create: created {ue_id} with {args}")
|
||||
|
@ -168,16 +168,14 @@ def formsemestre_associate_new_version(
|
||||
formation_id=new_formation_id,
|
||||
)
|
||||
)
|
||||
else:
|
||||
return flask.redirect(
|
||||
url_for(
|
||||
"notes.formsemestre_status",
|
||||
scodoc_dept=g.scodoc_dept,
|
||||
formsemestre_id=formsemestre_id,
|
||||
)
|
||||
return flask.redirect(
|
||||
url_for(
|
||||
"notes.formsemestre_status",
|
||||
scodoc_dept=g.scodoc_dept,
|
||||
formsemestre_id=formsemestre_id,
|
||||
)
|
||||
else:
|
||||
raise ScoValueError("Méthode invalide")
|
||||
)
|
||||
raise ScoValueError("Méthode invalide")
|
||||
|
||||
|
||||
def do_formsemestres_associate_new_version(
|
||||
|
@ -117,6 +117,7 @@ def formation_export_dict(
|
||||
ues = ues.all()
|
||||
ues.sort(key=lambda u: (u.semestre_idx or 0, u.numero or 0, u.acronyme))
|
||||
f_dict["ue"] = []
|
||||
ue: UniteEns
|
||||
for ue in ues:
|
||||
ue_dict = ue.to_dict()
|
||||
f_dict["ue"].append(ue_dict)
|
||||
@ -363,7 +364,9 @@ def formation_import_xml(doc: str, import_tags=True, use_local_refcomp=False):
|
||||
ue_info[1]["niveau_competence_id"] = _formation_retreive_apc_niveau(
|
||||
referentiel_competence_id, ue_info[1]
|
||||
)
|
||||
ue_id = sco_edit_ue.do_ue_create(ue_info[1])
|
||||
# Note: si le code est indiqué "" dans le xml, il faut le conserver vide
|
||||
# pour la comparaison ultérieure des formations XXX
|
||||
ue_id = sco_edit_ue.do_ue_create(ue_info[1], allow_empty_ue_code=True)
|
||||
ue: UniteEns = db.session.get(UniteEns, ue_id)
|
||||
assert ue
|
||||
if xml_ue_id:
|
||||
|
@ -824,7 +824,6 @@ def ue_clone():
|
||||
ue_id = int(request.form.get("ue_id"))
|
||||
ue = UniteEns.query.get_or_404(ue_id)
|
||||
ue2 = ue.clone()
|
||||
db.session.add(ue2)
|
||||
db.session.commit()
|
||||
flash(f"UE {ue.acronyme} dupliquée")
|
||||
return flask.redirect(
|
||||
|
Loading…
Reference in New Issue
Block a user