forked from ScoDoc/ScoDoc
Améliore saisie des UE extérieures. Pas de coefs en BUT.
This commit is contained in:
parent
c67d9a4ba5
commit
ffa5190a49
@ -228,7 +228,7 @@ class ResultatsSemestre(ResultatsCache):
|
|||||||
UE capitalisées.
|
UE capitalisées.
|
||||||
"""
|
"""
|
||||||
# Supposant qu'il y a peu d'UE capitalisées,
|
# Supposant qu'il y a peu d'UE capitalisées,
|
||||||
# on va soustraire la moyenne d'UE et ajouter celle de l'UE capitalisée.
|
# on recalcule les moyennes gen des etuds ayant des UE capitalisée.
|
||||||
if not self.validations:
|
if not self.validations:
|
||||||
self.validations = res_sem.load_formsemestre_validations(self.formsemestre)
|
self.validations = res_sem.load_formsemestre_validations(self.formsemestre)
|
||||||
ue_capitalisees = self.validations.ue_capitalisees
|
ue_capitalisees = self.validations.ue_capitalisees
|
||||||
@ -396,10 +396,10 @@ class ResultatsSemestre(ResultatsCache):
|
|||||||
|
|
||||||
def compute_etud_ue_coef(self, etudid: int, ue: UniteEns) -> float:
|
def compute_etud_ue_coef(self, etudid: int, ue: UniteEns) -> float:
|
||||||
"Détermine le coefficient de l'UE pour cet étudiant."
|
"Détermine le coefficient de l'UE pour cet étudiant."
|
||||||
# calcul différent en classqiue et BUT
|
# calcul différent en classique et BUT
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
def get_etud_ue_cap_coef(self, etudid, ue, ue_cap):
|
def get_etud_ue_cap_coef(self, etudid, ue, ue_cap): # UNUSED in ScoDoc 9
|
||||||
"""Calcule le coefficient d'une UE capitalisée, pour cet étudiant,
|
"""Calcule le coefficient d'une UE capitalisée, pour cet étudiant,
|
||||||
injectée dans le semestre courant.
|
injectée dans le semestre courant.
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ def TrivialFormulator(
|
|||||||
submitlabel="OK",
|
submitlabel="OK",
|
||||||
name=None,
|
name=None,
|
||||||
formid="tf",
|
formid="tf",
|
||||||
|
form_attrs="",
|
||||||
cssclass="",
|
cssclass="",
|
||||||
cancelbutton=None,
|
cancelbutton=None,
|
||||||
submitbutton=True,
|
submitbutton=True,
|
||||||
@ -100,7 +101,8 @@ def TrivialFormulator(
|
|||||||
submitlabel,
|
submitlabel,
|
||||||
name,
|
name,
|
||||||
formid,
|
formid,
|
||||||
cssclass,
|
form_attrs=form_attrs,
|
||||||
|
cssclass=cssclass,
|
||||||
cancelbutton=cancelbutton,
|
cancelbutton=cancelbutton,
|
||||||
submitbutton=submitbutton,
|
submitbutton=submitbutton,
|
||||||
submitbuttonattributes=submitbuttonattributes,
|
submitbuttonattributes=submitbuttonattributes,
|
||||||
@ -132,6 +134,7 @@ class TF(object):
|
|||||||
submitlabel="OK",
|
submitlabel="OK",
|
||||||
name=None,
|
name=None,
|
||||||
formid="tf",
|
formid="tf",
|
||||||
|
form_attrs="",
|
||||||
cssclass="",
|
cssclass="",
|
||||||
cancelbutton=None,
|
cancelbutton=None,
|
||||||
submitbutton=True,
|
submitbutton=True,
|
||||||
@ -154,6 +157,7 @@ class TF(object):
|
|||||||
else:
|
else:
|
||||||
self.name = formid # 'tf'
|
self.name = formid # 'tf'
|
||||||
self.formid = formid
|
self.formid = formid
|
||||||
|
self.form_attrs = form_attrs
|
||||||
self.cssclass = cssclass
|
self.cssclass = cssclass
|
||||||
self.cancelbutton = cancelbutton
|
self.cancelbutton = cancelbutton
|
||||||
self.submitbutton = submitbutton
|
self.submitbutton = submitbutton
|
||||||
@ -408,8 +412,16 @@ class TF(object):
|
|||||||
klass = ""
|
klass = ""
|
||||||
name = self.name
|
name = self.name
|
||||||
R.append(
|
R.append(
|
||||||
'<form action="%s" method="%s" id="%s" enctype="%s" name="%s" %s>'
|
'<form action="%s" method="%s" id="%s" enctype="%s" name="%s" %s %s>'
|
||||||
% (self.form_url, self.method, self.formid, enctype, name, klass)
|
% (
|
||||||
|
self.form_url,
|
||||||
|
self.method,
|
||||||
|
self.formid,
|
||||||
|
enctype,
|
||||||
|
name,
|
||||||
|
klass,
|
||||||
|
self.form_attrs,
|
||||||
|
)
|
||||||
)
|
)
|
||||||
R.append('<input type="hidden" name="%s_submitted" value="1">' % self.formid)
|
R.append('<input type="hidden" name="%s_submitted" value="1">' % self.formid)
|
||||||
if self.top_buttons:
|
if self.top_buttons:
|
||||||
|
@ -39,20 +39,23 @@ from flask_login import current_user
|
|||||||
|
|
||||||
from app.comp import res_sem
|
from app.comp import res_sem
|
||||||
from app.comp.res_compat import NotesTableCompat
|
from app.comp.res_compat import NotesTableCompat
|
||||||
from app.models import FormSemestre
|
from app.models import (
|
||||||
|
FormSemestre,
|
||||||
|
FormSemestreUECoef,
|
||||||
|
Identite,
|
||||||
|
ScolarFormSemestreValidation,
|
||||||
|
UniteEns,
|
||||||
|
)
|
||||||
import app.scodoc.sco_utils as scu
|
import app.scodoc.sco_utils as scu
|
||||||
import app.scodoc.notesdb as ndb
|
|
||||||
from app import log
|
from app import log
|
||||||
from app.scodoc.TrivialFormulator import TrivialFormulator, tf_error_message
|
from app.scodoc.TrivialFormulator import TrivialFormulator, tf_error_message
|
||||||
from app.scodoc import html_sco_header
|
from app.scodoc import html_sco_header
|
||||||
from app.scodoc import sco_cache
|
|
||||||
from app.scodoc import sco_edit_ue
|
|
||||||
from app.scodoc import sco_formations
|
from app.scodoc import sco_formations
|
||||||
from app.scodoc import sco_formsemestre
|
from app.scodoc import sco_formsemestre
|
||||||
from app.scodoc import sco_formsemestre_inscriptions
|
from app.scodoc import sco_formsemestre_inscriptions
|
||||||
from app.scodoc import sco_formsemestre_validation
|
from app.scodoc import sco_formsemestre_validation
|
||||||
from app.scodoc import sco_cursus_dut
|
|
||||||
from app.scodoc import sco_etud
|
from app.scodoc import sco_etud
|
||||||
|
from app.scodoc.sco_codes_parcours import UE_SPORT
|
||||||
|
|
||||||
|
|
||||||
def formsemestre_ext_create(etudid, sem_params):
|
def formsemestre_ext_create(etudid, sem_params):
|
||||||
@ -84,7 +87,7 @@ def formsemestre_ext_create(etudid, sem_params):
|
|||||||
|
|
||||||
def formsemestre_ext_create_form(etudid, formsemestre_id):
|
def formsemestre_ext_create_form(etudid, formsemestre_id):
|
||||||
"""Formulaire création/inscription à un semestre extérieur"""
|
"""Formulaire création/inscription à un semestre extérieur"""
|
||||||
etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0]
|
etud = Identite.query.get_or_404(etudid)
|
||||||
H = [
|
H = [
|
||||||
html_sco_header.sco_header(),
|
html_sco_header.sco_header(),
|
||||||
f"""<h2>Enregistrement d'une inscription antérieure dans un autre
|
f"""<h2>Enregistrement d'une inscription antérieure dans un autre
|
||||||
@ -103,7 +106,7 @@ def formsemestre_ext_create_form(etudid, formsemestre_id):
|
|||||||
</p>
|
</p>
|
||||||
<h3><a href="{ url_for('scolar.ficheEtud',
|
<h3><a href="{ url_for('scolar.ficheEtud',
|
||||||
scodoc_dept=g.scodoc_dept, etudid=etudid)
|
scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||||
}" class="stdlink">Étudiant {etud["nomprenom"]}</a></h3>
|
}" class="stdlink">Étudiant {etud.nomprenom}</a></h3>
|
||||||
""",
|
""",
|
||||||
]
|
]
|
||||||
F = html_sco_header.sco_footer()
|
F = html_sco_header.sco_footer()
|
||||||
@ -228,66 +231,82 @@ def formsemestre_ext_edit_ue_validations(formsemestre_id, etudid):
|
|||||||
"""Edition des validations d'UE et de semestre (jury)
|
"""Edition des validations d'UE et de semestre (jury)
|
||||||
pour un semestre extérieur.
|
pour un semestre extérieur.
|
||||||
On peut saisir pour chaque UE du programme de formation
|
On peut saisir pour chaque UE du programme de formation
|
||||||
sa validation, son code jury, sa note, son coefficient.
|
sa validation, son code jury, sa note, son coefficient
|
||||||
|
(sauf en BUT où le coef. des UE est toujours égal aux ECTS).
|
||||||
|
|
||||||
La moyenne générale du semestre est calculée et affichée,
|
La moyenne générale indicative du semestre est calculée et affichée,
|
||||||
mais pas enregistrée.
|
mais pas enregistrée.
|
||||||
"""
|
"""
|
||||||
sem = sco_formsemestre.get_formsemestre(formsemestre_id)
|
formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id)
|
||||||
etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0]
|
etud = Identite.query.get_or_404(etudid)
|
||||||
ues = _list_ue_with_coef_and_validations(sem, etudid)
|
ues = formsemestre.formation.ues.filter(UniteEns.type != UE_SPORT).order_by(
|
||||||
descr = _ue_form_description(ues, scu.get_request_args())
|
UniteEns.semestre_idx, UniteEns.numero
|
||||||
|
)
|
||||||
|
descr = _ue_form_description(formsemestre, etud, ues, scu.get_request_args())
|
||||||
|
initvalues = {}
|
||||||
if request.method == "GET":
|
if request.method == "GET":
|
||||||
initvalues = {
|
for ue in ues:
|
||||||
"note_" + str(ue["ue_id"]): ue["validation"].get("moy_ue", "") for ue in ues
|
validation = ScolarFormSemestreValidation.query.filter_by(
|
||||||
}
|
ue_id=ue.id, etudid=etud.id, formsemestre_id=formsemestre.id
|
||||||
else:
|
).first()
|
||||||
initvalues = {}
|
initvalues[f"note_{ue.id}"] = validation.moy_ue if validation else ""
|
||||||
|
|
||||||
tf = TrivialFormulator(
|
tf = TrivialFormulator(
|
||||||
request.base_url,
|
request.base_url,
|
||||||
scu.get_request_args(),
|
scu.get_request_args(),
|
||||||
descr,
|
descr,
|
||||||
cssclass="tf_ext_edit_ue_validations",
|
|
||||||
submitlabel="Enregistrer ces validations",
|
submitlabel="Enregistrer ces validations",
|
||||||
cancelbutton="Annuler",
|
cancelbutton="Annuler",
|
||||||
initvalues=initvalues,
|
initvalues=initvalues,
|
||||||
|
cssclass="tf_ext_edit_ue_validations ext_apc"
|
||||||
|
if formsemestre.formation.is_apc()
|
||||||
|
else "tf_ext_edit_ue_validations",
|
||||||
|
# En APC, stocke les coefficients pour l'affichage de la moyenne en direct
|
||||||
|
form_attrs=f"""data-ue_coefs='[{', '.join(str(ue.ects or 0) for ue in ues)}]'"""
|
||||||
|
if formsemestre.formation.is_apc()
|
||||||
|
else "",
|
||||||
)
|
)
|
||||||
if tf[0] == -1:
|
if tf[0] == -1:
|
||||||
return "<h4>annulation</h4>"
|
return "<h4>annulation</h4>"
|
||||||
else:
|
else:
|
||||||
H = _make_page(etud, sem, tf)
|
H = _make_page(etud, formsemestre, tf)
|
||||||
if tf[0] == 0: # premier affichage
|
if tf[0] == 0: # premier affichage
|
||||||
return "\n".join(H)
|
return "\n".join(H)
|
||||||
else: # soumission
|
else: # soumission
|
||||||
# simule erreur
|
# simule erreur
|
||||||
ok, message = _check_values(ues, tf[2])
|
ok, message = _check_values(formsemestre, ues, tf[2])
|
||||||
if not ok:
|
if not ok:
|
||||||
H = _make_page(etud, sem, tf, message=message)
|
H = _make_page(etud, formsemestre, tf, message=message)
|
||||||
return "\n".join(H)
|
return "\n".join(H)
|
||||||
else:
|
else:
|
||||||
# Submit
|
# Submit
|
||||||
_record_ue_validations_and_coefs(formsemestre_id, etudid, ues, tf[2])
|
_record_ue_validations_and_coefs(formsemestre, etud, ues, tf[2])
|
||||||
return flask.redirect(
|
return flask.redirect(
|
||||||
"formsemestre_bulletinetud?formsemestre_id=%s&etudid=%s"
|
url_for(
|
||||||
% (formsemestre_id, etudid)
|
"notes.formsemestre_bulletinetud",
|
||||||
|
scodoc_dept=g.scodoc_dept,
|
||||||
|
formsemestre_id=formsemestre_id,
|
||||||
|
etudid=etudid,
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def _make_page(etud: dict, sem, tf, message="") -> list:
|
def _make_page(etud: Identite, formsemestre: FormSemestre, tf, message="") -> list[str]:
|
||||||
formsemestre = FormSemestre.query.get_or_404(sem["formsemestre_id"])
|
"""html formulaire saisie"""
|
||||||
nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
|
nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
|
||||||
moy_gen = nt.get_etud_moy_gen(etud["etudid"])
|
moy_gen = nt.get_etud_moy_gen(etud.id)
|
||||||
H = [
|
H = [
|
||||||
html_sco_header.sco_header(
|
html_sco_header.sco_header(
|
||||||
page_title="Validation des UE d'un semestre extérieur",
|
page_title="Validation des UE d'un semestre extérieur",
|
||||||
javascripts=["js/formsemestre_ext_edit_ue_validations.js"],
|
javascripts=["js/formsemestre_ext_edit_ue_validations.js"],
|
||||||
),
|
),
|
||||||
tf_error_message(message),
|
tf_error_message(message),
|
||||||
"""<p><b>%(nomprenom)s</b> est inscrit%(ne)s à ce semestre extérieur.</p>
|
f"""<p><b>{etud.nomprenom}</b> est inscrit{etud.e} à ce semestre extérieur.</p>
|
||||||
<p>Voici les UE entregistrées avec leur notes et coefficients.
|
<p>Voici ses UE enregistrées avec leur notes
|
||||||
|
{ "et coefficients" if not formsemestre.formation.is_apc()
|
||||||
|
else " (en BUT, les coefficients sont égaux aux ECTS)"}.
|
||||||
</p>
|
</p>
|
||||||
"""
|
""",
|
||||||
% etud,
|
|
||||||
f"""<p>La moyenne de ce semestre serait:
|
f"""<p>La moyenne de ce semestre serait:
|
||||||
<span class="ext_sem_moy"><span class="ext_sem_moy_val">{moy_gen}</span> / 20</span>
|
<span class="ext_sem_moy"><span class="ext_sem_moy_val">{moy_gen}</span> / 20</span>
|
||||||
</p>
|
</p>
|
||||||
@ -298,7 +317,7 @@ def _make_page(etud: dict, sem, tf, message="") -> list:
|
|||||||
f"""<div>
|
f"""<div>
|
||||||
<a class="stdlink"
|
<a class="stdlink"
|
||||||
href="{url_for("notes.formsemestre_bulletinetud", scodoc_dept=g.scodoc_dept,
|
href="{url_for("notes.formsemestre_bulletinetud", scodoc_dept=g.scodoc_dept,
|
||||||
formsemestre_id=formsemestre.id, etudid=etud['etudid']
|
formsemestre_id=formsemestre.id, etudid=etud.id
|
||||||
)}">retour au bulletin de notes</a>
|
)}">retour au bulletin de notes</a>
|
||||||
</div>
|
</div>
|
||||||
""",
|
""",
|
||||||
@ -314,7 +333,9 @@ _UE_VALID_CODES = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def _ue_form_description(ues, values):
|
def _ue_form_description(
|
||||||
|
formsemestre: FormSemestre, etud: Identite, ues: list[UniteEns], values
|
||||||
|
):
|
||||||
"""Description du formulaire de saisie des UE / validations
|
"""Description du formulaire de saisie des UE / validations
|
||||||
Pour chaque UE, on peut saisir: son code jury, sa note, son coefficient.
|
Pour chaque UE, on peut saisir: son code jury, sa note, son coefficient.
|
||||||
"""
|
"""
|
||||||
@ -324,8 +345,14 @@ def _ue_form_description(ues, values):
|
|||||||
{
|
{
|
||||||
"input_type": "separator",
|
"input_type": "separator",
|
||||||
"template": """<tr %(item_dom_attr)s><th>UE</th>
|
"template": """<tr %(item_dom_attr)s><th>UE</th>
|
||||||
<th>Code jury</th><th>Note/20</th><th>Coefficient UE</th></tr>
|
<th>Code jury</th><th>Note/20</th>
|
||||||
""",
|
"""
|
||||||
|
+ (
|
||||||
|
"""<th>Coefficient UE</th>"""
|
||||||
|
if not formsemestre.formation.is_apc()
|
||||||
|
else ""
|
||||||
|
)
|
||||||
|
+ "</tr>",
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
("formsemestre_id", {"input_type": "hidden"}),
|
("formsemestre_id", {"input_type": "hidden"}),
|
||||||
@ -334,59 +361,80 @@ def _ue_form_description(ues, values):
|
|||||||
for ue in ues:
|
for ue in ues:
|
||||||
# Menu pour code validation UE:
|
# Menu pour code validation UE:
|
||||||
# Ne propose que ADM, CMP et "Non inscrit"
|
# Ne propose que ADM, CMP et "Non inscrit"
|
||||||
select_name = "valid_" + str(ue["ue_id"])
|
select_name = f"valid_{ue.id}"
|
||||||
menu_code_UE = """<select class="ueext_valid_select" name="%s">""" % (
|
menu_code_ue = f"""<select class="ueext_valid_select" name="{select_name}">"""
|
||||||
select_name,
|
cur_code_value = values.get("valid_{ue.id}", False)
|
||||||
)
|
for (code, explanation) in _UE_VALID_CODES.items():
|
||||||
cur_value = values.get("valid_" + str(ue["ue_id"]), False)
|
if cur_code_value is False: # pas dans le form, cherche en base
|
||||||
for code in _UE_VALID_CODES:
|
validation = ScolarFormSemestreValidation.query.filter_by(
|
||||||
if cur_value is False: # pas dans le form, cherche en base
|
ue_id=ue.id, etudid=etud.id, formsemestre_id=formsemestre.id
|
||||||
cur_value = ue["validation"].get("code", None)
|
).first()
|
||||||
if str(cur_value) == str(code):
|
cur_code_value = validation.code if validation else None
|
||||||
|
if str(cur_code_value) == str(code):
|
||||||
selected = "selected"
|
selected = "selected"
|
||||||
else:
|
else:
|
||||||
selected = ""
|
selected = ""
|
||||||
menu_code_UE += '<option value="%s" %s>%s</option>' % (
|
# code jury:
|
||||||
code,
|
menu_code_ue += (
|
||||||
selected,
|
f"""<option value="{code}" {selected}>{explanation}</option>"""
|
||||||
_UE_VALID_CODES[code],
|
|
||||||
)
|
)
|
||||||
if cur_value is None:
|
if cur_code_value is None:
|
||||||
disabled = 'disabled="1"'
|
coef_disabled = 'disabled="1"'
|
||||||
else:
|
else:
|
||||||
disabled = ""
|
coef_disabled = ""
|
||||||
menu_code_UE += "</select>"
|
menu_code_ue += "</select>"
|
||||||
cur_value = values.get("coef_" + str(ue["ue_id"]), False)
|
if formsemestre.formation.is_apc():
|
||||||
if cur_value is False: # pas dans le form, cherche en base
|
coef_disabled = 'disabled="1"'
|
||||||
cur_value = ue["uecoef"].get("coefficient", "")
|
cur_coef_value = ue.ects or 0
|
||||||
|
coef_input_class = "ext_coef_disabled"
|
||||||
|
else:
|
||||||
|
cur_coef_value = values.get(f"coef_{ue.id}", False)
|
||||||
|
coef_input_class = ""
|
||||||
|
if cur_coef_value is False: # pas dans le form, cherche en base
|
||||||
|
ue_coef: FormSemestreUECoef = FormSemestreUECoef.query.filter_by(
|
||||||
|
formsemestre_id=formsemestre.id, ue_id=ue.id
|
||||||
|
).first()
|
||||||
|
cur_coef_value = (ue_coef.coefficient if ue_coef else "") or ""
|
||||||
itemtemplate = (
|
itemtemplate = (
|
||||||
"""<tr><td class="tf-fieldlabel">%(label)s</td>"""
|
f"""
|
||||||
+ "<td>"
|
<tr>
|
||||||
+ menu_code_UE
|
<td class="tf-fieldlabel">%(label)s</td>
|
||||||
+ "</td>" # code jury
|
<td>{ menu_code_ue }</td>
|
||||||
+ '<td class="tf-field tf_field_note">%(elem)s</td>' # note
|
<td class="tf-field tf_field_note">%(elem)s</td>
|
||||||
+ """<td class="tf-field tf_field_coef">
|
"""
|
||||||
<input type="text" size="4" name="coef_%s" value="%s" %s></input></td>
|
+ (
|
||||||
"""
|
f"""<td class="tf-field tf_field_coef">
|
||||||
% (ue["ue_id"], cur_value, disabled)
|
<input type="text" size="4" name="coef_{ue.id}"
|
||||||
+ "</td></tr>"
|
class="{coef_input_class}"
|
||||||
|
value="{cur_coef_value}" {coef_disabled}></input>
|
||||||
|
</td>"""
|
||||||
|
if not formsemestre.formation.is_apc()
|
||||||
|
else ""
|
||||||
|
)
|
||||||
|
+ """</tr>"""
|
||||||
)
|
)
|
||||||
|
|
||||||
descr.append(
|
descr.append(
|
||||||
(
|
(
|
||||||
"note_" + str(ue["ue_id"]),
|
f"note_{ue.id}",
|
||||||
{
|
{
|
||||||
"input_type": "text",
|
"input_type": "text",
|
||||||
"size": 4,
|
"size": 4,
|
||||||
"template": itemtemplate,
|
"template": itemtemplate,
|
||||||
"title": "<tt><b>%(acronyme)s</b></tt> %(titre)s" % ue,
|
"title": "<tt>"
|
||||||
"attributes": [disabled],
|
+ (f"S{ue.semestre_idx} " if ue.semestre_idx is not None else "")
|
||||||
|
+ f"<b>{ue.acronyme}</b></tt> {ue.titre}"
|
||||||
|
+ f" ({ue.ects} ECTS)"
|
||||||
|
if ue.ects is not None
|
||||||
|
else "",
|
||||||
|
"attributes": [coef_disabled],
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
return descr
|
return descr
|
||||||
|
|
||||||
|
|
||||||
def _check_values(ue_list, values):
|
def _check_values(formsemestre: FormSemestre, ue_list, values):
|
||||||
"""Check that form values are ok
|
"""Check that form values are ok
|
||||||
for each UE:
|
for each UE:
|
||||||
code != None => note and coef
|
code != None => note and coef
|
||||||
@ -396,107 +444,82 @@ def _check_values(ue_list, values):
|
|||||||
coef float >= 0
|
coef float >= 0
|
||||||
"""
|
"""
|
||||||
for ue in ue_list:
|
for ue in ue_list:
|
||||||
pu = " pour UE %s" % ue["acronyme"]
|
pu = f" pour UE {ue.acronyme}"
|
||||||
code = values.get("valid_" + str(ue["ue_id"]), False)
|
code = values.get(f"valid_{ue.id}", False)
|
||||||
if code == "None":
|
if code == "None":
|
||||||
code = None
|
code = None
|
||||||
note = values.get("note_" + str(ue["ue_id"]), False)
|
note = values.get(f"note_{ue.id}", False)
|
||||||
try:
|
try:
|
||||||
note = _convert_field_to_float(note)
|
note = _convert_field_to_float(note)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
return False, "note invalide" + pu
|
return False, "note invalide" + pu
|
||||||
coef = values.get("coef_" + str(ue["ue_id"]), False)
|
|
||||||
|
if code is not False:
|
||||||
|
if code not in _UE_VALID_CODES:
|
||||||
|
return False, "code invalide" + pu
|
||||||
|
if code is not None:
|
||||||
|
if note is False or note == "":
|
||||||
|
return False, "note manquante" + pu
|
||||||
|
coef = values.get(f"coef_{ue.id}", False)
|
||||||
try:
|
try:
|
||||||
coef = _convert_field_to_float(coef)
|
coef = _convert_field_to_float(coef)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
return False, "coefficient invalide" + pu
|
return False, "coefficient invalide" + pu
|
||||||
if code != False:
|
if note is not False and note != "":
|
||||||
if code not in _UE_VALID_CODES:
|
if code is None:
|
||||||
return False, "code invalide" + pu
|
|
||||||
if code != None:
|
|
||||||
if note is False or note == "":
|
|
||||||
return False, "note manquante" + pu
|
|
||||||
if note != False and note != "":
|
|
||||||
if code == None:
|
|
||||||
return (
|
return (
|
||||||
False,
|
False,
|
||||||
"code jury incohérent (code %s, note %s)" % (code, note)
|
f"""code jury incohérent (code {code}, note {note}) {pu}
|
||||||
+ pu
|
(supprimer note)""",
|
||||||
+ " (supprimer note et coef)",
|
|
||||||
)
|
)
|
||||||
if note < 0 or note > 20:
|
if note < 0 or note > 20:
|
||||||
return False, "valeur note invalide" + pu
|
return False, "valeur note invalide" + pu
|
||||||
if not isinstance(coef, float):
|
if not isinstance(coef, float) and not formsemestre.formation.is_apc():
|
||||||
return False, "coefficient manquant pour note %s" % note + pu
|
return False, f"coefficient manquant pour note {note} {pu}"
|
||||||
if coef != False and coef != "":
|
|
||||||
if coef < 0:
|
# Vérifie valeur coef seulement pour formations classiques:
|
||||||
return False, "valeur coefficient invalide" + pu
|
if not formsemestre.formation.is_apc():
|
||||||
|
if coef is not False and coef != "":
|
||||||
|
if coef < 0:
|
||||||
|
return False, "valeur coefficient invalide" + pu
|
||||||
|
|
||||||
return True, "ok"
|
return True, "ok"
|
||||||
|
|
||||||
|
|
||||||
def _convert_field_to_float(val):
|
def _convert_field_to_float(val):
|
||||||
"""value may be empty, False, or a float. Raise exception"""
|
"""val may be empty, False (left unchanged), or a float. Raise exception ValueError"""
|
||||||
if val != False:
|
if val is not False:
|
||||||
val = val.strip()
|
val = val.strip()
|
||||||
if val:
|
if val:
|
||||||
val = float(val)
|
val = float(val)
|
||||||
return val
|
return val
|
||||||
|
|
||||||
|
|
||||||
def _list_ue_with_coef_and_validations(sem, etudid):
|
def _record_ue_validations_and_coefs(
|
||||||
"""Liste des UE de la même formation que sem,
|
formsemestre: FormSemestre, etud: Identite, ues: list[UniteEns], values
|
||||||
avec leurs coefs d'UE capitalisée (si déjà saisi)
|
):
|
||||||
et leur validation pour cet étudiant.
|
"""Enregistre en base les validations
|
||||||
|
En APC, le coef est toujours NULL
|
||||||
"""
|
"""
|
||||||
cnx = ndb.GetDBConnexion()
|
|
||||||
formsemestre_id = sem["formsemestre_id"]
|
|
||||||
ues = sco_edit_ue.ue_list({"formation_id": sem["formation_id"]})
|
|
||||||
for ue in ues:
|
for ue in ues:
|
||||||
# add coefficient
|
code = values.get(f"valid_{ue.id}", False)
|
||||||
uecoef = sco_formsemestre.formsemestre_uecoef_list(
|
|
||||||
cnx, args={"formsemestre_id": formsemestre_id, "ue_id": ue["ue_id"]}
|
|
||||||
)
|
|
||||||
if uecoef:
|
|
||||||
ue["uecoef"] = uecoef[0]
|
|
||||||
else:
|
|
||||||
ue["uecoef"] = {}
|
|
||||||
# add validation
|
|
||||||
validation = sco_cursus_dut.scolar_formsemestre_validation_list(
|
|
||||||
cnx,
|
|
||||||
args={
|
|
||||||
"formsemestre_id": formsemestre_id,
|
|
||||||
"etudid": etudid,
|
|
||||||
"ue_id": ue["ue_id"],
|
|
||||||
},
|
|
||||||
)
|
|
||||||
if validation:
|
|
||||||
ue["validation"] = validation[0]
|
|
||||||
else:
|
|
||||||
ue["validation"] = {}
|
|
||||||
return ues
|
|
||||||
|
|
||||||
|
|
||||||
def _record_ue_validations_and_coefs(formsemestre_id, etudid, ues, values):
|
|
||||||
for ue in ues:
|
|
||||||
code = values.get("valid_" + str(ue["ue_id"]), False)
|
|
||||||
if code == "None":
|
if code == "None":
|
||||||
code = None
|
code = None
|
||||||
note = values.get("note_" + str(ue["ue_id"]), False)
|
note = values.get(f"note_{ue.id}", False)
|
||||||
note = _convert_field_to_float(note)
|
note = _convert_field_to_float(note)
|
||||||
coef = values.get("coef_" + str(ue["ue_id"]), False)
|
coef = values.get(f"coef_{ue.id}", False)
|
||||||
coef = _convert_field_to_float(coef)
|
coef = _convert_field_to_float(coef)
|
||||||
if coef == "" or coef == False:
|
if coef == "" or coef is False:
|
||||||
coef = None
|
coef = None
|
||||||
now_dmy = time.strftime("%d/%m/%Y")
|
now_dmy = time.strftime("%d/%m/%Y")
|
||||||
log(
|
log(
|
||||||
"_record_ue_validations_and_coefs: %s etudid=%s ue_id=%s moy_ue=%s ue_coef=%s"
|
f"_record_ue_validations_and_coefs: {formsemestre.id} etudid={etud.id} ue_id={ue.id} moy_ue={note} ue_coef={coef}"
|
||||||
% (formsemestre_id, etudid, ue["ue_id"], note, repr(coef))
|
|
||||||
)
|
)
|
||||||
assert code == None or (note) # si code validant, il faut une note
|
assert code is None or (note) # si code validant, il faut une note
|
||||||
sco_formsemestre_validation.do_formsemestre_validate_previous_ue(
|
sco_formsemestre_validation.do_formsemestre_validate_previous_ue(
|
||||||
formsemestre_id,
|
formsemestre.id,
|
||||||
etudid,
|
etud.id,
|
||||||
ue["ue_id"],
|
ue.id,
|
||||||
note,
|
note,
|
||||||
now_dmy,
|
now_dmy,
|
||||||
code=code,
|
code=code,
|
||||||
|
@ -3,21 +3,33 @@
|
|||||||
|
|
||||||
function compute_moyenne() {
|
function compute_moyenne() {
|
||||||
var notes = $(".tf_field_note input").map(
|
var notes = $(".tf_field_note input").map(
|
||||||
function() { return parseFloat($(this).val()); }
|
function () { return parseFloat($(this).val()); }
|
||||||
).get();
|
|
||||||
var coefs = $(".tf_field_coef input").map(
|
|
||||||
function() { return parseFloat($(this).val()); }
|
|
||||||
).get();
|
).get();
|
||||||
|
// les coefs sont donnes (ECTS en BUT)
|
||||||
|
let coefs = $("form.tf_ext_edit_ue_validations").data("ue_coefs");
|
||||||
|
// ou saisis (formations classiques)
|
||||||
|
if (coefs == 'undefined') {
|
||||||
|
coefs = $(".tf_field_coef input").map(
|
||||||
|
function () { return parseFloat($(this).val()); }
|
||||||
|
).get();
|
||||||
|
}
|
||||||
var N = notes.length;
|
var N = notes.length;
|
||||||
var dp = 0.;
|
var dp = 0.;
|
||||||
var sum_coefs = 0.;
|
var sum_coefs = 0.;
|
||||||
for (var i=0; i < N; i++) {
|
for (var i = 0; i < N; i++) {
|
||||||
if (!(isNaN(notes[i]) || isNaN(coefs[i]))) {
|
if (!(isNaN(notes[i]) || isNaN(coefs[i]))) {
|
||||||
dp += notes[i] * coefs[i];
|
dp += notes[i] * coefs[i];
|
||||||
sum_coefs += coefs[i];
|
sum_coefs += coefs[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return dp / sum_coefs;
|
let moy = dp / sum_coefs;
|
||||||
|
if (isNaN(moy)) {
|
||||||
|
moy = "-";
|
||||||
|
}
|
||||||
|
if (typeof moy == "number") {
|
||||||
|
moy = moy.toFixed(2);
|
||||||
|
}
|
||||||
|
return moy;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Callback select menu (UE code)
|
// Callback select menu (UE code)
|
||||||
@ -26,42 +38,44 @@ function enable_disable_fields_cb() {
|
|||||||
}
|
}
|
||||||
function enable_disable_fields(select_elt) {
|
function enable_disable_fields(select_elt) {
|
||||||
// input fields controled by this menu
|
// input fields controled by this menu
|
||||||
var input_fields = $(select_elt).parent().parent().find('input');
|
var input_fields = $(select_elt).parent().parent().find('input:not(.ext_coef_disabled)');
|
||||||
var disabled = false;
|
var disabled = false;
|
||||||
if ($(select_elt).val() === "None") {
|
if ($(select_elt).val() === "None") {
|
||||||
disabled = true;
|
disabled = true;
|
||||||
}
|
}
|
||||||
console.log('disabled=', disabled);
|
input_fields.each(function () {
|
||||||
input_fields.each( function () {
|
if (disabled) {
|
||||||
var old_state = this.disabled;
|
let cur_value = $(this).val();
|
||||||
console.log("old_state=", old_state)
|
$(this).data('saved-value', cur_value);
|
||||||
if (old_state == disabled) {
|
$(this).val("");
|
||||||
return; /* state unchanged */
|
} else {
|
||||||
|
let saved_value = $(this).data('saved-value');
|
||||||
|
if (typeof saved_value == 'undefined') {
|
||||||
|
saved_value = '';
|
||||||
|
}
|
||||||
|
if (saved_value) {
|
||||||
|
$(this).val(saved_value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
var saved_value = $(this).data('saved-value');
|
|
||||||
if (typeof saved_value == 'undefined') {
|
|
||||||
saved_value = '';
|
|
||||||
}
|
|
||||||
var cur_value = $(this).val();
|
|
||||||
// swap
|
|
||||||
$(this).data('saved-value', cur_value);
|
|
||||||
$(this).val(saved_value);
|
|
||||||
});
|
});
|
||||||
input_fields.prop('disabled', disabled);
|
input_fields.prop('disabled', disabled);
|
||||||
}
|
}
|
||||||
function setup_text_fields() {
|
function setup_text_fields() {
|
||||||
$(".ueext_valid_select").each(
|
$(".ueext_valid_select").each(
|
||||||
function() {
|
function () {
|
||||||
enable_disable_fields(this);
|
enable_disable_fields(this);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$().ready(function(){
|
$().ready(function () {
|
||||||
$(".tf_ext_edit_ue_validations").change(function (){
|
$(".tf_ext_edit_ue_validations").change(function () {
|
||||||
$(".ext_sem_moy_val")[0].innerHTML=compute_moyenne();
|
$(".ext_sem_moy_val")[0].innerHTML = compute_moyenne();
|
||||||
});
|
});
|
||||||
$(".ueext_valid_select").change( enable_disable_fields_cb );
|
$("form.tf_ext_edit_ue_validations input").blur(function () {
|
||||||
|
$(".ext_sem_moy_val")[0].innerHTML = compute_moyenne();
|
||||||
|
});
|
||||||
|
$(".ueext_valid_select").change(enable_disable_fields_cb);
|
||||||
|
|
||||||
setup_text_fields();
|
setup_text_fields();
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user