1
0
forked from ScoDoc/ScoDoc

Bools. Edit formsemestre ok.

This commit is contained in:
Emmanuel Viennet 2021-08-11 00:36:07 +02:00
parent 4a43e96fe9
commit 055dcfea36
33 changed files with 223 additions and 166 deletions

View File

@ -9,6 +9,7 @@ import json
import os import os
import re import re
from time import time from time import time
from typing import Optional
from flask import current_app, url_for, g from flask import current_app, url_for, g
from flask_login import UserMixin, AnonymousUserMixin from flask_login import UserMixin, AnonymousUserMixin
@ -265,12 +266,16 @@ class User(UserMixin, db.Model):
) )
@staticmethod @staticmethod
def get_user_name_from_nomplogin(nomplogin): def get_user_id_from_nomplogin(nomplogin: str) -> Optional[int]:
"""Returns user_name from the string "Dupont Pierre (dupont)" """ """Returns id from the string "Dupont Pierre (dupont)"
or None if user does not exist
"""
m = re.match(r".*\((.*)\)", nomplogin.strip()) m = re.match(r".*\((.*)\)", nomplogin.strip())
if m: if m:
return m.group(1) user_name = m.group(1)
else: u = User.query.filter_by(user_name=user_name).first()
if u:
return u.id
return None return None
def get_nom_fmt(self): def get_nom_fmt(self):

View File

@ -199,7 +199,7 @@ def scodoc7func(context):
# necessary for db ids and boolean values # necessary for db ids and boolean values
try: try:
v = int(v) v = int(v)
except ValueError: except (ValueError, TypeError):
pass pass
kwargs[arg_name] = v kwargs[arg_name] = v
# current_app.logger.info( # current_app.logger.info(

View File

@ -287,9 +287,9 @@ class NotesEvaluation(db.Model):
publish_incomplete = db.Column( publish_incomplete = db.Column(
db.Boolean, nullable=False, default=False, server_default="false" db.Boolean, nullable=False, default=False, server_default="false"
) )
# type d'evaluation: False normale, True rattrapage: # type d'evaluation: 0 normale, 1 rattrapage, 2 "2eme session"
evaluation_type = db.Column( evaluation_type = db.Column(
db.Boolean, nullable=False, default=False, server_default="false" db.Integer, nullable=False, default=0, server_default="0"
) )
# ordre de presentation (par défaut, le plus petit numero # ordre de presentation (par défaut, le plus petit numero
# est la plus ancienne eval): # est la plus ancienne eval):

View File

@ -209,7 +209,10 @@ class TF(object):
# convert numbers, except ids # convert numbers, except ids
if field.endswith("id") and self.values[field]: if field.endswith("id") and self.values[field]:
# enforce integer ids: # enforce integer ids:
try:
self.values[field] = int(self.values[field]) self.values[field] = int(self.values[field])
except ValueError:
pass
elif isinstance(self.values[field], (int, float)): elif isinstance(self.values[field], (int, float)):
self.values[field] = str(self.values[field]) self.values[field] = str(self.values[field])
# #
@ -299,9 +302,9 @@ class TF(object):
# boolean checkbox # boolean checkbox
if descr.get("input_type", None) == "boolcheckbox": if descr.get("input_type", None) == "boolcheckbox":
if int(val): if int(val):
self.values[field] = 1 self.values[field] = True
else: else:
self.values[field] = 0 self.values[field] = False
# open('/tmp/toto','a').write('checkvalues: val=%s (%s) values[%s] = %s\n' % (val, type(val), field, self.values[field])) # open('/tmp/toto','a').write('checkvalues: val=%s (%s) values[%s] = %s\n' % (val, type(val), field, self.values[field]))
if descr.get("convert_numbers", False): if descr.get("convert_numbers", False):
if typ[:3] == "int": if typ[:3] == "int":
@ -493,10 +496,15 @@ class TF(object):
checked = "" checked = ""
else: # boolcheckbox else: # boolcheckbox
# open('/tmp/toto','a').write('GenForm: values[%s] = %s (%s)\n' % (field, values[field], type(values[field]))) # open('/tmp/toto','a').write('GenForm: values[%s] = %s (%s)\n' % (field, values[field], type(values[field])))
if values[field] == "True":
v = True
elif values[field] == "False":
v = False
else:
try: try:
v = int(values[field]) v = int(values[field])
except: except:
v = 0 v = False
if v: if v:
checked = 'checked="checked"' checked = 'checked="checked"'
else: else:
@ -562,7 +570,7 @@ class TF(object):
'<input type="text" name="%s" id="%s" size="%d" %s' '<input type="text" name="%s" id="%s" size="%d" %s'
% (field, field, size, attribs) % (field, field, size, attribs)
) )
lem.append('value="%(' + field + ')s" />' % values) lem.append(('value="%(' + field + ')s" />') % values)
suggest_js.append( suggest_js.append(
f"""var {field}_opts = {dict2js(descr.get("text_suggest_options", {}))}; f"""var {field}_opts = {dict2js(descr.get("text_suggest_options", {}))};
var {field}_as = new bsn.AutoSuggest('{field}', {field}_opts); var {field}_as = new bsn.AutoSuggest('{field}', {field}_opts);

View File

@ -800,7 +800,7 @@ class NotesTable(object):
# was_capitalized s'il y a precedemment une UE capitalisée (pas forcement meilleure) # was_capitalized s'il y a precedemment une UE capitalisée (pas forcement meilleure)
mu["was_capitalized"] = False mu["was_capitalized"] = False
is_external = 0 is_external = False
event_date = None event_date = None
if not block_computation: if not block_computation:
for ue_cap in self.ue_capitalisees[etudid]: for ue_cap in self.ue_capitalisees[etudid]:
@ -1098,7 +1098,7 @@ class NotesTable(object):
if self.get_etud_etat(etudid) == DEF: if self.get_etud_etat(etudid) == DEF:
return { return {
"code": DEF, "code": DEF,
"assidu": 0, "assidu": False,
"event_date": "", "event_date": "",
"compense_formsemestre_id": None, "compense_formsemestre_id": None,
} }

View File

@ -764,6 +764,10 @@ _billet_absenceEditor = ndb.EditableTable(
"justified", "justified",
), ),
sortkey="entry_date desc", sortkey="entry_date desc",
input_formators={
"etat": bool,
"justified": bool,
},
) )
billet_absence_create = _billet_absenceEditor.create billet_absence_create = _billet_absenceEditor.create

View File

@ -514,7 +514,7 @@ def _ue_mod_bulletin(context, etudid, formsemestre_id, ue_id, modimpls, nt, vers
mod["evaluations"] = [] mod["evaluations"] = []
for e in evals: for e in evals:
e = e.copy() e = e.copy()
if int(e["visibulletin"]) == 1 or version == "long": if e["visibulletin"] or version == "long":
# affiche "bonus" quand les points de malus sont négatifs # affiche "bonus" quand les points de malus sont négatifs
if is_malus: if is_malus:
val = e["notes"].get(etudid, {"value": "NP"})[ val = e["notes"].get(etudid, {"value": "NP"})[

View File

@ -94,7 +94,7 @@ def formsemestre_bulletinetud_published_dict(
d = {} d = {}
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
if sem["bul_hide_xml"] == "0" or force_publishing: if (not sem["bul_hide_xml"]) or force_publishing:
published = 1 published = 1
else: else:
published = 0 published = 0
@ -264,7 +264,7 @@ def formsemestre_bulletinetud_published_dict(
m["evaluation"] = [] m["evaluation"] = []
if version != "short": if version != "short":
for e in evals: for e in evals:
if int(e["visibulletin"]) == 1 or version == "long": if e["visibulletin"] or version == "long":
val = e["notes"].get(etudid, {"value": "NP"})[ val = e["notes"].get(etudid, {"value": "NP"})[
"value" "value"
] # NA si etud demissionnaire ] # NA si etud demissionnaire

View File

@ -155,7 +155,7 @@ class BulletinGeneratorLegacy(sco_bulletins_generator.BulletinGenerator):
if self.version != "short": if self.version != "short":
# --- notes de chaque eval: # --- notes de chaque eval:
for e in mod["evaluations"]: for e in mod["evaluations"]:
if int(e["visibulletin"]) == 1 or self.version == "long": if e["visibulletin"] or self.version == "long":
H.append( H.append(
'<tr class="notes_bulletin_row_eval%s">' % rowstyle '<tr class="notes_bulletin_row_eval%s">' % rowstyle
) )
@ -492,7 +492,7 @@ def _bulletin_pdf_table_legacy(context, I, version="long"):
if version != "short": if version != "short":
# --- notes de chaque eval: # --- notes de chaque eval:
for e in mod["evaluations"]: for e in mod["evaluations"]:
if int(e["visibulletin"]) == 1 or version == "long": if e["visibulletin"] or version == "long":
S.newline(ue_type=ue_type) S.newline(ue_type=ue_type)
t = ["", "", e["name"], e["note_txt"], e["coef_txt"]] t = ["", "", e["name"], e["note_txt"], e["coef_txt"]]
if bul_show_abs_modules: if bul_show_abs_modules:

View File

@ -647,7 +647,7 @@ class BulletinGeneratorStandard(sco_bulletins_generator.BulletinGenerator):
# --- notes de chaque eval: # --- notes de chaque eval:
nbeval = 0 nbeval = 0
for e in evals: for e in evals:
if int(e["visibulletin"]) == 1 or self.version == "long": if e["visibulletin"] or self.version == "long":
if nbeval == 0: if nbeval == 0:
eval_style = " b_eval_first" eval_style = " b_eval_first"
else: else:

View File

@ -82,7 +82,7 @@ def make_xml_formsemestre_bulletinetud(
REQUEST.RESPONSE.setHeader("content-type", scu.XML_MIMETYPE) REQUEST.RESPONSE.setHeader("content-type", scu.XML_MIMETYPE)
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
if sem["bul_hide_xml"] == "0" or force_publishing: if (not sem["bul_hide_xml"]) or force_publishing:
published = "1" published = "1"
else: else:
published = "0" published = "0"
@ -270,7 +270,7 @@ def make_xml_formsemestre_bulletinetud(
evals = nt.get_evals_in_mod(modimpl["moduleimpl_id"]) evals = nt.get_evals_in_mod(modimpl["moduleimpl_id"])
if version != "short": if version != "short":
for e in evals: for e in evals:
if int(e["visibulletin"]) == 1 or version == "long": if e["visibulletin"] or version == "long":
x_eval = Element( x_eval = Element(
"evaluation", "evaluation",
jour=ndb.DateDMYtoISO(e["jour"], null_is_empty=True), jour=ndb.DateDMYtoISO(e["jour"], null_is_empty=True),

View File

@ -290,7 +290,7 @@ def do_moduleimpl_moyennes(context, nt, mod):
sum_coefs += e["coefficient"] sum_coefs += e["coefficient"]
else: else:
# il manque une note ! (si publish_incomplete, cela peut arriver, on ignore) # il manque une note ! (si publish_incomplete, cela peut arriver, on ignore)
if e["coefficient"] > 0 and e["publish_incomplete"] == "0": if e["coefficient"] > 0 and not e["publish_incomplete"]:
nb_missing += 1 nb_missing += 1
if nb_missing == 0 and sum_coefs > 0: if nb_missing == 0 and sum_coefs > 0:
if sum_coefs > 0: if sum_coefs > 0:

View File

@ -72,7 +72,10 @@ _ueEditor = ndb.EditableTable(
"coefficient", "coefficient",
), ),
sortkey="numero", sortkey="numero",
input_formators={"type": ndb.int_null_is_zero}, input_formators={
"type": ndb.int_null_is_zero,
"is_external": bool,
},
output_formators={ output_formators={
"numero": ndb.int_null_is_zero, "numero": ndb.int_null_is_zero,
"ects": ndb.float_null_is_null, "ects": ndb.float_null_is_null,

View File

@ -149,7 +149,10 @@ _entreprisesEditor = EntreprisesEditor(
"date_creation", "date_creation",
), ),
sortkey="nom", sortkey="nom",
input_formators={"nom": _format_nom}, input_formators={
"nom": _format_nom,
"plus10salaries": bool,
},
) )
# ----------- Correspondants # ----------- Correspondants

View File

@ -264,6 +264,7 @@ _identiteEditor = ndb.EditableTable(
"prenom": force_uppercase, "prenom": force_uppercase,
"civilite": input_civilite, "civilite": input_civilite,
"date_naissance": ndb.DateDMYtoISO, "date_naissance": ndb.DateDMYtoISO,
"boursier": bool,
}, },
output_formators={"date_naissance": ndb.DateISOtoDMY}, output_formators={"date_naissance": ndb.DateISOtoDMY},
convert_null_outputs_to_empty=True, convert_null_outputs_to_empty=True,

View File

@ -115,8 +115,6 @@ _evaluationEditor = ndb.EditableTable(
sortkey="numero desc, jour desc, heure_debut desc", # plus recente d'abord sortkey="numero desc, jour desc, heure_debut desc", # plus recente d'abord
output_formators={ output_formators={
"jour": ndb.DateISOtoDMY, "jour": ndb.DateISOtoDMY,
"visibulletin": bool,
"publish_incomplete": bool,
"numero": ndb.int_null_is_zero, "numero": ndb.int_null_is_zero,
}, },
input_formators={ input_formators={
@ -125,6 +123,7 @@ _evaluationEditor = ndb.EditableTable(
"heure_fin": ndb.TimetoISO8601, # converti par do_evaluation_list "heure_fin": ndb.TimetoISO8601, # converti par do_evaluation_list
"visibulletin": bool, "visibulletin": bool,
"publish_incomplete": bool, "publish_incomplete": bool,
"evaluation_type": int,
}, },
) )
@ -494,14 +493,14 @@ def do_evaluation_etat(evaluation_id, partition_id=None, select_first_partition=
complete = True complete = True
if ( if (
TotalNbMissing > 0 TotalNbMissing > 0
and (TotalNbMissing == TotalNbAtt or E["publish_incomplete"] != "0") and ((TotalNbMissing == TotalNbAtt) or E["publish_incomplete"])
and not is_malus and not is_malus
): ):
evalattente = True evalattente = True
else: else:
evalattente = False evalattente = False
# mais ne met pas en attente les evals immediates sans aucune notes: # mais ne met pas en attente les evals immediates sans aucune notes:
if E["publish_incomplete"] != "0" and nb_notes == 0: if E["publish_incomplete"] and nb_notes == 0:
evalattente = False evalattente = False
# Calcul moyenne dans chaque groupe de TD # Calcul moyenne dans chaque groupe de TD
@ -1235,8 +1234,8 @@ def evaluation_create_form(
heures = ["%02dh%02d" % (h, m) for h in range(8, 19) for m in (0, 30)] heures = ["%02dh%02d" % (h, m) for h in range(8, 19) for m in (0, 30)]
# #
initvalues["visibulletin"] = initvalues.get("visibulletin", "1") initvalues["visibulletin"] = initvalues.get("visibulletin", True)
if initvalues["visibulletin"] == "1": if initvalues["visibulletin"]:
initvalues["visibulletinlist"] = ["X"] initvalues["visibulletinlist"] = ["X"]
else: else:
initvalues["visibulletinlist"] = [] initvalues["visibulletinlist"] = []
@ -1372,9 +1371,9 @@ def evaluation_create_form(
else: else:
# form submission # form submission
if tf[2]["visibulletinlist"]: if tf[2]["visibulletinlist"]:
tf[2]["visibulletin"] = 1 tf[2]["visibulletin"] = True
else: else:
tf[2]["visibulletin"] = 0 tf[2]["visibulletin"] = False
if not edit: if not edit:
# creation d'une evaluation # creation d'une evaluation
evaluation_id = do_evaluation_create(REQUEST=REQUEST, **tf[2]) evaluation_id = do_evaluation_create(REQUEST=REQUEST, **tf[2])

View File

@ -106,8 +106,13 @@ def search_etud_in_dept(context, expnom="", REQUEST=None):
expnom: string, regexp sur le nom ou un code_nip ou un etudid expnom: string, regexp sur le nom ou un code_nip ou un etudid
""" """
if len(expnom) > 1: if len(expnom) > 1:
try:
etudid = int(expnom)
except ValueError:
etudid = None
if etudid is not None:
etuds = sco_etud.get_etud_info(filled=1, etudid=expnom, REQUEST=REQUEST) etuds = sco_etud.get_etud_info(filled=1, etudid=expnom, REQUEST=REQUEST)
if len(etuds) != 1: if (etudid is None) or len(etuds) != 1:
if scu.is_valid_code_nip(expnom): if scu.is_valid_code_nip(expnom):
etuds = search_etuds_infos(code_nip=expnom) etuds = search_etuds_infos(code_nip=expnom)
else: else:

View File

@ -69,18 +69,19 @@ _formsemestreEditor = ndb.EditableTable(
output_formators={ output_formators={
"date_debut": ndb.DateISOtoDMY, "date_debut": ndb.DateISOtoDMY,
"date_fin": ndb.DateISOtoDMY, "date_fin": ndb.DateISOtoDMY,
"gestion_compensation": bool,
"gestion_semestrielle": bool,
"etat": bool,
"bul_hide_xml": bool,
}, },
input_formators={ input_formators={
"date_debut": ndb.DateDMYtoISO, "date_debut": ndb.DateDMYtoISO,
"date_fin": ndb.DateDMYtoISO, "date_fin": ndb.DateDMYtoISO,
"etat": bool,
"gestion_compensation": bool,
"bul_hide_xml": bool,
"gestion_semestrielle": bool,
"gestion_compensation": bool, "gestion_compensation": bool,
"gestion_semestrielle": bool, "gestion_semestrielle": bool,
"etat": bool, "resp_can_edit": bool,
"bul_hide_xml": bool, "resp_can_change_ens": bool,
"ens_can_edit_eval": bool,
}, },
) )

View File

@ -29,6 +29,7 @@
""" """
import flask import flask
from flask import url_for, g from flask import url_for, g
from flask_login import current_user
from app.auth.models import User from app.auth.models import User
import app.scodoc.notesdb as ndb import app.scodoc.notesdb as ndb
@ -124,9 +125,8 @@ def formsemestre_editwithmodules(context, REQUEST, formsemestre_id):
def can_edit_sem(context, REQUEST, formsemestre_id="", sem=None): def can_edit_sem(context, REQUEST, formsemestre_id="", sem=None):
"""Return sem if user can edit it, False otherwise""" """Return sem if user can edit it, False otherwise"""
sem = sem or sco_formsemestre.get_formsemestre(context, formsemestre_id) sem = sem or sco_formsemestre.get_formsemestre(context, formsemestre_id)
authuser = REQUEST.AUTHENTICATED_USER if not current_user.has_permission(Permission.ScoImplement): # pas chef
if not authuser.has_permission(Permission.ScoImplement): # pas chef if not sem["resp_can_edit"] or current_user.id not in sem["responsables"]:
if not sem["resp_can_edit"] or str(authuser) not in sem["responsables"]:
return False return False
return sem return sem
@ -137,23 +137,22 @@ def do_formsemestre_createwithmodules(context, REQUEST=None, edit=False):
if edit: if edit:
formsemestre_id = REQUEST.form["formsemestre_id"] formsemestre_id = REQUEST.form["formsemestre_id"]
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
authuser = REQUEST.AUTHENTICATED_USER if not current_user.has_permission(Permission.ScoImplement):
if not authuser.has_permission(Permission.ScoImplement):
if not edit: if not edit:
# il faut ScoImplement pour creer un semestre # il faut ScoImplement pour creer un semestre
raise AccessDenied("vous n'avez pas le droit d'effectuer cette opération") raise AccessDenied("vous n'avez pas le droit d'effectuer cette opération")
else: else:
if not sem["resp_can_edit"] or str(authuser) not in sem["responsables"]: if not sem["resp_can_edit"] or current_user.id not in sem["responsables"]:
raise AccessDenied( raise AccessDenied(
"vous n'avez pas le droit d'effectuer cette opération" "vous n'avez pas le droit d'effectuer cette opération"
) )
# Liste des enseignants avec forme pour affichage / saisie avec suggestion # Liste des enseignants avec forme pour affichage / saisie avec suggestion
userlist = sco_users.get_user_list() userlist = sco_users.get_user_list()
login2display = {} # user_name : forme pour affichage = "NOM Prenom (login)" uid2display = {} # user_name : forme pour affichage = "NOM Prenom (login)"
for u in userlist: for u in userlist:
login2display[u.user_name] = u.get_nomplogin() uid2display[u.id] = u.get_nomplogin()
allowed_user_names = list(login2display.values()) + [""] allowed_user_names = list(uid2display.values()) + [""]
# #
formation_id = REQUEST.form["formation_id"] formation_id = REQUEST.form["formation_id"]
F = sco_formations.formation_list(context, args={"formation_id": formation_id}) F = sco_formations.formation_list(context, args={"formation_id": formation_id})
@ -168,29 +167,22 @@ def do_formsemestre_createwithmodules(context, REQUEST=None, edit=False):
# setup form init values # setup form init values
initvalues = sem initvalues = sem
semestre_id = initvalues["semestre_id"] semestre_id = initvalues["semestre_id"]
# initvalues['inscrire_etuds'] = initvalues.get('inscrire_etuds','1') # add associated modules to tf-checked:
# if initvalues['inscrire_etuds'] == '1':
# initvalues['inscrire_etudslist'] = ['X']
# else:
# initvalues['inscrire_etudslist'] = []
# if REQUEST.form.get('tf-submitted',False) and not REQUEST.form.has_key('inscrire_etudslist'):
# REQUEST.form['inscrire_etudslist'] = []
# add associated modules to tf-checked
ams = sco_moduleimpl.do_moduleimpl_list( ams = sco_moduleimpl.do_moduleimpl_list(
context, formsemestre_id=formsemestre_id context, formsemestre_id=formsemestre_id
) )
sem_module_ids = set([x["module_id"] for x in ams]) sem_module_ids = set([x["module_id"] for x in ams])
initvalues["tf-checked"] = [x["module_id"] for x in ams] initvalues["tf-checked"] = ["MI" + str(x["module_id"]) for x in ams]
for x in ams: for x in ams:
initvalues[str(x["module_id"])] = login2display.get( initvalues["MI" + str(x["module_id"])] = uid2display.get(
x["responsable_id"], x["responsable_id"] x["responsable_id"], x["responsable_id"]
) )
initvalues["responsable_id"] = login2display.get( initvalues["responsable_id"] = uid2display.get(
sem["responsables"][0], sem["responsables"][0] sem["responsables"][0], sem["responsables"][0]
) )
if len(sem["responsables"]) > 1: if len(sem["responsables"]) > 1:
initvalues["responsable_id2"] = login2display.get( initvalues["responsable_id2"] = uid2display.get(
sem["responsables"][1], sem["responsables"][1] sem["responsables"][1], sem["responsables"][1]
) )
@ -200,13 +192,13 @@ def do_formsemestre_createwithmodules(context, REQUEST=None, edit=False):
NB_SEM = parcours.NB_SEM NB_SEM = parcours.NB_SEM
else: else:
NB_SEM = 10 # fallback, max 10 semestres NB_SEM = 10 # fallback, max 10 semestres
semestre_id_list = ["-1"] + [str(x) for x in range(1, NB_SEM + 1)] semestre_id_list = [-1] + list(range(1, NB_SEM + 1))
semestre_id_labels = [] semestre_id_labels = []
for sid in semestre_id_list: for sid in semestre_id_list:
if sid == "-1": if sid == "-1":
semestre_id_labels.append("pas de semestres") semestre_id_labels.append("pas de semestres")
else: else:
semestre_id_labels.append(sid) semestre_id_labels.append(str(sid))
# Liste des modules dans ce semestre de cette formation # Liste des modules dans ce semestre de cette formation
# on pourrait faire un simple module_list( ) # on pourrait faire un simple module_list( )
# mais si on veut l'ordre du PPN (groupe par UE et matieres) il faut: # mais si on veut l'ordre du PPN (groupe par UE et matieres) il faut:
@ -464,7 +456,7 @@ def do_formsemestre_createwithmodules(context, REQUEST=None, edit=False):
}, },
), ),
] ]
if authuser.has_permission(Permission.ScoImplement): if current_user.has_permission(Permission.ScoImplement):
modform += [ modform += [
( (
"resp_can_edit", "resp_can_edit",
@ -627,8 +619,8 @@ def do_formsemestre_createwithmodules(context, REQUEST=None, edit=False):
initvalues["vdi_apo" + str(n)] = etape_vdi.vdi initvalues["vdi_apo" + str(n)] = etape_vdi.vdi
n += 1 n += 1
# #
initvalues["gestion_compensation"] = initvalues.get("gestion_compensation", "0") initvalues["gestion_compensation"] = initvalues.get("gestion_compensation", False)
if initvalues["gestion_compensation"] == "1": if initvalues["gestion_compensation"]:
initvalues["gestion_compensation_lst"] = ["X"] initvalues["gestion_compensation_lst"] = ["X"]
else: else:
initvalues["gestion_compensation_lst"] = [] initvalues["gestion_compensation_lst"] = []
@ -638,8 +630,8 @@ def do_formsemestre_createwithmodules(context, REQUEST=None, edit=False):
): ):
REQUEST.form["gestion_compensation_lst"] = [] REQUEST.form["gestion_compensation_lst"] = []
initvalues["gestion_semestrielle"] = initvalues.get("gestion_semestrielle", "0") initvalues["gestion_semestrielle"] = initvalues.get("gestion_semestrielle", False)
if initvalues["gestion_semestrielle"] == "1": if initvalues["gestion_semestrielle"]:
initvalues["gestion_semestrielle_lst"] = ["X"] initvalues["gestion_semestrielle_lst"] = ["X"]
else: else:
initvalues["gestion_semestrielle_lst"] = [] initvalues["gestion_semestrielle_lst"] = []
@ -649,8 +641,8 @@ def do_formsemestre_createwithmodules(context, REQUEST=None, edit=False):
): ):
REQUEST.form["gestion_semestrielle_lst"] = [] REQUEST.form["gestion_semestrielle_lst"] = []
initvalues["bul_hide_xml"] = initvalues.get("bul_hide_xml", "0") initvalues["bul_hide_xml"] = initvalues.get("bul_hide_xml", False)
if initvalues["bul_hide_xml"] == "0": if not initvalues["bul_hide_xml"]:
initvalues["bul_publish_xml_lst"] = ["X"] initvalues["bul_publish_xml_lst"] = ["X"]
else: else:
initvalues["bul_publish_xml_lst"] = [] initvalues["bul_publish_xml_lst"] = []
@ -691,23 +683,23 @@ def do_formsemestre_createwithmodules(context, REQUEST=None, edit=False):
return "<h4>annulation</h4>" return "<h4>annulation</h4>"
else: else:
if tf[2]["gestion_compensation_lst"]: if tf[2]["gestion_compensation_lst"]:
tf[2]["gestion_compensation"] = 1 tf[2]["gestion_compensation"] = True
else: else:
tf[2]["gestion_compensation"] = 0 tf[2]["gestion_compensation"] = False
if tf[2]["gestion_semestrielle_lst"]: if tf[2]["gestion_semestrielle_lst"]:
tf[2]["gestion_semestrielle"] = 1 tf[2]["gestion_semestrielle"] = True
else: else:
tf[2]["gestion_semestrielle"] = 0 tf[2]["gestion_semestrielle"] = False
if tf[2]["bul_publish_xml_lst"]: if tf[2]["bul_publish_xml_lst"]:
tf[2]["bul_hide_xml"] = 0 tf[2]["bul_hide_xml"] = False
else: else:
tf[2]["bul_hide_xml"] = 1 tf[2]["bul_hide_xml"] = True
# remap les identifiants de responsables: # remap les identifiants de responsables:
tf[2]["responsable_id"] = User.get_user_name_from_nomplogin( tf[2]["responsable_id"] = User.get_user_id_from_nomplogin(
tf[2]["responsable_id"] tf[2]["responsable_id"]
) )
tf[2]["responsable_id2"] = User.get_user_name_from_nomplogin( tf[2]["responsable_id2"] = User.get_user_id_from_nomplogin(
tf[2]["responsable_id2"] tf[2]["responsable_id2"]
) )
tf[2]["responsables"] = [tf[2]["responsable_id"]] tf[2]["responsables"] = [tf[2]["responsable_id"]]
@ -715,7 +707,7 @@ def do_formsemestre_createwithmodules(context, REQUEST=None, edit=False):
tf[2]["responsables"].append(tf[2]["responsable_id2"]) tf[2]["responsables"].append(tf[2]["responsable_id2"])
for module_id in tf[2]["tf-checked"]: for module_id in tf[2]["tf-checked"]:
mod_resp_id = User.get_user_name_from_nomplogin(tf[2][module_id]) mod_resp_id = User.get_user_id_from_nomplogin(tf[2][module_id])
if mod_resp_id is None: if mod_resp_id is None:
# Si un module n'a pas de responsable (ou inconnu), l'affecte au 1er directeur des etudes: # Si un module n'a pas de responsable (ou inconnu), l'affecte au 1er directeur des etudes:
mod_resp_id = tf[2]["responsable_id"] mod_resp_id = tf[2]["responsable_id"]
@ -774,7 +766,7 @@ def do_formsemestre_createwithmodules(context, REQUEST=None, edit=False):
modargs = { modargs = {
"module_id": module_id, "module_id": module_id,
"formsemestre_id": formsemestre_id, "formsemestre_id": formsemestre_id,
"responsable_id": tf[2][module_id], "responsable_id": tf[2]["MI" + str(module_id)],
} }
moduleimpl_id = sco_moduleimpl.do_moduleimpl_create(context, modargs) moduleimpl_id = sco_moduleimpl.do_moduleimpl_create(context, modargs)
mod = sco_edit_module.do_module_list(context, {"module_id": module_id})[ mod = sco_edit_module.do_module_list(context, {"module_id": module_id})[
@ -825,7 +817,7 @@ def do_formsemestre_createwithmodules(context, REQUEST=None, edit=False):
"moduleimpl_id": moduleimpl_id, "moduleimpl_id": moduleimpl_id,
"module_id": module_id, "module_id": module_id,
"formsemestre_id": formsemestre_id, "formsemestre_id": formsemestre_id,
"responsable_id": tf[2][module_id], "responsable_id": tf[2]["MI" + str(module_id)],
} }
sco_moduleimpl.do_moduleimpl_edit( sco_moduleimpl.do_moduleimpl_edit(
context, modargs, formsemestre_id=formsemestre_id context, modargs, formsemestre_id=formsemestre_id
@ -893,14 +885,14 @@ def formsemestre_clone(context, formsemestre_id, REQUEST=None):
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
# Liste des enseignants avec forme pour affichage / saisie avec suggestion # Liste des enseignants avec forme pour affichage / saisie avec suggestion
userlist = sco_users.get_user_list() userlist = sco_users.get_user_list()
login2display = {} # user_name : forme pour affichage = "NOM Prenom (login)" uid2display = {} # user_name : forme pour affichage = "NOM Prenom (login)"
for u in userlist: for u in userlist:
login2display[u.user_name] = u.get_nomplogin() uid2display[u.id] = u.get_nomplogin()
allowed_user_names = list(login2display.values()) + [""] allowed_user_names = list(uid2display.values()) + [""]
initvalues = { initvalues = {
"formsemestre_id": sem["formsemestre_id"], "formsemestre_id": sem["formsemestre_id"],
"responsable_id": login2display.get( "responsable_id": uid2display.get(
sem["responsables"][0], sem["responsables"][0] sem["responsables"][0], sem["responsables"][0]
), ),
} }
@ -1001,7 +993,7 @@ def formsemestre_clone(context, formsemestre_id, REQUEST=None):
new_formsemestre_id = do_formsemestre_clone( new_formsemestre_id = do_formsemestre_clone(
context, context,
formsemestre_id, formsemestre_id,
User.get_user_name_from_nomplogin(tf[2]["responsable_id"]), User.get_user_id_from_nomplogin(tf[2]["responsable_id"]),
tf[2]["date_debut"], tf[2]["date_debut"],
tf[2]["date_fin"], tf[2]["date_fin"],
clone_evaluations=tf[2]["clone_evaluations"], clone_evaluations=tf[2]["clone_evaluations"],
@ -1523,7 +1515,7 @@ def formsemestre_change_publication_bul(
if not ok: if not ok:
return err return err
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
etat = 1 - int(sem["bul_hide_xml"]) etat = not sem["bul_hide_xml"]
if REQUEST and not dialog_confirmed: if REQUEST and not dialog_confirmed:
if etat: if etat:
@ -1542,10 +1534,6 @@ def formsemestre_change_publication_bul(
parameters={"bul_hide_xml": etat, "formsemestre_id": formsemestre_id}, parameters={"bul_hide_xml": etat, "formsemestre_id": formsemestre_id},
) )
if etat not in (0, 1):
raise ScoValueError(
"formsemestre_change_publication_bul: invalid value for etat (%s)" % etat
)
args = {"formsemestre_id": formsemestre_id, "bul_hide_xml": etat} args = {"formsemestre_id": formsemestre_id, "bul_hide_xml": etat}
sco_formsemestre.do_formsemestre_edit(context, args) sco_formsemestre.do_formsemestre_edit(context, args)
if REQUEST: if REQUEST:

View File

@ -550,7 +550,7 @@ def fill_formsemestre(sem):
else: else:
sem["locklink"] = "" sem["locklink"] = ""
if sco_preferences.get_preference("bul_display_publication", formsemestre_id): if sco_preferences.get_preference("bul_display_publication", formsemestre_id):
if sem["bul_hide_xml"] != "0": if sem["bul_hide_xml"]:
eyeicon = scu.icontag("hide_img", border="0", title="Bulletins NON publiés") eyeicon = scu.icontag("hide_img", border="0", title="Bulletins NON publiés")
else: else:
eyeicon = scu.icontag("eye_img", border="0", title="Bulletins publiés") eyeicon = scu.icontag("eye_img", border="0", title="Bulletins publiés")
@ -672,7 +672,7 @@ def formsemestre_description_table(
e["evalcomplete_str"] = "Non" e["evalcomplete_str"] = "Non"
e["_evalcomplete_str_td_attrs"] = 'style="color: red;"' e["_evalcomplete_str_td_attrs"] = 'style="color: red;"'
if int(e["publish_incomplete"]): if e["publish_incomplete"]:
e["publish_incomplete_str"] = "Oui" e["publish_incomplete_str"] = "Oui"
e["_publish_incomplete_str_td_attrs"] = 'style="color: green;"' e["_publish_incomplete_str_td_attrs"] = 'style="color: green;"'
else: else:
@ -969,7 +969,7 @@ Il y a des notes en attente ! Le classement des étudiants n'a qu'une valeur ind
</td></tr>""" </td></tr>"""
) )
H.append("</table>") H.append("</table>")
if sem["bul_hide_xml"] != "0": if sem["bul_hide_xml"]:
H.append( H.append(
'<p class="fontorange"><em>Bulletins non publiés sur le portail</em></p>' '<p class="fontorange"><em>Bulletins non publiés sur le portail</em></p>'
) )

View File

@ -323,7 +323,7 @@ def formsemestre_validation_etud_form(
) )
H.append('<p style="font-size: 50%;">Formation ') H.append('<p style="font-size: 50%;">Formation ')
if Se.sem["gestion_semestrielle"] == "1": if Se.sem["gestion_semestrielle"]:
H.append("avec semestres décalés</p>") H.append("avec semestres décalés</p>")
else: else:
H.append("sans semestres décalés</p>") H.append("sans semestres décalés</p>")
@ -375,7 +375,7 @@ def formsemestre_validation_etud_manu(
): ):
"""Enregistre validation""" """Enregistre validation"""
if assidu: if assidu:
assidu = 1 assidu = True
etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0] etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0]
Se = sco_parcours_dut.SituationEtudParcours(context, etud, formsemestre_id) Se = sco_parcours_dut.SituationEtudParcours(context, etud, formsemestre_id)
if code_etat in Se.parcours.UNUSED_CODES: if code_etat in Se.parcours.UNUSED_CODES:
@ -526,7 +526,7 @@ def formsemestre_recap_parcours_table(
pv = dpv["decisions"][0] pv = dpv["decisions"][0]
decision_sem = pv["decision_sem"] decision_sem = pv["decision_sem"]
decisions_ue = pv["decisions_ue"] decisions_ue = pv["decisions_ue"]
if with_all_columns and decision_sem and decision_sem["assidu"] == 0: if with_all_columns and decision_sem and not decision_sem["assidu"]:
ass = " (non ass.)" ass = " (non ass.)"
else: else:
ass = "" ass = ""
@ -744,7 +744,7 @@ def form_decision_manuelle(
'<option value="%s">%s (code %s)</option>' '<option value="%s">%s (code %s)</option>'
% (cod, sco_codes_parcours.CODES_EXPL[cod], cod) % (cod, sco_codes_parcours.CODES_EXPL[cod], cod)
) )
elif Se.sem["gestion_compensation"] == "1": elif Se.sem["gestion_compensation"]:
# traitement spécial pour ADC (compensation) # traitement spécial pour ADC (compensation)
# ne propose que les semestres avec lesquels on peut compenser # ne propose que les semestres avec lesquels on peut compenser
# le code transmis est ADC_formsemestre_id # le code transmis est ADC_formsemestre_id
@ -795,7 +795,7 @@ def form_decision_manuelle(
else: else:
allowed_codes = set(sco_codes_parcours.DEVENIRS_STD) allowed_codes = set(sco_codes_parcours.DEVENIRS_STD)
# semestres decales ? # semestres decales ?
if Se.sem["gestion_semestrielle"] == "1": if Se.sem["gestion_semestrielle"]:
allowed_codes = allowed_codes.union(sco_codes_parcours.DEVENIRS_DEC) allowed_codes = allowed_codes.union(sco_codes_parcours.DEVENIRS_DEC)
# n'autorise les codes NEXT2 que si semestres décalés et s'il ne manque qu'un semestre avant le n+2 # n'autorise les codes NEXT2 que si semestres décalés et s'il ne manque qu'un semestre avant le n+2
if Se.can_jump_to_next2(): if Se.can_jump_to_next2():
@ -1082,7 +1082,9 @@ def formsemestre_validate_previous_ue(context, formsemestre_id, etudid, REQUEST=
return "\n".join(H) + tf[1] + X + warn + html_sco_header.sco_footer() return "\n".join(H) + tf[1] + X + warn + html_sco_header.sco_footer()
elif tf[0] == -1: elif tf[0] == -1:
return flask.redirect( return flask.redirect(
scu.NotesURL() + "/formsemestre_status?formsemestre_id=" + str(formsemestre_id) scu.NotesURL()
+ "/formsemestre_status?formsemestre_id="
+ str(formsemestre_id)
) )
else: else:
if tf[2]["semestre_id"]: if tf[2]["semestre_id"]:
@ -1143,7 +1145,7 @@ def do_formsemestre_validate_previous_ue(
moy_ue=moy_ue, moy_ue=moy_ue,
date=date, date=date,
semestre_id=semestre_id, semestre_id=semestre_id,
is_external=1, is_external=True,
) )
logdb( logdb(

View File

@ -86,6 +86,10 @@ partitionEditor = ndb.EditableTable(
"bul_show_rank", "bul_show_rank",
"show_in_lists", "show_in_lists",
), ),
input_formators={
"bul_show_rank": bool,
"show_in_lists": bool,
},
) )
groupEditor = ndb.EditableTable( groupEditor = ndb.EditableTable(
@ -390,14 +394,15 @@ def formsemestre_get_etud_groupnames(context, formsemestre_id, attr="group_name"
{ etudid : { partition_id : group_name }} (attr=group_name or group_id) { etudid : { partition_id : group_name }} (attr=group_name or group_id)
""" """
infos = ndb.SimpleDictFetch( infos = ndb.SimpleDictFetch(
"""SELECT i.id AS etudid, p.is AS partition_id, gd.group_name, gd.id AS group_id """SELECT i.id AS etudid, p.id AS partition_id,
gd.group_name, gd.id AS group_id
FROM notes_formsemestre_inscription i, partition p, FROM notes_formsemestre_inscription i, partition p,
group_descr gd, group_membership gm group_descr gd, group_membership gm
WHERE i.formsemestre_id=%(formsemestre_id)s WHERE i.formsemestre_id=%(formsemestre_id)s
and i.formsemestre_id=p.formsemestre_id and i.formsemestre_id = p.formsemestre_id
and p.id=gd.partition_id and p.id = gd.partition_id
and gm.etudid=i.etudid and gm.etudid = i.etudid
and gm.group_id = gd.group_id and gm.group_id = gd.id
and p.partition_name is not NULL and p.partition_name is not NULL
""", """,
{"formsemestre_id": formsemestre_id}, {"formsemestre_id": formsemestre_id},
@ -505,9 +510,9 @@ def XMLgetGroupsInPartition(context, partition_id, REQUEST=None): # was XMLgetG
for group in groups: for group in groups:
x_group = Element( x_group = Element(
"group", "group",
partition_id=partition_id, partition_id=str(partition_id),
partition_name=partition["partition_name"], partition_name=partition["partition_name"],
group_id=group["group_id"], group_id=str(group["group_id"]),
group_name=group["group_name"], group_name=group["group_name"],
) )
x_response.append(x_group) x_response.append(x_group)
@ -516,7 +521,7 @@ def XMLgetGroupsInPartition(context, partition_id, REQUEST=None): # was XMLgetG
x_group.append( x_group.append(
Element( Element(
"etud", "etud",
etudid=e["etudid"], etudid=str(e["etudid"]),
civilite=etud["civilite_str"], civilite=etud["civilite_str"],
sexe=etud["civilite_str"], # compat sexe=etud["civilite_str"], # compat
nom=sco_etud.format_nom(etud["nom"]), nom=sco_etud.format_nom(etud["nom"]),
@ -531,7 +536,7 @@ def XMLgetGroupsInPartition(context, partition_id, REQUEST=None): # was XMLgetG
if etuds_set: if etuds_set:
x_group = Element( x_group = Element(
"group", "group",
partition_id=partition_id, partition_id=str(partition_id),
partition_name=partition["partition_name"], partition_name=partition["partition_name"],
group_id="_none_", group_id="_none_",
group_name="", group_name="",
@ -542,7 +547,7 @@ def XMLgetGroupsInPartition(context, partition_id, REQUEST=None): # was XMLgetG
x_group.append( x_group.append(
Element( Element(
"etud", "etud",
etudid=etud["etudid"], etudid=str(etud["etudid"]),
sexe=etud["civilite_str"], sexe=etud["civilite_str"],
nom=sco_etud.format_nom(etud["nom"]), nom=sco_etud.format_nom(etud["nom"]),
prenom=sco_etud.format_prenom(etud["prenom"]), prenom=sco_etud.format_prenom(etud["prenom"]),
@ -618,10 +623,14 @@ def change_etud_group_in_partition(
partition = get_partition(context, group["partition_id"]) partition = get_partition(context, group["partition_id"])
# 1- Supprime membership dans cette partition # 1- Supprime membership dans cette partition
ndb.SimpleQuery( ndb.SimpleQuery(
"""DELETE FROM group_membership WHERE id IN """DELETE FROM group_membership
WHERE id IN
(SELECT gm.id (SELECT gm.id
FROM group_membership gm, group_descr gd FROM group_membership gm, group_descr gd
WHERE gm.etudid=%(etudid)s AND gm.group_id=gd.group_id AND gd.partition_id=%(partition_id)s)""", WHERE gm.etudid = %(etudid)s
AND gm.group_id = gd.id
AND gd.partition_id = %(partition_id)s)
""",
{"etudid": etudid, "partition_id": partition["partition_id"]}, {"etudid": etudid, "partition_id": partition["partition_id"]},
) )
@ -688,7 +697,8 @@ def setGroups(
old_members = get_group_members(context, group_id) old_members = get_group_members(context, group_id)
old_members_set = set([x["etudid"] for x in old_members]) old_members_set = set([x["etudid"] for x in old_members])
# Place dans ce groupe les etudiants indiqués: # Place dans ce groupe les etudiants indiqués:
for etudid in fs[1:-1]: for etudid_str in fs[1:-1]:
etudid = int(etudid_str)
if etudid in old_members_set: if etudid in old_members_set:
old_members_set.remove( old_members_set.remove(
etudid etudid
@ -1175,7 +1185,7 @@ def group_set_name(context, group_id, group_name, REQUEST=None, redirect=1):
# redirect to partition edit page: # redirect to partition edit page:
if redirect: if redirect:
return flask.redirect("affectGroups?partition_id=" + group["partition_id"]) return flask.redirect("affectGroups?partition_id=" + str(group["partition_id"]))
def group_rename(context, group_id, REQUEST=None): def group_rename(context, group_id, REQUEST=None):

View File

@ -303,7 +303,7 @@ class DisplayedGroupsInfos(object):
def __init__( def __init__(
self, self,
context, context,
group_ids=[], # groupes specifies dans l'URL group_ids=[], # groupes specifies dans l'URL, ou un seul int
formsemestre_id=None, formsemestre_id=None,
etat=None, etat=None,
select_all_when_unspecified=False, select_all_when_unspecified=False,
@ -311,7 +311,7 @@ class DisplayedGroupsInfos(object):
REQUEST=None, REQUEST=None,
): ):
# log('DisplayedGroupsInfos %s' % group_ids) # log('DisplayedGroupsInfos %s' % group_ids)
if isinstance(group_ids, str): if isinstance(group_ids, int):
if group_ids: if group_ids:
group_ids = [group_ids] # cas ou un seul parametre, pas de liste group_ids = [group_ids] # cas ou un seul parametre, pas de liste
else: else:

View File

@ -436,7 +436,7 @@ def moduleimpl_status(context, moduleimpl_id=None, partition_id=None, REQUEST=No
if etat["evalcomplete"]: if etat["evalcomplete"]:
etat_txt = """(prise en compte)""" etat_txt = """(prise en compte)"""
etat_descr = "notes utilisées dans les moyennes" etat_descr = "notes utilisées dans les moyennes"
elif eval["publish_incomplete"] != "0": elif eval["publish_incomplete"]:
etat_txt = """(prise en compte <b>immédiate</b>)""" etat_txt = """(prise en compte <b>immédiate</b>)"""
etat_descr = ( etat_descr = (
"il manque des notes, mais la prise en compte immédiate a été demandée" "il manque des notes, mais la prise en compte immédiate a été demandée"
@ -511,7 +511,7 @@ def moduleimpl_status(context, moduleimpl_id=None, partition_id=None, REQUEST=No
) )
) )
# #
if eval["visibulletin"] == "1": if eval["visibulletin"]:
H.append( H.append(
scu.icontag( scu.icontag(
"status_visible_img", title="visible dans bulletins intermédiaires" "status_visible_img", title="visible dans bulletins intermédiaires"

View File

@ -146,7 +146,7 @@ class SituationEtudParcoursGeneric(object):
# Verifie barres # Verifie barres
self._comp_barres() self._comp_barres()
# Verifie compensation # Verifie compensation
if self.prev and self.sem["gestion_compensation"] == "1": if self.prev and self.sem["gestion_compensation"]:
self.can_compensate_with_prev = self.prev["can_compensate"] self.can_compensate_with_prev = self.prev["can_compensate"]
else: else:
self.can_compensate_with_prev = False self.can_compensate_with_prev = False
@ -176,10 +176,9 @@ class SituationEtudParcoursGeneric(object):
if rule.conclusion[0] in self.parcours.UNUSED_CODES: if rule.conclusion[0] in self.parcours.UNUSED_CODES:
continue continue
# Saute regles REDOSEM si pas de semestres decales: # Saute regles REDOSEM si pas de semestres decales:
if ( if (not self.sem["gestion_semestrielle"]) and rule.conclusion[
self.sem["gestion_semestrielle"] != "1" 3
and rule.conclusion[3] == "REDOSEM" ] == "REDOSEM":
):
continue continue
if rule.match(state): if rule.match(state):
if rule.conclusion[0] == ADC: if rule.conclusion[0] == ADC:
@ -283,7 +282,7 @@ class SituationEtudParcoursGeneric(object):
(et que le sem courant n soit validé, ce qui n'est pas testé ici) (et que le sem courant n soit validé, ce qui n'est pas testé ici)
""" """
n = self.sem["semestre_id"] n = self.sem["semestre_id"]
if self.sem["gestion_semestrielle"] != "1": if not self.sem["gestion_semestrielle"]:
return False # pas de semestre décalés return False # pas de semestre décalés
if n == NO_SEMESTRE_ID or n > self.parcours.NB_SEM - 2: if n == NO_SEMESTRE_ID or n > self.parcours.NB_SEM - 2:
return False # n+2 en dehors du parcours return False # n+2 en dehors du parcours
@ -602,7 +601,7 @@ class SituationEtudParcoursGeneric(object):
self.prev["formsemestre_id"], self.prev["formsemestre_id"],
self.etudid, self.etudid,
decision.new_code_prev, decision.new_code_prev,
assidu=1, assidu=True,
formsemestre_id_utilise_pour_compenser=fsid, formsemestre_id_utilise_pour_compenser=fsid,
) )
logdb( logdb(
@ -779,8 +778,14 @@ _scolar_formsemestre_validation_editor = ndb.EditableTable(
"semestre_id", "semestre_id",
"is_external", "is_external",
), ),
output_formators={"event_date": ndb.DateISOtoDMY, "assidu": bool}, output_formators={
input_formators={"event_date": ndb.DateDMYtoISO, "assidu": bool}, "event_date": ndb.DateISOtoDMY,
},
input_formators={
"event_date": ndb.DateDMYtoISO,
"assidu": bool,
"is_external": bool,
},
) )
scolar_formsemestre_validation_create = _scolar_formsemestre_validation_editor.create scolar_formsemestre_validation_create = _scolar_formsemestre_validation_editor.create
@ -837,7 +842,7 @@ def formsemestre_update_validation_sem(
formsemestre_id, formsemestre_id,
etudid, etudid,
code, code,
assidu=1, assidu=True,
formsemestre_id_utilise_pour_compenser=None, formsemestre_id_utilise_pour_compenser=None,
): ):
"Update validation semestre" "Update validation semestre"
@ -845,7 +850,7 @@ def formsemestre_update_validation_sem(
"formsemestre_id": formsemestre_id, "formsemestre_id": formsemestre_id,
"etudid": etudid, "etudid": etudid,
"code": code, "code": code,
"assidu": int(assidu), "assidu": assidu,
} }
log("formsemestre_update_validation_sem: %s" % args) log("formsemestre_update_validation_sem: %s" % args)
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor) cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)

View File

@ -114,7 +114,7 @@ def feuille_preparation_jury(context, formsemestre_id, REQUEST):
code[etudid] = decision["code"] code[etudid] = decision["code"]
if decision["compense_formsemestre_id"]: if decision["compense_formsemestre_id"]:
code[etudid] += "+" # indique qu'il a servi a compenser code[etudid] += "+" # indique qu'il a servi a compenser
assidu[etudid] = {0: "Non", 1: "Oui"}.get(decision["assidu"], "") assidu[etudid] = {False: "Non", True: "Oui"}.get(decision["assidu"], "")
aut_list = sco_parcours_dut.formsemestre_get_autorisation_inscription( aut_list = sco_parcours_dut.formsemestre_get_autorisation_inscription(
context, etudid, formsemestre_id context, etudid, formsemestre_id
) )

View File

@ -54,6 +54,7 @@ Solution proposée (nov 2014):
""" """
import flask import flask
from flask_login import current_user
import app.scodoc.notesdb as ndb import app.scodoc.notesdb as ndb
import app.scodoc.sco_utils as scu import app.scodoc.sco_utils as scu
@ -87,9 +88,8 @@ def external_ue_create(
log("external_ue_create( formsemestre_id=%s, titre=%s )" % (formsemestre_id, titre)) log("external_ue_create( formsemestre_id=%s, titre=%s )" % (formsemestre_id, titre))
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
# Contrôle d'accès: # Contrôle d'accès:
authuser = REQUEST.AUTHENTICATED_USER if not current_user.has_permission(Permission.ScoImplement):
if not authuser.has_permission(Permission.ScoImplement): if not sem["resp_can_edit"] or (current_user.id not in sem["responsables"]):
if not sem["resp_can_edit"] or str(authuser) not in sem["responsables"]:
raise AccessDenied("vous n'avez pas le droit d'effectuer cette opération") raise AccessDenied("vous n'avez pas le droit d'effectuer cette opération")
# #
formation_id = sem["formation_id"] formation_id = sem["formation_id"]
@ -107,7 +107,7 @@ def external_ue_create(
"numero": numero, "numero": numero,
"type": ue_type, "type": ue_type,
"ects": ects, "ects": ects,
"is_external": 1, "is_external": True,
}, },
) )
@ -170,9 +170,9 @@ def external_ue_inscrit_et_note(
moduleimpl_id=moduleimpl_id, moduleimpl_id=moduleimpl_id,
note_max=20.0, note_max=20.0,
coefficient=1.0, coefficient=1.0,
publish_incomplete=1, publish_incomplete=True,
evaluation_type=0, evaluation_type=scu.EVALUATION_NORMALE,
visibulletin=0, visibulletin=False,
description="note externe", description="note externe",
) )
# Saisie des notes # Saisie des notes
@ -188,7 +188,7 @@ def external_ue_inscrit_et_note(
def get_existing_external_ue(context, formation_id): def get_existing_external_ue(context, formation_id):
"la liste de toutes les UE externes définies dans cette formation" "la liste de toutes les UE externes définies dans cette formation"
return sco_edit_ue.do_ue_list( return sco_edit_ue.do_ue_list(
context, args={"formation_id": formation_id, "is_external": 1} context, args={"formation_id": formation_id, "is_external": True}
) )
@ -221,9 +221,8 @@ def external_ue_create_form(context, formsemestre_id, etudid, REQUEST=None):
""" """
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
# Contrôle d'accès: # Contrôle d'accès:
authuser = REQUEST.AUTHENTICATED_USER if not current_user.has_permission(Permission.ScoImplement):
if not authuser.has_permission(Permission.ScoImplement): if not sem["resp_can_edit"] or (current_user.id not in sem["responsables"]):
if not sem["resp_can_edit"] or str(authuser) not in sem["responsables"]:
raise AccessDenied("vous n'avez pas le droit d'effectuer cette opération") raise AccessDenied("vous n'avez pas le droit d'effectuer cette opération")
etud = sco_etud.get_etud_info(etudid=etudid, filled=1, REQUEST=REQUEST)[0] etud = sco_etud.get_etud_info(etudid=etudid, filled=1, REQUEST=REQUEST)[0]

View File

@ -449,9 +449,13 @@ def stripquotes(s):
def suppress_accents(s): def suppress_accents(s):
"remove accents and suppress non ascii characters from string s" "remove accents and suppress non ascii characters from string s"
if isinstance(s, str):
return ( return (
unicodedata.normalize("NFD", s).encode("ascii", "ignore").decode(SCO_ENCODING) unicodedata.normalize("NFD", s)
.encode("ascii", "ignore")
.decode(SCO_ENCODING)
) )
return s # may be int
def sanitize_string(s): def sanitize_string(s):

View File

@ -1189,7 +1189,7 @@ def _tableBillets(context, billets, etud=None, title=""):
m = " après-midi" m = " après-midi"
b["abs_end_str"] = b["abs_end"].strftime("%d/%m/%Y") + m b["abs_end_str"] = b["abs_end"].strftime("%d/%m/%Y") + m
if b["etat"] == 0: if b["etat"] == 0:
if b["justified"] == 0: if b["justified"]:
b["etat_str"] = "à traiter" b["etat_str"] = "à traiter"
else: else:
b["etat_str"] = "à justifier" b["etat_str"] = "à justifier"
@ -1441,7 +1441,7 @@ def ProcessBilletAbsenceForm(context, billet_id, REQUEST=None):
if tf[0] == 0: if tf[0] == 0:
tab = _tableBillets(context, [billet], etud=etud) tab = _tableBillets(context, [billet], etud=etud)
H.append(tab.html()) H.append(tab.html())
if billet["justified"] == 1: if billet["justified"]:
H.append( H.append(
"""<p>L'étudiant pense pouvoir justifier cette absence.<br/><em>Vérifiez le justificatif avant d'enregistrer.</em></p>""" """<p>L'étudiant pense pouvoir justifier cette absence.<br/><em>Vérifiez le justificatif avant d'enregistrer.</em></p>"""
) )

View File

@ -640,6 +640,7 @@ sco_publish(
"/formsemestre_change_publication_bul", "/formsemestre_change_publication_bul",
sco_formsemestre_edit.formsemestre_change_publication_bul, sco_formsemestre_edit.formsemestre_change_publication_bul,
Permission.ScoView, Permission.ScoView,
methods=["GET", "POST"],
) )
sco_publish( sco_publish(
"/view_formsemestre_by_etape", "/view_formsemestre_by_etape",
@ -746,7 +747,7 @@ def edit_enseignants_form(context, REQUEST, moduleimpl_id):
elif tf[0] == -1: elif tf[0] == -1:
return flask.redirect("moduleimpl_status?moduleimpl_id=" + moduleimpl_id) return flask.redirect("moduleimpl_status?moduleimpl_id=" + moduleimpl_id)
else: else:
ens_id = User.get_user_name_from_nomplogin(tf[2]["ens_id"]) ens_id = User.get_user_id_from_nomplogin(tf[2]["ens_id"])
if not ens_id: if not ens_id:
H.append( H.append(
'<p class="help">Pour ajouter un enseignant, choisissez un nom dans le menu</p>' '<p class="help">Pour ajouter un enseignant, choisissez un nom dans le menu</p>'
@ -838,7 +839,7 @@ def edit_moduleimpl_resp(context, REQUEST, moduleimpl_id):
elif tf[0] == -1: elif tf[0] == -1:
return flask.redirect("moduleimpl_status?moduleimpl_id=" + moduleimpl_id) return flask.redirect("moduleimpl_status?moduleimpl_id=" + moduleimpl_id)
else: else:
responsable_id = User.get_user_name_from_nomplogin(tf[2]["responsable_id"]) responsable_id = User.get_user_id_from_nomplogin(tf[2]["responsable_id"])
if ( if (
not responsable_id not responsable_id
): # presque impossible: tf verifie les valeurs (mais qui peuvent changer entre temps) ): # presque impossible: tf verifie les valeurs (mais qui peuvent changer entre temps)

View File

@ -703,6 +703,18 @@ sco_publish(
Permission.ScoView, Permission.ScoView,
methods=["GET", "POST"], methods=["GET", "POST"],
) )
# @bp.route("/partition_create", methods=["GET", "POST"])
# @permission_required(Permission.ScoView)
# @scodoc7func(context)
# def partition_create(
# context,
# formsemestre_id,
# partition_name="",
# default=False,
# numero=None,
# redirect=1):
# return sco_groups.partition_create(context, formsemestre_id,
sco_publish("/etud_info_html", sco_page_etud.etud_info_html, Permission.ScoView) sco_publish("/etud_info_html", sco_page_etud.etud_info_html, Permission.ScoView)

View File

@ -43,22 +43,29 @@ mi = G.create_moduleimpl(
# --- Création d'un étudiant # --- Création d'un étudiant
etud = G.create_etud(code_nip=None) etud = G.create_etud(code_nip=None)
G.inscrit_etudiant(sem, etud) G.inscrit_etudiant(sem, etud)
etudid=etud["etudid"] etudid = etud["etudid"]
# --- Création d'une absence # --- Création d'une absence
sco_abs_views.doSignaleAbsence(context.Absences, datedebut="22/01/2021", datefin="22/01/2021", demijournee=2, etudid=etudid, REQUEST=REQUEST) sco_abs_views.doSignaleAbsence(
context.Absences,
datedebut="22/01/2021",
datefin="22/01/2021",
demijournee=2,
etudid=etudid,
REQUEST=REQUEST,
)
# --- Création d'un billet # --- Création d'un billet
b1 = context.Absences.AddBilletAbsence( b1 = context.Absences.AddBilletAbsence(
begin="2021-01-22 00:00", begin="2021-01-22 00:00",
end="2021-01-22 23:59", end="2021-01-22 23:59",
etudid=etudid, etudid=etudid,
description = "abs du 22", description="abs du 22",
justified=False, justified=False,
code_nip=etuds[0]["code_nip"], code_nip=etuds[0]["code_nip"],
code_ine=etuds[0]["code_ine"], code_ine=etuds[0]["code_ine"],
REQUEST=REQUEST, REQUEST=REQUEST,
) )
# --- Suppression d'un billet # --- Suppression d'un billet
_ = context.Absences.deleteBilletAbsence(load_li_bi[1]["billet_id"], REQUEST=REQUEST) _ = context.Absences.deleteBilletAbsence(load_li_bi[1]["billet_id"], REQUEST=REQUEST)

View File

@ -132,7 +132,7 @@ def run_sco_basic(verbose=False):
assert etat["evalcomplete"] assert etat["evalcomplete"]
# Modifie l'évaluation 2 pour "prise en compte immédiate" # Modifie l'évaluation 2 pour "prise en compte immédiate"
e2["publish_incomplete"] = "1" e2["publish_incomplete"] = True
sco_evaluations.do_evaluation_edit(e2) sco_evaluations.do_evaluation_edit(e2)
etat = sco_evaluations.do_evaluation_etat(e2["evaluation_id"]) etat = sco_evaluations.do_evaluation_etat(e2["evaluation_id"])
assert etat["evalcomplete"] == False assert etat["evalcomplete"] == False