forked from ScoDoc/ScoDoc
Compare commits
No commits in common. "08a585aa1b25ca03de650d27729e0ec0db7fa921" and "dc25ad7ca22aab15e97d85e5946af1c66ec8e2fa" have entirely different histories.
08a585aa1b
...
dc25ad7ca2
@ -239,7 +239,7 @@ class LogoForm(FlaskForm):
|
|||||||
|
|
||||||
if self.do_delete.data and self.can_delete:
|
if self.do_delete.data and self.can_delete:
|
||||||
return LogoDelete.build_action(self.data)
|
return LogoDelete.build_action(self.data)
|
||||||
if self.upload.data:
|
if self.upload.data and self.validate():
|
||||||
return LogoUpdate.build_action(self.data)
|
return LogoUpdate.build_action(self.data)
|
||||||
if self.do_rename.data and self.validate():
|
if self.do_rename.data and self.validate():
|
||||||
return LogoRename.build_action(self.data)
|
return LogoRename.build_action(self.data)
|
||||||
|
@ -760,7 +760,7 @@ class GenTable:
|
|||||||
return js
|
return js
|
||||||
else:
|
else:
|
||||||
log(f"make_page: format={fmt}")
|
log(f"make_page: format={fmt}")
|
||||||
raise ValueError("make_page: invalid format")
|
raise ValueError("_make_page: invalid format")
|
||||||
|
|
||||||
|
|
||||||
# -----
|
# -----
|
||||||
|
@ -25,9 +25,222 @@
|
|||||||
#
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
"""Legacy constants (TODO: remove)"""
|
"""HTML Header/Footer for ScoDoc pages"""
|
||||||
|
|
||||||
|
from flask import g, render_template, url_for
|
||||||
|
from flask_login import current_user
|
||||||
|
|
||||||
|
import app.scodoc.sco_utils as scu
|
||||||
|
from app import scodoc_flash_status_messages
|
||||||
|
from app.scodoc import html_sidebar
|
||||||
|
import sco_version
|
||||||
|
|
||||||
|
|
||||||
# Some constants:
|
# Some constants:
|
||||||
BOOTSTRAP_JS = ["libjs/bootstrap/js/bootstrap.min.js", "libjs/purl.js"]
|
BOOTSTRAP_JS = ["libjs/bootstrap/js/bootstrap.min.js", "libjs/purl.js"]
|
||||||
BOOTSTRAP_CSS = ["libjs/bootstrap/css/bootstrap.min.css"]
|
BOOTSTRAP_CSS = ["libjs/bootstrap/css/bootstrap.min.css"]
|
||||||
|
|
||||||
|
|
||||||
|
def standard_html_header():
|
||||||
|
"""Standard HTML header for pages outside depts"""
|
||||||
|
# not used in ZScolar, see sco_header
|
||||||
|
return f"""<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
||||||
|
<html><head>
|
||||||
|
<title>ScoDoc: accueil</title>
|
||||||
|
<META http-equiv="Content-Type" content="text/html; charset={scu.SCO_ENCODING}">
|
||||||
|
<META http-equiv="Content-Style-Type" content="text/css">
|
||||||
|
<META name="LANG" content="fr">
|
||||||
|
<META name="DESCRIPTION" content="ScoDoc: gestion scolarite">
|
||||||
|
|
||||||
|
<link href="{scu.STATIC_DIR}/css/scodoc.css" rel="stylesheet" type="text/css"/>
|
||||||
|
|
||||||
|
</head><body>{scu.CUSTOM_HTML_HEADER_CNX}"""
|
||||||
|
|
||||||
|
|
||||||
|
def standard_html_footer():
|
||||||
|
"""Le pied de page HTML de la page d'accueil."""
|
||||||
|
return f"""<p class="footer">
|
||||||
|
Problème de connexion (identifiant, mot de passe): <em>contacter votre responsable ou chef de département</em>.</p>
|
||||||
|
<p>Problèmes et suggestions sur le logiciel: <a href="mailto:{scu.SCO_USERS_LIST}">{scu.SCO_USERS_LIST}</a></p>
|
||||||
|
<p><em>ScoDoc est un logiciel libre développé par Emmanuel Viennet.</em></p>
|
||||||
|
</body></html>"""
|
||||||
|
|
||||||
|
|
||||||
|
_HTML_BEGIN = f"""<!DOCTYPE html>
|
||||||
|
<html lang="fr">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=%(encoding)s" />
|
||||||
|
<meta http-equiv="Content-Style-Type" content="text/css" />
|
||||||
|
<meta name="LANG" content="fr" />
|
||||||
|
<meta name="DESCRIPTION" content="ScoDoc" />
|
||||||
|
<title>%(page_title)s</title>
|
||||||
|
|
||||||
|
<link type="text/css" rel="stylesheet" href="{scu.STATIC_DIR}/libjs/jquery-ui-1.10.4.custom/css/smoothness/jquery-ui-1.10.4.custom.min.css" />
|
||||||
|
|
||||||
|
<link href="{scu.STATIC_DIR}/css/scodoc.css" rel="stylesheet" type="text/css" />
|
||||||
|
<link href="{scu.STATIC_DIR}/css/menu.css" rel="stylesheet" type="text/css" />
|
||||||
|
<link rel="stylesheet" type="text/css" href="{scu.STATIC_DIR}/DataTables/datatables.min.css" />
|
||||||
|
<link href="{scu.STATIC_DIR}/css/gt_table.css" rel="stylesheet" type="text/css" />
|
||||||
|
<script src="{scu.STATIC_DIR}/libjs/menu.js"></script>
|
||||||
|
<script src="{scu.STATIC_DIR}/libjs/bubble.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
<script src="{scu.STATIC_DIR}/jQuery/jquery.js"></script>
|
||||||
|
<script src="{scu.STATIC_DIR}/jQuery/jquery-migrate-3.5.2.min.js"></script>
|
||||||
|
<script src="{scu.STATIC_DIR}/libjs/jquery.field.min.js"></script>
|
||||||
|
|
||||||
|
<script src="{scu.STATIC_DIR}/libjs/jquery-ui-1.10.4.custom/js/jquery-ui-1.10.4.custom.min.js"></script>
|
||||||
|
<script src="{scu.STATIC_DIR}/DataTables/datatables.min.js"></script>
|
||||||
|
|
||||||
|
<script src="{scu.STATIC_DIR}/libjs/qtip/jquery.qtip-3.0.3.min.js"></script>
|
||||||
|
<link type="text/css" rel="stylesheet" href="{scu.STATIC_DIR}/libjs/qtip/jquery.qtip-3.0.3.min.css" />
|
||||||
|
|
||||||
|
<link type="text/css" rel="stylesheet" href="{scu.STATIC_DIR}/libjs/timepicker-1.3.5/jquery.timepicker.min.css" />
|
||||||
|
<script src="{scu.STATIC_DIR}/libjs/timepicker-1.3.5/jquery.timepicker.min.js"></script>
|
||||||
|
|
||||||
|
<script src="{scu.STATIC_DIR}/js/scodoc.js"></script>
|
||||||
|
<script src="{scu.STATIC_DIR}/js/etud_info.js"></script>
|
||||||
|
|
||||||
|
<script src="{scu.STATIC_DIR}/libjs/qtip/jquery.qtip-3.0.3.min.js"></script>
|
||||||
|
<link type="text/css" rel="stylesheet" href="{scu.STATIC_DIR}/libjs/qtip/jquery.qtip-3.0.3.min.css" />
|
||||||
|
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {{
|
||||||
|
if (document.getElementById('gtrcontent')) {{
|
||||||
|
enableTooltips("gtrcontent");
|
||||||
|
}}
|
||||||
|
if (document.getElementById('sidebar')) {{
|
||||||
|
enableTooltips("sidebar");
|
||||||
|
}}
|
||||||
|
}});
|
||||||
|
</script>
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def scodoc_top_html_header(page_title="ScoDoc: bienvenue"):
|
||||||
|
"""HTML header for top level pages"""
|
||||||
|
H = [
|
||||||
|
_HTML_BEGIN % {"page_title": page_title, "encoding": scu.SCO_ENCODING},
|
||||||
|
"""</head><body id="gtrcontent">""",
|
||||||
|
scu.CUSTOM_HTML_HEADER_CNX,
|
||||||
|
]
|
||||||
|
return "\n".join(H)
|
||||||
|
|
||||||
|
|
||||||
|
# Header:
|
||||||
|
def sco_header(
|
||||||
|
# optional args
|
||||||
|
page_title="", # page title
|
||||||
|
no_sidebar=False, # hide sidebar
|
||||||
|
cssstyles=(), # additionals CSS sheets
|
||||||
|
javascripts=(), # additionals JS filenames to load
|
||||||
|
scripts=(), # script to put in page header
|
||||||
|
init_google_maps=False, # Google maps
|
||||||
|
titrebandeau="", # titre dans bandeau superieur
|
||||||
|
etudid=None,
|
||||||
|
formsemestre_id=None,
|
||||||
|
):
|
||||||
|
"""Main HTML page header for ScoDoc
|
||||||
|
Utilisé dans les anciennes pages. Les nouvelles pages utilisent le template Jinja.
|
||||||
|
"""
|
||||||
|
from app.scodoc.sco_formsemestre_status import formsemestre_page_title
|
||||||
|
|
||||||
|
if etudid is not None:
|
||||||
|
g.current_etudid = etudid
|
||||||
|
scodoc_flash_status_messages()
|
||||||
|
|
||||||
|
params = {
|
||||||
|
"page_title": page_title or sco_version.SCONAME,
|
||||||
|
"no_sidebar": no_sidebar,
|
||||||
|
"ScoURL": url_for("scolar.index_html", scodoc_dept=g.scodoc_dept),
|
||||||
|
"encoding": scu.SCO_ENCODING,
|
||||||
|
"titrebandeau_mkup": "<td>" + titrebandeau + "</td>",
|
||||||
|
"authuser": current_user.user_name,
|
||||||
|
}
|
||||||
|
if no_sidebar:
|
||||||
|
params["margin_left"] = "1em"
|
||||||
|
else:
|
||||||
|
params["margin_left"] = "140px"
|
||||||
|
|
||||||
|
H = [_HTML_BEGIN % params]
|
||||||
|
|
||||||
|
if init_google_maps:
|
||||||
|
# It may be necessary to add an API key:
|
||||||
|
H.append('<script src="https://maps.google.com/maps/api/js"></script>')
|
||||||
|
|
||||||
|
# Feuilles de style additionnelles:
|
||||||
|
for cssstyle in cssstyles:
|
||||||
|
H.append(
|
||||||
|
f"""<link type="text/css" rel="stylesheet" href="{scu.STATIC_DIR}/{cssstyle}" />\n"""
|
||||||
|
)
|
||||||
|
|
||||||
|
H.append(
|
||||||
|
f"""
|
||||||
|
<script>
|
||||||
|
const SCO_URL="{url_for("scolar.index_html", scodoc_dept=g.scodoc_dept)}";
|
||||||
|
const SCO_TIMEZONE="{scu.TIME_ZONE}";
|
||||||
|
</script>"""
|
||||||
|
)
|
||||||
|
|
||||||
|
if init_google_maps: # utilisé uniquement pour carte lycées
|
||||||
|
H.append(
|
||||||
|
f'<script src="{scu.STATIC_DIR}/libjs/jquery.ui.map.full.min.js"></script>'
|
||||||
|
)
|
||||||
|
|
||||||
|
# JS additionels
|
||||||
|
for js in javascripts:
|
||||||
|
H.append(f"""<script src="{scu.STATIC_DIR}/{js}"></script>\n""")
|
||||||
|
|
||||||
|
H.append(
|
||||||
|
f"""<style>
|
||||||
|
#gtrcontent {{
|
||||||
|
margin-left: {params["margin_left"]};
|
||||||
|
height: 100%%;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}}
|
||||||
|
</style>
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
# Scripts de la page:
|
||||||
|
if scripts:
|
||||||
|
H.append("""<script>""")
|
||||||
|
for script in scripts:
|
||||||
|
H.append(script)
|
||||||
|
H.append("""</script>""")
|
||||||
|
|
||||||
|
# Fin head, Body et bandeau haut:
|
||||||
|
H.append(
|
||||||
|
f"""</head>
|
||||||
|
<!-- Legacy ScoDoc header -->
|
||||||
|
<body>
|
||||||
|
{scu.CUSTOM_HTML_HEADER}
|
||||||
|
{'' if no_sidebar else html_sidebar.sidebar(etudid)}
|
||||||
|
<div id="mobileNav" mobile="true" style="display:none;"></div>
|
||||||
|
|
||||||
|
<div id="gtrcontent">
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
# En attendant le replacement complet de cette fonction,
|
||||||
|
# inclusion ici des messages flask
|
||||||
|
H.append(render_template("flashed_messages.j2"))
|
||||||
|
#
|
||||||
|
# Barre menu semestre:
|
||||||
|
H.append(formsemestre_page_title(formsemestre_id))
|
||||||
|
|
||||||
|
# div pour affichage messages temporaires
|
||||||
|
H.append('<div id="sco_msg" class="head_message"></div>')
|
||||||
|
#
|
||||||
|
H.append('<div class="sco-app-content">')
|
||||||
|
return "".join(H)
|
||||||
|
|
||||||
|
|
||||||
|
def sco_footer():
|
||||||
|
"""Main HTMl pages footer"""
|
||||||
|
return (
|
||||||
|
"""</div></div><!-- /gtrcontent -->"""
|
||||||
|
+ scu.CUSTOM_HTML_FOOTER
|
||||||
|
+ """</body></html>"""
|
||||||
|
)
|
||||||
|
@ -69,6 +69,7 @@ et sur page "réglages bulletin" (avec formsemestre_id)
|
|||||||
# raise ValueError("invalid value for 'side' parameter")
|
# raise ValueError("invalid value for 'side' parameter")
|
||||||
# signatureloc = get_bul_sig_img()
|
# signatureloc = get_bul_sig_img()
|
||||||
# H = [
|
# H = [
|
||||||
|
# self.sco_header(page_title="Changement de signature"),
|
||||||
# """<h2>Changement de la signature bulletin de %(sidetxt)s</h2>
|
# """<h2>Changement de la signature bulletin de %(sidetxt)s</h2>
|
||||||
# """
|
# """
|
||||||
# % (sidetxt,),
|
# % (sidetxt,),
|
||||||
|
@ -43,6 +43,7 @@ import app.scodoc.sco_utils as scu
|
|||||||
from app.scodoc.TrivialFormulator import TrivialFormulator, tf_error_message
|
from app.scodoc.TrivialFormulator import TrivialFormulator, tf_error_message
|
||||||
from app.scodoc.sco_exceptions import ScoValueError, ScoNonEmptyFormationObject
|
from app.scodoc.sco_exceptions import ScoValueError, ScoNonEmptyFormationObject
|
||||||
|
|
||||||
|
from app.scodoc import html_sco_header
|
||||||
from app.scodoc import sco_cache
|
from app.scodoc import sco_cache
|
||||||
from app.scodoc import codes_cursus
|
from app.scodoc import codes_cursus
|
||||||
from app.scodoc import sco_edit_ue
|
from app.scodoc import sco_edit_ue
|
||||||
@ -95,7 +96,7 @@ def formation_delete(formation_id=None, dialog_confirmed=False):
|
|||||||
)
|
)
|
||||||
|
|
||||||
return render_template(
|
return render_template(
|
||||||
"sco_page_dept.j2", content="\n".join(H), title="Suppression d'une formation"
|
"sco_page-dept.j2", content="\n".join(H), title="Suppression d'une formation"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -145,6 +146,7 @@ def formation_edit(formation_id=None, create=False):
|
|||||||
"""Edit or create a formation"""
|
"""Edit or create a formation"""
|
||||||
if create:
|
if create:
|
||||||
H = [
|
H = [
|
||||||
|
html_sco_header.sco_header(page_title="Création d'une formation"),
|
||||||
"""<h2>Création d'une formation</h2>
|
"""<h2>Création d'une formation</h2>
|
||||||
|
|
||||||
<p class="help">Une "formation" décrit une filière, comme un DUT ou une Licence. La formation se subdivise en unités pédagogiques (UE, matières, modules). Elle peut se diviser en plusieurs semestres (ou sessions), qui seront mis en place séparément.
|
<p class="help">Une "formation" décrit une filière, comme un DUT ou une Licence. La formation se subdivise en unités pédagogiques (UE, matières, modules). Elle peut se diviser en plusieurs semestres (ou sessions), qui seront mis en place séparément.
|
||||||
@ -166,6 +168,7 @@ def formation_edit(formation_id=None, create=False):
|
|||||||
is_locked = formation.has_locked_sems(formation_id)
|
is_locked = formation.has_locked_sems(formation_id)
|
||||||
submitlabel = "Modifier les valeurs"
|
submitlabel = "Modifier les valeurs"
|
||||||
H = [
|
H = [
|
||||||
|
html_sco_header.sco_header(page_title="Modification d'une formation"),
|
||||||
f"""<h2>Modification de la formation {formation.acronyme}
|
f"""<h2>Modification de la formation {formation.acronyme}
|
||||||
version {formation.version}
|
version {formation.version}
|
||||||
</h2>""",
|
</h2>""",
|
||||||
@ -248,57 +251,52 @@ def formation_edit(formation_id=None, create=False):
|
|||||||
submitlabel=submitlabel,
|
submitlabel=submitlabel,
|
||||||
)
|
)
|
||||||
if tf[0] == 0:
|
if tf[0] == 0:
|
||||||
return render_template(
|
return "\n".join(H) + tf[1] + html_sco_header.sco_footer()
|
||||||
"sco_page_dept.j2",
|
elif tf[0] == -1:
|
||||||
title="Modification d'une formation",
|
|
||||||
content="\n".join(H) + tf[1],
|
|
||||||
)
|
|
||||||
if tf[0] == -1:
|
|
||||||
return flask.redirect(url_for("notes.index_html", scodoc_dept=g.scodoc_dept))
|
return flask.redirect(url_for("notes.index_html", scodoc_dept=g.scodoc_dept))
|
||||||
|
|
||||||
# check unicity : constraint UNIQUE(acronyme,titre,version)
|
|
||||||
if create:
|
|
||||||
version = 1
|
|
||||||
else:
|
else:
|
||||||
version = initvalues["version"]
|
# check unicity : constraint UNIQUE(acronyme,titre,version)
|
||||||
args = {
|
if create:
|
||||||
"acronyme": tf[2]["acronyme"],
|
version = 1
|
||||||
"titre": tf[2]["titre"],
|
else:
|
||||||
"version": version,
|
version = initvalues["version"]
|
||||||
"dept_id": g.scodoc_dept_id,
|
args = {
|
||||||
}
|
"acronyme": tf[2]["acronyme"],
|
||||||
other_formations: list[Formation] = Formation.query.filter_by(**args).all()
|
"titre": tf[2]["titre"],
|
||||||
if other_formations and (
|
"version": version,
|
||||||
(len(other_formations) > 1) or other_formations[0].id != formation_id
|
"dept_id": g.scodoc_dept_id,
|
||||||
):
|
}
|
||||||
return render_template(
|
other_formations: list[Formation] = Formation.query.filter_by(**args).all()
|
||||||
"sco_page_dept.j2",
|
if other_formations and (
|
||||||
title="Modification d'une formation",
|
(len(other_formations) > 1) or other_formations[0].id != formation_id
|
||||||
content=(
|
):
|
||||||
|
return (
|
||||||
"\n".join(H)
|
"\n".join(H)
|
||||||
+ tf_error_message(
|
+ tf_error_message(
|
||||||
f"""Valeurs incorrectes: il existe déjà <a href="{
|
f"""Valeurs incorrectes: il existe déjà <a href="{
|
||||||
url_for('notes.ue_table',
|
url_for('notes.ue_table',
|
||||||
scodoc_dept=g.scodoc_dept, formation_id=other_formations[0].id)
|
scodoc_dept=g.scodoc_dept, formation_id=other_formations[0].id)
|
||||||
}">une formation</a> avec même titre,
|
}">une formation</a> avec même titre,
|
||||||
acronyme et version.
|
acronyme et version.
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
+ tf[1]
|
+ tf[1]
|
||||||
),
|
+ html_sco_header.sco_footer()
|
||||||
)
|
|
||||||
#
|
|
||||||
if create:
|
|
||||||
formation = do_formation_create(tf[2])
|
|
||||||
else:
|
|
||||||
if do_formation_edit(tf[2]):
|
|
||||||
flash(
|
|
||||||
f"""Modification de la formation {
|
|
||||||
formation.titre} ({formation.acronyme}) version {formation.version}"""
|
|
||||||
)
|
)
|
||||||
return flask.redirect(
|
#
|
||||||
url_for("notes.ue_table", scodoc_dept=g.scodoc_dept, formation_id=formation.id)
|
if create:
|
||||||
)
|
formation = do_formation_create(tf[2])
|
||||||
|
else:
|
||||||
|
if do_formation_edit(tf[2]):
|
||||||
|
flash(
|
||||||
|
f"""Modification de la formation {
|
||||||
|
formation.titre} ({formation.acronyme}) version {formation.version}"""
|
||||||
|
)
|
||||||
|
return flask.redirect(
|
||||||
|
url_for(
|
||||||
|
"notes.ue_table", scodoc_dept=g.scodoc_dept, formation_id=formation.id
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def do_formation_create(args: dict) -> Formation:
|
def do_formation_create(args: dict) -> Formation:
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
(portage from DTML)
|
(portage from DTML)
|
||||||
"""
|
"""
|
||||||
import flask
|
import flask
|
||||||
from flask import g, render_template, request, url_for
|
from flask import g, url_for, request
|
||||||
|
|
||||||
from app import db, log
|
from app import db, log
|
||||||
from app.models import Formation, Matiere, UniteEns, ScolarNews
|
from app.models import Formation, Matiere, UniteEns, ScolarNews
|
||||||
@ -43,6 +43,7 @@ from app.scodoc.sco_exceptions import (
|
|||||||
ScoLockedFormError,
|
ScoLockedFormError,
|
||||||
ScoNonEmptyFormationObject,
|
ScoNonEmptyFormationObject,
|
||||||
)
|
)
|
||||||
|
from app.scodoc import html_sco_header
|
||||||
|
|
||||||
_matiereEditor = ndb.EditableTable(
|
_matiereEditor = ndb.EditableTable(
|
||||||
"notes_matieres",
|
"notes_matieres",
|
||||||
@ -62,6 +63,7 @@ def matiere_list(*args, **kw):
|
|||||||
def do_matiere_edit(*args, **kw):
|
def do_matiere_edit(*args, **kw):
|
||||||
"edit a matiere"
|
"edit a matiere"
|
||||||
from app.scodoc import sco_edit_ue
|
from app.scodoc import sco_edit_ue
|
||||||
|
from app.scodoc import sco_edit_formation
|
||||||
|
|
||||||
cnx = ndb.GetDBConnexion()
|
cnx = ndb.GetDBConnexion()
|
||||||
# check
|
# check
|
||||||
@ -77,6 +79,7 @@ def do_matiere_edit(*args, **kw):
|
|||||||
def do_matiere_create(args):
|
def do_matiere_create(args):
|
||||||
"create a matiere"
|
"create a matiere"
|
||||||
from app.scodoc import sco_edit_ue
|
from app.scodoc import sco_edit_ue
|
||||||
|
from app.models import ScolarNews
|
||||||
|
|
||||||
cnx = ndb.GetDBConnexion()
|
cnx = ndb.GetDBConnexion()
|
||||||
# check
|
# check
|
||||||
@ -100,6 +103,7 @@ def matiere_create(ue_id=None):
|
|||||||
ue: UniteEns = UniteEns.query.get_or_404(ue_id)
|
ue: UniteEns = UniteEns.query.get_or_404(ue_id)
|
||||||
default_numero = max([mat.numero for mat in ue.matieres] or [9]) + 1
|
default_numero = max([mat.numero for mat in ue.matieres] or [9]) + 1
|
||||||
H = [
|
H = [
|
||||||
|
html_sco_header.sco_header(page_title="Création d'une matière"),
|
||||||
f"""<h2>Création d'une matière dans l'UE {ue.titre or ''} ({ue.acronyme})</h2>
|
f"""<h2>Création d'une matière dans l'UE {ue.titre or ''} ({ue.acronyme})</h2>
|
||||||
<p class="help">Les matières sont des groupes de modules dans une UE
|
<p class="help">Les matières sont des groupes de modules dans une UE
|
||||||
d'une formation donnée. Les matières servent surtout pour la
|
d'une formation donnée. Les matières servent surtout pour la
|
||||||
@ -147,25 +151,21 @@ associé.
|
|||||||
)
|
)
|
||||||
|
|
||||||
if tf[0] == 0:
|
if tf[0] == 0:
|
||||||
return render_template(
|
return "\n".join(H) + tf[1] + html_sco_header.sco_footer()
|
||||||
"sco_page.j2", title="Création d'une matière", content="\n".join(H) + tf[1]
|
elif tf[0] == -1:
|
||||||
)
|
|
||||||
if tf[0] == -1:
|
|
||||||
return flask.redirect(dest_url)
|
return flask.redirect(dest_url)
|
||||||
# check unicity
|
else:
|
||||||
mats = matiere_list(args={"ue_id": ue_id, "titre": tf[2]["titre"]})
|
# check unicity
|
||||||
if mats:
|
mats = matiere_list(args={"ue_id": ue_id, "titre": tf[2]["titre"]})
|
||||||
return render_template(
|
if mats:
|
||||||
"sco_page.j2",
|
return (
|
||||||
title="Création d'une matière",
|
|
||||||
content=(
|
|
||||||
"\n".join(H)
|
"\n".join(H)
|
||||||
+ tf_error_message("Titre de matière déjà existant dans cette UE")
|
+ tf_error_message("Titre de matière déjà existant dans cette UE")
|
||||||
+ tf[1]
|
+ tf[1]
|
||||||
),
|
+ html_sco_header.sco_footer()
|
||||||
)
|
)
|
||||||
_ = do_matiere_create(tf[2])
|
_ = do_matiere_create(tf[2])
|
||||||
return flask.redirect(dest_url)
|
return flask.redirect(dest_url)
|
||||||
|
|
||||||
|
|
||||||
def can_delete_matiere(matiere: Matiere) -> tuple[bool, str]:
|
def can_delete_matiere(matiere: Matiere) -> tuple[bool, str]:
|
||||||
@ -230,6 +230,7 @@ def matiere_delete(matiere_id=None):
|
|||||||
mat = matiere_list(args={"matiere_id": matiere_id})[0]
|
mat = matiere_list(args={"matiere_id": matiere_id})[0]
|
||||||
UE = sco_edit_ue.ue_list(args={"ue_id": mat["ue_id"]})[0]
|
UE = sco_edit_ue.ue_list(args={"ue_id": mat["ue_id"]})[0]
|
||||||
H = [
|
H = [
|
||||||
|
html_sco_header.sco_header(page_title="Suppression d'une matière"),
|
||||||
"<h2>Suppression de la matière %(titre)s" % mat,
|
"<h2>Suppression de la matière %(titre)s" % mat,
|
||||||
" dans l'UE (%(acronyme)s))</h2>" % UE,
|
" dans l'UE (%(acronyme)s))</h2>" % UE,
|
||||||
]
|
]
|
||||||
@ -247,16 +248,12 @@ def matiere_delete(matiere_id=None):
|
|||||||
cancelbutton="Annuler",
|
cancelbutton="Annuler",
|
||||||
)
|
)
|
||||||
if tf[0] == 0:
|
if tf[0] == 0:
|
||||||
return render_template(
|
return "\n".join(H) + tf[1] + html_sco_header.sco_footer()
|
||||||
"sco_page.j2",
|
elif tf[0] == -1:
|
||||||
title="Suppression d'une matière",
|
return flask.redirect(dest_url)
|
||||||
content="\n".join(H) + tf[1],
|
else:
|
||||||
)
|
do_matiere_delete(matiere_id)
|
||||||
if tf[0] == -1:
|
|
||||||
return flask.redirect(dest_url)
|
return flask.redirect(dest_url)
|
||||||
|
|
||||||
do_matiere_delete(matiere_id)
|
|
||||||
return flask.redirect(dest_url)
|
|
||||||
|
|
||||||
|
|
||||||
def matiere_edit(matiere_id=None):
|
def matiere_edit(matiere_id=None):
|
||||||
@ -276,10 +273,11 @@ def matiere_edit(matiere_id=None):
|
|||||||
ue_names = ["%(acronyme)s (%(titre)s)" % u for u in ues]
|
ue_names = ["%(acronyme)s (%(titre)s)" % u for u in ues]
|
||||||
ue_ids = [u["ue_id"] for u in ues]
|
ue_ids = [u["ue_id"] for u in ues]
|
||||||
H = [
|
H = [
|
||||||
|
html_sco_header.sco_header(page_title="Modification d'une matière"),
|
||||||
"""<h2>Modification de la matière %(titre)s""" % F,
|
"""<h2>Modification de la matière %(titre)s""" % F,
|
||||||
f"""(formation ({formation.acronyme}, version {formation.version})</h2>""",
|
f"""(formation ({formation.acronyme}, version {formation.version})</h2>""",
|
||||||
]
|
]
|
||||||
help_msg = """<p class="help">Les matières sont des groupes de modules dans une UE
|
help = """<p class="help">Les matières sont des groupes de modules dans une UE
|
||||||
d'une formation donnée. Les matières servent surtout pour la
|
d'une formation donnée. Les matières servent surtout pour la
|
||||||
présentation (bulletins, etc) mais <em>n'ont pas de rôle dans le calcul
|
présentation (bulletins, etc) mais <em>n'ont pas de rôle dans le calcul
|
||||||
des notes.</em>
|
des notes.</em>
|
||||||
@ -327,25 +325,18 @@ associé.
|
|||||||
formation_id=str(ue["formation_id"]),
|
formation_id=str(ue["formation_id"]),
|
||||||
)
|
)
|
||||||
if tf[0] == 0:
|
if tf[0] == 0:
|
||||||
return render_template(
|
return "\n".join(H) + tf[1] + help + html_sco_header.sco_footer()
|
||||||
"sco_page.j2",
|
|
||||||
title="Modification d'une matière",
|
|
||||||
content="\n".join(H) + tf[1] + help_msg,
|
|
||||||
)
|
|
||||||
elif tf[0] == -1:
|
elif tf[0] == -1:
|
||||||
return flask.redirect(dest_url)
|
return flask.redirect(dest_url)
|
||||||
else:
|
else:
|
||||||
# check unicity
|
# check unicity
|
||||||
mats = matiere_list(args={"ue_id": tf[2]["ue_id"], "titre": tf[2]["titre"]})
|
mats = matiere_list(args={"ue_id": tf[2]["ue_id"], "titre": tf[2]["titre"]})
|
||||||
if len(mats) > 1 or (len(mats) == 1 and mats[0]["matiere_id"] != matiere_id):
|
if len(mats) > 1 or (len(mats) == 1 and mats[0]["matiere_id"] != matiere_id):
|
||||||
return render_template(
|
return (
|
||||||
"sco_page.j2",
|
"\n".join(H)
|
||||||
title="Modification d'une matière",
|
+ tf_error_message("Titre de matière déjà existant dans cette UE")
|
||||||
content=(
|
+ tf[1]
|
||||||
"\n".join(H)
|
+ html_sco_header.sco_footer()
|
||||||
+ tf_error_message("Titre de matière déjà existant dans cette UE")
|
|
||||||
+ tf[1]
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# changement d'UE ?
|
# changement d'UE ?
|
||||||
|
@ -32,11 +32,12 @@ import io
|
|||||||
from zipfile import ZipFile
|
from zipfile import ZipFile
|
||||||
|
|
||||||
import flask
|
import flask
|
||||||
from flask import flash, g, render_template, request, Response, send_file, url_for
|
from flask import flash, g, request, Response, send_file, url_for
|
||||||
|
|
||||||
import app.scodoc.sco_utils as scu
|
import app.scodoc.sco_utils as scu
|
||||||
from app import log
|
from app import log
|
||||||
from app.models import Formation
|
from app.models import Formation
|
||||||
|
from app.scodoc import html_sco_header
|
||||||
from app.scodoc import sco_apogee_csv, sco_apogee_reader
|
from app.scodoc import sco_apogee_csv, sco_apogee_reader
|
||||||
from app.scodoc import sco_etape_apogee
|
from app.scodoc import sco_etape_apogee
|
||||||
from app.scodoc import sco_formsemestre
|
from app.scodoc import sco_formsemestre
|
||||||
@ -99,6 +100,10 @@ def apo_semset_maq_status(
|
|||||||
ok_for_export &= semset["jury_ok"]
|
ok_for_export &= semset["jury_ok"]
|
||||||
|
|
||||||
H = [
|
H = [
|
||||||
|
html_sco_header.sco_header(
|
||||||
|
page_title="Export Apogée",
|
||||||
|
javascripts=["js/apo_semset_maq_status.js"],
|
||||||
|
),
|
||||||
"""<h2>Export des résultats vers Apogée</h2>"""
|
"""<h2>Export des résultats vers Apogée</h2>"""
|
||||||
"""<div class="semset_descr">""",
|
"""<div class="semset_descr">""",
|
||||||
semset.html_descr(),
|
semset.html_descr(),
|
||||||
@ -433,12 +438,8 @@ def apo_semset_maq_status(
|
|||||||
</div>
|
</div>
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
return render_template(
|
H.append(html_sco_header.sco_footer())
|
||||||
"sco_page_dept.j2",
|
return "\n".join(H)
|
||||||
title="Export Apogée",
|
|
||||||
javascripts=["js/apo_semset_maq_status.js"],
|
|
||||||
content="\n".join(H),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def table_apo_csv_list(semset):
|
def table_apo_csv_list(semset):
|
||||||
@ -593,21 +594,21 @@ def _view_etuds_page(
|
|||||||
if fmt != "html":
|
if fmt != "html":
|
||||||
return tab.make_page(fmt=fmt)
|
return tab.make_page(fmt=fmt)
|
||||||
|
|
||||||
return render_template(
|
return f"""
|
||||||
"sco_page_dept.j2",
|
{html_sco_header.sco_header(
|
||||||
title=title,
|
page_title=title,
|
||||||
content=f"""
|
)}
|
||||||
<h2>{title}</h2>
|
<h2>{title}</h2>
|
||||||
|
|
||||||
{tab.html()}
|
{tab.html()}
|
||||||
|
|
||||||
<div class="space-before-24"><a class="stdlink" href="{
|
<p><a href="{
|
||||||
url_for("notes.apo_semset_maq_status",
|
url_for("notes.apo_semset_maq_status",
|
||||||
scodoc_dept=g.scodoc_dept, semset_id=semset_id)
|
scodoc_dept=g.scodoc_dept, semset_id=semset_id)
|
||||||
}">Retour à la page d'export Apogée</a>
|
}">Retour à la page d'export Apogée</a>
|
||||||
</div>
|
</p>
|
||||||
""",
|
{html_sco_header.sco_footer()}
|
||||||
)
|
"""
|
||||||
|
|
||||||
|
|
||||||
def view_apo_csv_store(semset_id="", csvfile=None, data: bytes = "", autodetect=False):
|
def view_apo_csv_store(semset_id="", csvfile=None, data: bytes = "", autodetect=False):
|
||||||
@ -746,6 +747,9 @@ def view_apo_csv(etape_apo="", semset_id="", fmt="html"):
|
|||||||
) = sco_etape_apogee.apo_csv_semset_check(semset)
|
) = sco_etape_apogee.apo_csv_semset_check(semset)
|
||||||
|
|
||||||
H = [
|
H = [
|
||||||
|
html_sco_header.sco_header(
|
||||||
|
page_title=f"""Maquette Apogée enregistrée pour {etape_apo}""",
|
||||||
|
),
|
||||||
f"""<h2>Étudiants dans la maquette Apogée {etape_apo}</h2>
|
f"""<h2>Étudiants dans la maquette Apogée {etape_apo}</h2>
|
||||||
<p>Pour l'ensemble <a class="stdlink" href="{
|
<p>Pour l'ensemble <a class="stdlink" href="{
|
||||||
url_for("notes.apo_semset_maq_status",
|
url_for("notes.apo_semset_maq_status",
|
||||||
@ -764,11 +768,7 @@ def view_apo_csv(etape_apo="", semset_id="", fmt="html"):
|
|||||||
# Liste des étudiants (sans les résultats pour le moment): TODO
|
# Liste des étudiants (sans les résultats pour le moment): TODO
|
||||||
etuds = apo_data.etuds
|
etuds = apo_data.etuds
|
||||||
if not etuds:
|
if not etuds:
|
||||||
return render_template(
|
return "\n".join(H) + "<p>Aucun étudiant</p>" + html_sco_header.sco_footer()
|
||||||
"sco_page_dept.j2",
|
|
||||||
title=f"""Maquette Apogée {etape_apo}""",
|
|
||||||
content="\n".join(H) + "<p>Aucun étudiant</p>",
|
|
||||||
)
|
|
||||||
|
|
||||||
# Ajout infos sur ScoDoc vs Apogee
|
# Ajout infos sur ScoDoc vs Apogee
|
||||||
for e in etuds:
|
for e in etuds:
|
||||||
@ -830,13 +830,10 @@ def view_apo_csv(etape_apo="", semset_id="", fmt="html"):
|
|||||||
}">Retour</a>
|
}">Retour</a>
|
||||||
</div>
|
</div>
|
||||||
""",
|
""",
|
||||||
|
html_sco_header.sco_footer(),
|
||||||
]
|
]
|
||||||
|
|
||||||
return render_template(
|
return "\n".join(H)
|
||||||
"sco_page_dept.j2",
|
|
||||||
title=f"""Maquette Apogée enregistrée pour {etape_apo}""",
|
|
||||||
content="\n".join(H),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
# called from Web (GET)
|
# called from Web (GET)
|
||||||
|
@ -42,6 +42,7 @@ import app.scodoc.sco_utils as scu
|
|||||||
from app.scodoc.sco_utils import ModuleType
|
from app.scodoc.sco_utils import ModuleType
|
||||||
from app.scodoc.sco_exceptions import ScoValueError
|
from app.scodoc.sco_exceptions import ScoValueError
|
||||||
from app.scodoc.TrivialFormulator import TrivialFormulator
|
from app.scodoc.TrivialFormulator import TrivialFormulator
|
||||||
|
from app.scodoc import html_sco_header
|
||||||
from app.scodoc import sco_cache
|
from app.scodoc import sco_cache
|
||||||
from app.scodoc import sco_evaluations
|
from app.scodoc import sco_evaluations
|
||||||
from app.scodoc import sco_preferences
|
from app.scodoc import sco_preferences
|
||||||
@ -73,18 +74,16 @@ def evaluation_create_form(
|
|||||||
min_note_max = scu.NOTES_PRECISION # le plus petit bareme possible
|
min_note_max = scu.NOTES_PRECISION # le plus petit bareme possible
|
||||||
#
|
#
|
||||||
if not modimpl.can_edit_evaluation(current_user):
|
if not modimpl.can_edit_evaluation(current_user):
|
||||||
return render_template(
|
return f"""
|
||||||
"sco_page.j2",
|
{html_sco_header.sco_header()}
|
||||||
title="Opération non autorisée",
|
|
||||||
content=f"""
|
|
||||||
<h2>Opération non autorisée</h2>
|
<h2>Opération non autorisée</h2>
|
||||||
<p>Modification évaluation impossible pour {current_user.get_nomplogin()}</p>
|
<p>Modification évaluation impossible pour {current_user.get_nomplogin()}</p>
|
||||||
<p><a href="{url_for('notes.moduleimpl_status',
|
<p><a href="{url_for('notes.moduleimpl_status',
|
||||||
scodoc_dept=g.scodoc_dept, moduleimpl_id=moduleimpl_id)
|
scodoc_dept=g.scodoc_dept, moduleimpl_id=moduleimpl_id)
|
||||||
}" class="stdlink">Revenir</a>
|
}" class="stdlink">Revenir</a>
|
||||||
</p>
|
</p>
|
||||||
""",
|
{html_sco_header.sco_footer()}
|
||||||
)
|
"""
|
||||||
if not edit:
|
if not edit:
|
||||||
# création nouvel
|
# création nouvel
|
||||||
if moduleimpl_id is None:
|
if moduleimpl_id is None:
|
||||||
@ -362,21 +361,20 @@ def evaluation_create_form(
|
|||||||
"""
|
"""
|
||||||
]
|
]
|
||||||
if tf[0] == 0:
|
if tf[0] == 0:
|
||||||
return render_template(
|
head = html_sco_header.sco_header(page_title=page_title)
|
||||||
"sco_page.j2",
|
return (
|
||||||
title=page_title,
|
head
|
||||||
content=(
|
+ "\n".join(H)
|
||||||
"\n".join(H)
|
+ "\n"
|
||||||
+ "\n"
|
+ tf[1]
|
||||||
+ tf[1]
|
+ render_template(
|
||||||
+ render_template(
|
"scodoc/forms/evaluation_edit.j2",
|
||||||
"scodoc/forms/evaluation_edit.j2",
|
)
|
||||||
)
|
+ render_template(
|
||||||
+ render_template(
|
"scodoc/help/evaluations.j2", is_apc=is_apc, modimpl=modimpl
|
||||||
"scodoc/help/evaluations.j2", is_apc=is_apc, modimpl=modimpl
|
)
|
||||||
)
|
+ render_template("sco_timepicker.j2")
|
||||||
+ render_template("sco_timepicker.j2")
|
+ html_sco_header.sco_footer()
|
||||||
),
|
|
||||||
)
|
)
|
||||||
elif tf[0] == -1:
|
elif tf[0] == -1:
|
||||||
return flask.redirect(dest_url)
|
return flask.redirect(dest_url)
|
||||||
|
@ -17,6 +17,7 @@ from app.models import Evaluation, FormSemestre
|
|||||||
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.comp.moy_mod import ModuleImplResults
|
from app.comp.moy_mod import ModuleImplResults
|
||||||
|
from app.scodoc import html_sco_header
|
||||||
import app.scodoc.sco_utils as scu
|
import app.scodoc.sco_utils as scu
|
||||||
|
|
||||||
|
|
||||||
@ -62,7 +63,9 @@ def evaluations_recap(formsemestre_id: int) -> str:
|
|||||||
pas pris en compte dans cette table.</div>
|
pas pris en compte dans cette table.</div>
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
H.append(
|
||||||
|
html_sco_header.sco_footer(),
|
||||||
|
)
|
||||||
return render_template(
|
return render_template(
|
||||||
"sco_page.j2",
|
"sco_page.j2",
|
||||||
title="Évaluations du semestre",
|
title="Évaluations du semestre",
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
"""Export d'une table avec les résultats de tous les étudiants
|
"""Export d'une table avec les résultats de tous les étudiants
|
||||||
"""
|
"""
|
||||||
from flask import url_for, g, render_template, request
|
from flask import url_for, g, request
|
||||||
|
|
||||||
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
|
||||||
@ -42,12 +42,12 @@ from app.scodoc import codes_cursus
|
|||||||
from app.scodoc import sco_preferences
|
from app.scodoc import sco_preferences
|
||||||
from app.scodoc import sco_pv_dict
|
from app.scodoc import sco_pv_dict
|
||||||
from app.scodoc import sco_etud
|
from app.scodoc import sco_etud
|
||||||
|
import sco_version
|
||||||
from app.scodoc.gen_tables import GenTable
|
from app.scodoc.gen_tables import GenTable
|
||||||
from app.scodoc.codes_cursus import NO_SEMESTRE_ID
|
from app.scodoc.codes_cursus import NO_SEMESTRE_ID
|
||||||
import sco_version
|
|
||||||
|
|
||||||
|
|
||||||
def _build_results_table(start_date=None, end_date=None, types_parcours=()):
|
def _build_results_table(start_date=None, end_date=None, types_parcours=[]):
|
||||||
"""Construit une table avec les résultats de jury de TOUS les étudiants
|
"""Construit une table avec les résultats de jury de TOUS les étudiants
|
||||||
de TOUS les semestres ScoDoc de ce département entre les dates indiquées
|
de TOUS les semestres ScoDoc de ce département entre les dates indiquées
|
||||||
(c'est à dire commençant APRES ou à start_date et terminant avant ou à end_date)
|
(c'est à dire commençant APRES ou à start_date et terminant avant ou à end_date)
|
||||||
@ -285,6 +285,11 @@ def scodoc_table_results(
|
|||||||
info_sems.append("</ul>")
|
info_sems.append("</ul>")
|
||||||
|
|
||||||
H = [
|
H = [
|
||||||
|
html_sco_header.sco_header(
|
||||||
|
page_title="Export résultats",
|
||||||
|
javascripts=html_sco_header.BOOTSTRAP_JS + ["js/export_results.js"],
|
||||||
|
cssstyles=html_sco_header.BOOTSTRAP_CSS,
|
||||||
|
),
|
||||||
# XXX
|
# XXX
|
||||||
"""
|
"""
|
||||||
<h2>Table des résultats de tous les semestres</h2>
|
<h2>Table des résultats de tous les semestres</h2>
|
||||||
@ -305,14 +310,9 @@ def scodoc_table_results(
|
|||||||
""",
|
""",
|
||||||
"\n".join(info_sems),
|
"\n".join(info_sems),
|
||||||
"""</div>""",
|
"""</div>""",
|
||||||
|
html_sco_header.sco_footer(),
|
||||||
]
|
]
|
||||||
return render_template(
|
return "\n".join(H)
|
||||||
"sco_page_dept.j2",
|
|
||||||
title="Export résultats",
|
|
||||||
javascripts=html_sco_header.BOOTSTRAP_JS + ["js/export_results.js"],
|
|
||||||
cssstyles=html_sco_header.BOOTSTRAP_CSS,
|
|
||||||
content="\n".join(H),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
# Formulaire pour saisie dates et sélection parcours
|
# Formulaire pour saisie dates et sélection parcours
|
||||||
|
@ -31,11 +31,12 @@ import flask
|
|||||||
from flask import g, url_for, render_template, request
|
from flask import g, url_for, render_template, request
|
||||||
from flask_login import current_user
|
from flask_login import current_user
|
||||||
|
|
||||||
from app.models.config import ScoDocSiteConfig
|
from app.models.config import ScoDocSiteConfig, PersonalizedLink
|
||||||
from app.models import FormSemestre
|
from app.models import FormSemestre
|
||||||
import app.scodoc.sco_utils as scu
|
import app.scodoc.sco_utils as scu
|
||||||
import app.scodoc.notesdb as ndb
|
import app.scodoc.notesdb as ndb
|
||||||
from app.scodoc.TrivialFormulator import TrivialFormulator
|
from app.scodoc.TrivialFormulator import TrivialFormulator
|
||||||
|
from app.scodoc import html_sco_header
|
||||||
|
|
||||||
_custommenuEditor = ndb.EditableTable(
|
_custommenuEditor = ndb.EditableTable(
|
||||||
"notes_formsemestre_custommenu",
|
"notes_formsemestre_custommenu",
|
||||||
@ -106,7 +107,7 @@ def formsemestre_custommenu_edit(formsemestre_id):
|
|||||||
dest_url = url_for(
|
dest_url = url_for(
|
||||||
"notes.formsemestre_status",
|
"notes.formsemestre_status",
|
||||||
scodoc_dept=g.scodoc_dept,
|
scodoc_dept=g.scodoc_dept,
|
||||||
formsemestre_id=formsemestre.id,
|
formsemestre_id=formsemestre_id,
|
||||||
)
|
)
|
||||||
H = [
|
H = [
|
||||||
"""<div class="help">
|
"""<div class="help">
|
||||||
|
@ -1720,6 +1720,7 @@ def formsemestre_edit_options(formsemestre_id):
|
|||||||
"""dialog to change formsemestre options
|
"""dialog to change formsemestre options
|
||||||
(accessible par EditFormSemestre ou dir. etudes)
|
(accessible par EditFormSemestre ou dir. etudes)
|
||||||
"""
|
"""
|
||||||
|
log("formsemestre_edit_options")
|
||||||
ok, err = sco_permissions_check.check_access_diretud(formsemestre_id)
|
ok, err = sco_permissions_check.check_access_diretud(formsemestre_id)
|
||||||
if not ok:
|
if not ok:
|
||||||
return err
|
return err
|
||||||
|
@ -34,7 +34,7 @@ Ces semestres n'auront qu'un seul inscrit !
|
|||||||
import time
|
import time
|
||||||
|
|
||||||
import flask
|
import flask
|
||||||
from flask import flash, g, render_template, request, url_for
|
from flask import url_for, g, request
|
||||||
from flask_login import current_user
|
from flask_login import current_user
|
||||||
|
|
||||||
from app.comp import res_sem
|
from app.comp import res_sem
|
||||||
@ -50,6 +50,7 @@ from app.models import (
|
|||||||
import app.scodoc.sco_utils as scu
|
import app.scodoc.sco_utils as scu
|
||||||
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 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
|
||||||
@ -85,6 +86,7 @@ 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 = Identite.get_etud(etudid)
|
etud = Identite.get_etud(etudid)
|
||||||
H = [
|
H = [
|
||||||
|
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
|
||||||
établissement</h2>
|
établissement</h2>
|
||||||
<p class="help">
|
<p class="help">
|
||||||
@ -104,6 +106,7 @@ def formsemestre_ext_create_form(etudid, formsemestre_id):
|
|||||||
}" class="stdlink">Étudiant {etud.nomprenom}</a></h3>
|
}" class="stdlink">Étudiant {etud.nomprenom}</a></h3>
|
||||||
""",
|
""",
|
||||||
]
|
]
|
||||||
|
F = html_sco_header.sco_footer()
|
||||||
orig_sem = sco_formsemestre.get_formsemestre(formsemestre_id)
|
orig_sem = sco_formsemestre.get_formsemestre(formsemestre_id)
|
||||||
# Ne propose que des semestres de semestre_id strictement inférieur
|
# Ne propose que des semestres de semestre_id strictement inférieur
|
||||||
# au semestre courant
|
# au semestre courant
|
||||||
@ -130,7 +133,7 @@ def formsemestre_ext_create_form(etudid, formsemestre_id):
|
|||||||
(indices entre {min_semestre_id} et {max_semestre_id}, semestre courant.)
|
(indices entre {min_semestre_id} et {max_semestre_id}, semestre courant.)
|
||||||
</p>"""
|
</p>"""
|
||||||
)
|
)
|
||||||
return render_template("sco_page.j2", content="\n".join(H))
|
return "\n".join(H) + F
|
||||||
# Formulaire
|
# Formulaire
|
||||||
semestre_ids_list = sorted(semestre_ids)
|
semestre_ids_list = sorted(semestre_ids)
|
||||||
semestre_ids_labels = [f"S{x}" for x in semestre_ids_list]
|
semestre_ids_labels = [f"S{x}" for x in semestre_ids_list]
|
||||||
@ -202,7 +205,7 @@ def formsemestre_ext_create_form(etudid, formsemestre_id):
|
|||||||
la formation effectué dans un autre établissement.
|
la formation effectué dans un autre établissement.
|
||||||
</p>"""
|
</p>"""
|
||||||
)
|
)
|
||||||
return render_template("sco_page.j2", content="\n".join(H) + "\n" + tf[1])
|
return "\n".join(H) + "\n" + tf[1] + F
|
||||||
elif tf[0] == -1:
|
elif tf[0] == -1:
|
||||||
return flask.redirect(
|
return flask.redirect(
|
||||||
url_for(
|
url_for(
|
||||||
@ -267,35 +270,17 @@ def formsemestre_ext_edit_ue_validations(formsemestre_id, etudid):
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
if tf[0] == -1:
|
if tf[0] == -1:
|
||||||
flash("annulation")
|
return "<h4>annulation</h4>"
|
||||||
return flask.redirect(
|
|
||||||
url_for(
|
|
||||||
"notes.formsemestre_bulletinetud",
|
|
||||||
scodoc_dept=g.scodoc_dept,
|
|
||||||
formsemestre_id=formsemestre_id,
|
|
||||||
etudid=etudid,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
H = _make_page(etud, formsemestre, tf)
|
H = _make_page(etud, formsemestre, tf)
|
||||||
if tf[0] == 0: # premier affichage
|
if tf[0] == 0: # premier affichage
|
||||||
return render_template(
|
return "\n".join(H)
|
||||||
"sco_page.j2",
|
|
||||||
title="Validation des UE d'un semestre extérieur",
|
|
||||||
javascripts=["js/formsemestre_ext_edit_ue_validations.js"],
|
|
||||||
content="\n".join(H),
|
|
||||||
)
|
|
||||||
else: # soumission
|
else: # soumission
|
||||||
# simule erreur
|
# simule erreur
|
||||||
ok, message = _check_values(formsemestre, ues, tf[2])
|
ok, message = _check_values(formsemestre, ues, tf[2])
|
||||||
if not ok:
|
if not ok:
|
||||||
H = _make_page(etud, formsemestre, tf, message=message)
|
H = _make_page(etud, formsemestre, tf, message=message)
|
||||||
return render_template(
|
return "\n".join(H)
|
||||||
"sco_page.j2",
|
|
||||||
title="Validation des UE d'un semestre extérieur",
|
|
||||||
javascripts=["js/formsemestre_ext_edit_ue_validations.js"],
|
|
||||||
content="\n".join(H),
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
# Submit
|
# Submit
|
||||||
_record_ue_validations_and_coefs(formsemestre, etud, ues, tf[2])
|
_record_ue_validations_and_coefs(formsemestre, etud, ues, tf[2])
|
||||||
@ -314,6 +299,10 @@ def _make_page(etud: Identite, formsemestre: FormSemestre, tf, message="") -> li
|
|||||||
nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
|
nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
|
||||||
moy_gen = nt.get_etud_moy_gen(etud.id)
|
moy_gen = nt.get_etud_moy_gen(etud.id)
|
||||||
H = [
|
H = [
|
||||||
|
html_sco_header.sco_header(
|
||||||
|
page_title="Validation des UE d'un semestre extérieur",
|
||||||
|
javascripts=["js/formsemestre_ext_edit_ue_validations.js"],
|
||||||
|
),
|
||||||
tf_error_message(message),
|
tf_error_message(message),
|
||||||
f"""<p><b>{etud.nomprenom}</b> est inscrit{etud.e} à ce semestre extérieur.</p>
|
f"""<p><b>{etud.nomprenom}</b> est inscrit{etud.e} à ce semestre extérieur.</p>
|
||||||
<p>Voici ses UE enregistrées avec leur notes
|
<p>Voici ses UE enregistrées avec leur notes
|
||||||
@ -335,6 +324,7 @@ def _make_page(etud: Identite, formsemestre: FormSemestre, tf, message="") -> li
|
|||||||
)}">retour au bulletin de notes</a>
|
)}">retour au bulletin de notes</a>
|
||||||
</div>
|
</div>
|
||||||
""",
|
""",
|
||||||
|
html_sco_header.sco_footer(),
|
||||||
]
|
]
|
||||||
return H
|
return H
|
||||||
|
|
||||||
@ -532,8 +522,7 @@ def _record_ue_validations_and_coefs(
|
|||||||
coef = None
|
coef = None
|
||||||
now_dmy = time.strftime(scu.DATE_FMT)
|
now_dmy = time.strftime(scu.DATE_FMT)
|
||||||
log(
|
log(
|
||||||
f"""_record_ue_validations_and_coefs: {
|
f"_record_ue_validations_and_coefs: {formsemestre.id} etudid={etud.id} ue_id={ue.id} moy_ue={note} ue_coef={coef}"
|
||||||
formsemestre.id} etudid={etud.id} ue_id={ue.id} moy_ue={note} ue_coef={coef}"""
|
|
||||||
)
|
)
|
||||||
assert code is 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(
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
"""Opérations d'inscriptions aux semestres et modules
|
"""Opérations d'inscriptions aux semestres et modules
|
||||||
"""
|
"""
|
||||||
import collections
|
import collections
|
||||||
|
import time
|
||||||
|
|
||||||
import flask
|
import flask
|
||||||
from flask import flash, url_for, g, render_template, request
|
from flask import flash, url_for, g, render_template, request
|
||||||
@ -51,6 +52,7 @@ from app.scodoc import sco_moduleimpl
|
|||||||
from app.scodoc import sco_groups
|
from app.scodoc import sco_groups
|
||||||
from app.scodoc import sco_etud
|
from app.scodoc import sco_etud
|
||||||
from app.scodoc import sco_cache
|
from app.scodoc import sco_cache
|
||||||
|
from app.scodoc import html_sco_header
|
||||||
|
|
||||||
|
|
||||||
# --- Gestion des inscriptions aux semestres
|
# --- Gestion des inscriptions aux semestres
|
||||||
@ -248,6 +250,7 @@ def do_formsemestre_inscription_with_modules(
|
|||||||
]
|
]
|
||||||
formsemestre = FormSemestre.get_formsemestre(formsemestre_id, dept_id=dept_id)
|
formsemestre = FormSemestre.get_formsemestre(formsemestre_id, dept_id=dept_id)
|
||||||
# Inscription au semestre
|
# Inscription au semestre
|
||||||
|
args = {"formsemestre_id": formsemestre_id, "etudid": etudid}
|
||||||
formsemestre.inscrit_etudiant(etud, etat=etat, etape=etape, method=method)
|
formsemestre.inscrit_etudiant(etud, etat=etat, etape=etape, method=method)
|
||||||
log(
|
log(
|
||||||
f"""do_formsemestre_inscription_with_modules: etudid={
|
f"""do_formsemestre_inscription_with_modules: etudid={
|
||||||
@ -304,6 +307,7 @@ def formsemestre_inscription_with_modules_form(etudid, only_ext=False):
|
|||||||
id=etudid, dept_id=g.scodoc_dept_id
|
id=etudid, dept_id=g.scodoc_dept_id
|
||||||
).first_or_404()
|
).first_or_404()
|
||||||
H = [
|
H = [
|
||||||
|
html_sco_header.sco_header(),
|
||||||
f"<h2>Inscription de {etud.nomprenom}",
|
f"<h2>Inscription de {etud.nomprenom}",
|
||||||
]
|
]
|
||||||
if only_ext:
|
if only_ext:
|
||||||
@ -315,6 +319,8 @@ def formsemestre_inscription_with_modules_form(etudid, only_ext=False):
|
|||||||
</p>
|
</p>
|
||||||
<h3>Choisir un semestre:</h3>"""
|
<h3>Choisir un semestre:</h3>"""
|
||||||
)
|
)
|
||||||
|
footer = html_sco_header.sco_footer()
|
||||||
|
# sems = sco_formsemestre.do_formsemestre_list(args={"etat": "1"})
|
||||||
formsemestres = (
|
formsemestres = (
|
||||||
FormSemestre.query.filter_by(etat=True, dept_id=g.scodoc_dept_id)
|
FormSemestre.query.filter_by(etat=True, dept_id=g.scodoc_dept_id)
|
||||||
.join(Formation)
|
.join(Formation)
|
||||||
@ -353,9 +359,7 @@ def formsemestre_inscription_with_modules_form(etudid, only_ext=False):
|
|||||||
url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||||
}">retour à la fiche de {etud.nomprenom}</a>"""
|
}">retour à la fiche de {etud.nomprenom}</a>"""
|
||||||
)
|
)
|
||||||
return render_template(
|
return "\n".join(H) + footer
|
||||||
"sco_page_dept.j2", title="Inscription", content="\n".join(H)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def formsemestre_inscription_with_modules(
|
def formsemestre_inscription_with_modules(
|
||||||
@ -497,7 +501,9 @@ def formsemestre_inscription_option(etudid, formsemestre_id):
|
|||||||
formsemestre = FormSemestre.get_formsemestre(formsemestre_id)
|
formsemestre = FormSemestre.get_formsemestre(formsemestre_id)
|
||||||
nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
|
nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
|
||||||
|
|
||||||
|
footer = html_sco_header.sco_footer()
|
||||||
H = [
|
H = [
|
||||||
|
html_sco_header.sco_header(),
|
||||||
f"""<h2>Inscription de {etud.nomprenom} aux modules de {formsemestre.titre_mois()}</h2>""",
|
f"""<h2>Inscription de {etud.nomprenom} aux modules de {formsemestre.titre_mois()}</h2>""",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -614,7 +620,7 @@ function chkbx_select(field_id, state) {
|
|||||||
</p>
|
</p>
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
return render_template("sco_page.j2", content="\n".join(H) + "\n" + tf[1])
|
return "\n".join(H) + "\n" + tf[1] + footer
|
||||||
if tf[0] == -1:
|
if tf[0] == -1:
|
||||||
return flask.redirect(
|
return flask.redirect(
|
||||||
url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||||
@ -657,7 +663,7 @@ function chkbx_select(field_id, state) {
|
|||||||
}">retour à la fiche étudiant</a></p>
|
}">retour à la fiche étudiant</a></p>
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
return render_template("sco_page.j2", content="\n".join(H))
|
return "\n".join(H) + footer
|
||||||
|
|
||||||
H.append("<h3>Confirmer les modifications:</h3>")
|
H.append("<h3>Confirmer les modifications:</h3>")
|
||||||
if a_desinscrire:
|
if a_desinscrire:
|
||||||
@ -705,7 +711,7 @@ function chkbx_select(field_id, state) {
|
|||||||
</form>
|
</form>
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
return render_template("sco_page.j2", content="\n".join(H))
|
return "\n".join(H) + footer
|
||||||
|
|
||||||
|
|
||||||
def do_moduleimpl_incription_options(
|
def do_moduleimpl_incription_options(
|
||||||
@ -759,15 +765,17 @@ def do_moduleimpl_incription_options(
|
|||||||
)
|
)
|
||||||
|
|
||||||
H = [
|
H = [
|
||||||
|
html_sco_header.sco_header(),
|
||||||
f"""<h3>Modifications effectuées</h3>
|
f"""<h3>Modifications effectuées</h3>
|
||||||
<p><a class="stdlink" href="{
|
<p><a class="stdlink" href="{
|
||||||
url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||||
}">
|
}">
|
||||||
Retour à la fiche étudiant</a>
|
Retour à la fiche étudiant</a>
|
||||||
</p>
|
</p>
|
||||||
"""
|
""",
|
||||||
|
html_sco_header.sco_footer(),
|
||||||
]
|
]
|
||||||
return render_template("sco_page.j2", content="\n".join(H))
|
return "\n".join(H)
|
||||||
|
|
||||||
|
|
||||||
def est_inscrit_ailleurs(etudid, formsemestre_id):
|
def est_inscrit_ailleurs(etudid, formsemestre_id):
|
||||||
|
@ -51,9 +51,11 @@ from app.scodoc.sco_exceptions import ScoValueError
|
|||||||
from app.scodoc.codes_cursus import *
|
from app.scodoc.codes_cursus import *
|
||||||
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 sco_assiduites
|
from app.scodoc import sco_assiduites
|
||||||
from app.scodoc import codes_cursus
|
from app.scodoc import codes_cursus
|
||||||
from app.scodoc import sco_cache
|
from app.scodoc import sco_cache
|
||||||
|
from app.scodoc import sco_etud
|
||||||
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_cursus
|
from app.scodoc import sco_cursus
|
||||||
@ -73,7 +75,7 @@ def formsemestre_validation_etud_form(
|
|||||||
sortcol=None,
|
sortcol=None,
|
||||||
read_only=True,
|
read_only=True,
|
||||||
):
|
):
|
||||||
"""Formulaire de validation des décisions de jury (formations classiques)"""
|
"""Formulaire de validation des décisions de jury"""
|
||||||
formsemestre: FormSemestre = FormSemestre.query.filter_by(
|
formsemestre: FormSemestre = FormSemestre.query.filter_by(
|
||||||
id=formsemestre_id, dept_id=g.scodoc_dept_id
|
id=formsemestre_id, dept_id=g.scodoc_dept_id
|
||||||
).first_or_404()
|
).first_or_404()
|
||||||
@ -110,6 +112,7 @@ def formsemestre_validation_etud_form(
|
|||||||
if read_only:
|
if read_only:
|
||||||
check = True
|
check = True
|
||||||
|
|
||||||
|
etud_d = sco_etud.get_etud_info(etudid=etudid, filled=True)[0]
|
||||||
Se = sco_cursus.get_situation_etud_cursus(etud, formsemestre_id)
|
Se = sco_cursus.get_situation_etud_cursus(etud, formsemestre_id)
|
||||||
if not Se.sem["etat"]:
|
if not Se.sem["etat"]:
|
||||||
raise ScoValueError("validation: semestre verrouille")
|
raise ScoValueError("validation: semestre verrouille")
|
||||||
@ -122,7 +125,13 @@ def formsemestre_validation_etud_form(
|
|||||||
selected_etudid=etudid, # va a la bonne ligne
|
selected_etudid=etudid, # va a la bonne ligne
|
||||||
)
|
)
|
||||||
|
|
||||||
H = []
|
H = [
|
||||||
|
html_sco_header.sco_header(
|
||||||
|
page_title=f"Parcours {etud.nomprenom}",
|
||||||
|
javascripts=["js/recap_parcours.js"],
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
# Navigation suivant/precedent
|
# Navigation suivant/precedent
|
||||||
if etud_index_prev is not None:
|
if etud_index_prev is not None:
|
||||||
etud_prev = Identite.get_etud(T[etud_index_prev][-1])
|
etud_prev = Identite.get_etud(T[etud_index_prev][-1])
|
||||||
@ -158,6 +167,8 @@ def formsemestre_validation_etud_form(
|
|||||||
)
|
)
|
||||||
footer.append("</span></div>")
|
footer.append("</span></div>")
|
||||||
|
|
||||||
|
footer.append(html_sco_header.sco_footer())
|
||||||
|
|
||||||
H.append('<table style="width: 100%"><tr><td>')
|
H.append('<table style="width: 100%"><tr><td>')
|
||||||
if not check:
|
if not check:
|
||||||
H.append(
|
H.append(
|
||||||
@ -195,12 +206,7 @@ def formsemestre_validation_etud_form(
|
|||||||
</div>
|
</div>
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
return render_template(
|
return "\n".join(H + footer)
|
||||||
"sco_page.j2",
|
|
||||||
javascripts=["js/recap_parcours.js"],
|
|
||||||
title=f"Parcours {etud.nomprenom}",
|
|
||||||
content="\n".join(H + footer),
|
|
||||||
)
|
|
||||||
|
|
||||||
H.append(
|
H.append(
|
||||||
formsemestre_recap_parcours_table(
|
formsemestre_recap_parcours_table(
|
||||||
@ -212,12 +218,7 @@ def formsemestre_validation_etud_form(
|
|||||||
dest_url = url_tableau
|
dest_url = url_tableau
|
||||||
H.append(f'<ul><li><a href="{dest_url}">Continuer</a></li></ul>')
|
H.append(f'<ul><li><a href="{dest_url}">Continuer</a></li></ul>')
|
||||||
|
|
||||||
return render_template(
|
return "\n".join(H + footer)
|
||||||
"sco_page.j2",
|
|
||||||
javascripts=["js/recap_parcours.js"],
|
|
||||||
title=f"Parcours {etud.nomprenom}",
|
|
||||||
content="\n".join(H + footer),
|
|
||||||
)
|
|
||||||
|
|
||||||
decision_jury = Se.nt.get_etud_decision_sem(etudid)
|
decision_jury = Se.nt.get_etud_decision_sem(etudid)
|
||||||
|
|
||||||
@ -235,12 +236,7 @@ def formsemestre_validation_etud_form(
|
|||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
return render_template(
|
return "\n".join(H + footer)
|
||||||
"sco_page.j2",
|
|
||||||
javascripts=["js/recap_parcours.js"],
|
|
||||||
title=f"Parcours {etud.nomprenom}",
|
|
||||||
content="\n".join(H + footer),
|
|
||||||
)
|
|
||||||
|
|
||||||
evaluations_a_debloquer = Evaluation.get_evaluations_blocked_for_etud(
|
evaluations_a_debloquer = Evaluation.get_evaluations_blocked_for_etud(
|
||||||
formsemestre, etud
|
formsemestre, etud
|
||||||
@ -260,12 +256,7 @@ def formsemestre_validation_etud_form(
|
|||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
return render_template(
|
return "\n".join(H + footer)
|
||||||
"sco_page.j2",
|
|
||||||
javascripts=["js/recap_parcours.js"],
|
|
||||||
title=f"Parcours {etud.nomprenom}",
|
|
||||||
content="\n".join(H + footer),
|
|
||||||
)
|
|
||||||
|
|
||||||
# Infos si pas de semestre précédent
|
# Infos si pas de semestre précédent
|
||||||
if not Se.prev_formsemestre:
|
if not Se.prev_formsemestre:
|
||||||
@ -296,12 +287,8 @@ def formsemestre_validation_etud_form(
|
|||||||
}" class="stdlink">Supprimer décision existante</a>
|
}" class="stdlink">Supprimer décision existante</a>
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
return render_template(
|
H.append(html_sco_header.sco_footer())
|
||||||
"sco_page.j2",
|
return "\n".join(H)
|
||||||
javascripts=["js/recap_parcours.js"],
|
|
||||||
title=f"Parcours {etud.nomprenom}",
|
|
||||||
content="\n".join(H),
|
|
||||||
)
|
|
||||||
|
|
||||||
# Infos sur decisions déjà saisies
|
# Infos sur decisions déjà saisies
|
||||||
if decision_jury:
|
if decision_jury:
|
||||||
@ -342,12 +329,8 @@ def formsemestre_validation_etud_form(
|
|||||||
H.append(f"""<input type="hidden" name="sortcol" value="{sortcol}"/>""")
|
H.append(f"""<input type="hidden" name="sortcol" value="{sortcol}"/>""")
|
||||||
H.append("</form></div>")
|
H.append("</form></div>")
|
||||||
|
|
||||||
return render_template(
|
H.append(html_sco_header.sco_footer())
|
||||||
"sco_page.j2",
|
return "\n".join(H)
|
||||||
javascripts=["js/recap_parcours.js"],
|
|
||||||
title=f"Parcours {etud.nomprenom}",
|
|
||||||
content="\n".join(H),
|
|
||||||
)
|
|
||||||
|
|
||||||
# Explication sur barres actuelles
|
# Explication sur barres actuelles
|
||||||
H.append('<p class="sfv_explication">L\'étudiant ')
|
H.append('<p class="sfv_explication">L\'étudiant ')
|
||||||
@ -410,12 +393,7 @@ def formsemestre_validation_etud_form(
|
|||||||
else:
|
else:
|
||||||
H.append("sans semestres décalés</p>")
|
H.append("sans semestres décalés</p>")
|
||||||
|
|
||||||
return render_template(
|
return "".join(H + footer)
|
||||||
"sco_page.j2",
|
|
||||||
javascripts=["js/recap_parcours.js"],
|
|
||||||
title=f"Parcours {etud.nomprenom}",
|
|
||||||
content="\n".join(H + footer),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def formsemestre_validation_etud(
|
def formsemestre_validation_etud(
|
||||||
@ -1084,7 +1062,7 @@ def do_formsemestre_validation_auto(formsemestre_id):
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
H = [
|
H = [
|
||||||
f"""
|
f"""{html_sco_header.sco_header(page_title="Saisie automatique")}
|
||||||
<h2>Saisie automatique des décisions du semestre {formsemestre.titre_annee()}</h2>
|
<h2>Saisie automatique des décisions du semestre {formsemestre.titre_annee()}</h2>
|
||||||
<p>Opération effectuée.</p>
|
<p>Opération effectuée.</p>
|
||||||
<p>{nb_valid} étudiants validés sur {len(etudids)}</p>
|
<p>{nb_valid} étudiants validés sur {len(etudids)}</p>
|
||||||
@ -1110,10 +1088,8 @@ def do_formsemestre_validation_auto(formsemestre_id):
|
|||||||
scodoc_dept=g.scodoc_dept, formsemestre_id=formsemestre_id, mode_jury=1)
|
scodoc_dept=g.scodoc_dept, formsemestre_id=formsemestre_id, mode_jury=1)
|
||||||
}">continuer</a>"""
|
}">continuer</a>"""
|
||||||
)
|
)
|
||||||
|
H.append(html_sco_header.sco_footer())
|
||||||
return render_template(
|
return "\n".join(H)
|
||||||
"sco_page.j2", title="Saisie automatique", content="\n".join(H)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def formsemestre_validation_suppress_etud(formsemestre_id, etudid):
|
def formsemestre_validation_suppress_etud(formsemestre_id, etudid):
|
||||||
@ -1242,14 +1218,14 @@ def formsemestre_validate_previous_ue(formsemestre: FormSemestre, etud: Identite
|
|||||||
submitlabel="Enregistrer validation d'UE",
|
submitlabel="Enregistrer validation d'UE",
|
||||||
)
|
)
|
||||||
if tf[0] == 0:
|
if tf[0] == 0:
|
||||||
return render_template(
|
return f"""
|
||||||
"sco_page_dept.j2",
|
{html_sco_header.sco_header(
|
||||||
title="Validation UE antérieure",
|
page_title="Validation UE antérieure",
|
||||||
javascripts=["js/validate_previous_ue.js"],
|
javascripts=["js/validate_previous_ue.js"],
|
||||||
cssstyles=["css/jury_delete_manual.css"],
|
cssstyles=["css/jury_delete_manual.css"],
|
||||||
etudid=etud.id,
|
etudid=etud.id,
|
||||||
formsemestre_id=formsemestre.id,
|
formsemestre_id=formsemestre.id,
|
||||||
content=f"""
|
)}
|
||||||
<h2 class="formsemestre">Gestion des validations d'UEs antérieures
|
<h2 class="formsemestre">Gestion des validations d'UEs antérieures
|
||||||
de {etud.html_link_fiche()}
|
de {etud.html_link_fiche()}
|
||||||
</h2>
|
</h2>
|
||||||
@ -1289,8 +1265,8 @@ def formsemestre_validate_previous_ue(formsemestre: FormSemestre, etud: Identite
|
|||||||
<!-- filled by ue_sharing_code -->
|
<!-- filled by ue_sharing_code -->
|
||||||
</div>
|
</div>
|
||||||
{check_formation_ues(formation)[0]}
|
{check_formation_ues(formation)[0]}
|
||||||
""",
|
{html_sco_header.sco_footer()}
|
||||||
)
|
"""
|
||||||
|
|
||||||
dest_url = url_for(
|
dest_url = url_for(
|
||||||
"notes.formsemestre_validate_previous_ue",
|
"notes.formsemestre_validate_previous_ue",
|
||||||
|
@ -34,7 +34,8 @@ from xml.etree import ElementTree
|
|||||||
from xml.etree.ElementTree import Element
|
from xml.etree.ElementTree import Element
|
||||||
|
|
||||||
import flask
|
import flask
|
||||||
from flask import g, make_response, render_template, request, url_for
|
from flask import g, request
|
||||||
|
from flask import url_for, make_response
|
||||||
from sqlalchemy.sql import text
|
from sqlalchemy.sql import text
|
||||||
|
|
||||||
from app import cache, db, log
|
from app import cache, db, log
|
||||||
@ -44,6 +45,7 @@ from app.models import FormSemestre, Identite, Scolog
|
|||||||
from app.models import SHORT_STR_LEN
|
from app.models import SHORT_STR_LEN
|
||||||
from app.models.groups import GroupDescr, Partition
|
from app.models.groups import GroupDescr, Partition
|
||||||
import app.scodoc.notesdb as ndb
|
import app.scodoc.notesdb as ndb
|
||||||
|
from app.scodoc import html_sco_header
|
||||||
from app.scodoc import sco_cache
|
from app.scodoc import sco_cache
|
||||||
from app.scodoc import codes_cursus
|
from app.scodoc import codes_cursus
|
||||||
from app.scodoc import sco_cursus
|
from app.scodoc import sco_cursus
|
||||||
@ -54,6 +56,7 @@ from app.scodoc import sco_xml
|
|||||||
from app.scodoc.sco_exceptions import ScoException, AccessDenied, ScoValueError
|
from app.scodoc.sco_exceptions import ScoException, AccessDenied, ScoValueError
|
||||||
from app.scodoc.TrivialFormulator import TrivialFormulator
|
from app.scodoc.TrivialFormulator import TrivialFormulator
|
||||||
|
|
||||||
|
|
||||||
partitionEditor = ndb.EditableTable(
|
partitionEditor = ndb.EditableTable(
|
||||||
"partition",
|
"partition",
|
||||||
"partition_id",
|
"partition_id",
|
||||||
@ -927,12 +930,16 @@ def edit_partition_form(formsemestre_id=None):
|
|||||||
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 !")
|
||||||
|
|
||||||
partitions = get_partitions_list(formsemestre_id)
|
partitions = get_partitions_list(formsemestre_id)
|
||||||
arrow_up, arrow_down, _ = get_arrow_icons_tags()
|
arrow_up, arrow_down, arrow_none = get_arrow_icons_tags()
|
||||||
suppricon = scu.icontag(
|
suppricon = scu.icontag(
|
||||||
"delete_small_img", border="0", alt="supprimer", title="Supprimer"
|
"delete_small_img", border="0", alt="supprimer", title="Supprimer"
|
||||||
)
|
)
|
||||||
#
|
#
|
||||||
H = [
|
H = [
|
||||||
|
html_sco_header.sco_header(
|
||||||
|
page_title="Partitions...",
|
||||||
|
javascripts=["js/edit_partition_form.js"],
|
||||||
|
),
|
||||||
# limite à SHORT_STR_LEN
|
# limite à SHORT_STR_LEN
|
||||||
r"""<script type="text/javascript">
|
r"""<script type="text/javascript">
|
||||||
function checkname() {
|
function checkname() {
|
||||||
@ -1050,8 +1057,7 @@ def edit_partition_form(formsemestre_id=None):
|
|||||||
H.append(
|
H.append(
|
||||||
f"""
|
f"""
|
||||||
<div style="margin-top: 10px"><a class="stdlink" href="{
|
<div style="margin-top: 10px"><a class="stdlink" href="{
|
||||||
url_for("scolar.create_partition_parcours",
|
url_for("scolar.create_partition_parcours", scodoc_dept=g.scodoc_dept, formsemestre_id=formsemestre_id)
|
||||||
scodoc_dept=g.scodoc_dept, formsemestre_id=formsemestre_id)
|
|
||||||
}">Créer une partition avec un groupe par parcours (BUT)</a>
|
}">Créer une partition avec un groupe par parcours (BUT)</a>
|
||||||
</div>
|
</div>
|
||||||
"""
|
"""
|
||||||
@ -1076,19 +1082,14 @@ def edit_partition_form(formsemestre_id=None):
|
|||||||
(ainsi, on peut afficher le classement en groupes de TD mais pas en
|
(ainsi, on peut afficher le classement en groupes de TD mais pas en
|
||||||
groupe de TP, si ce sont deux partitions).
|
groupe de TP, si ce sont deux partitions).
|
||||||
</li>
|
</li>
|
||||||
<li>Décocher "Afficher ces groupes sur les tableaux et bulletins"
|
<li>Décocher "Afficher ces groupes sur les tableaux et bulletins" pour ne pas que cette partition
|
||||||
pour ne pas que cette partition apparaisse dans les noms de groupes
|
apparaisse dans les noms de groupes
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
return render_template(
|
return "\n".join(H) + html_sco_header.sco_footer()
|
||||||
"sco_page.j2",
|
|
||||||
title="Partitions...",
|
|
||||||
javascripts=["js/edit_partition_form.js"],
|
|
||||||
content="\n".join(H),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def partition_set_attr(partition_id, attr, value):
|
def partition_set_attr(partition_id, attr, value):
|
||||||
@ -1247,10 +1248,12 @@ def partition_rename(partition_id):
|
|||||||
cancelbutton="Annuler",
|
cancelbutton="Annuler",
|
||||||
)
|
)
|
||||||
if tf[0] == 0:
|
if tf[0] == 0:
|
||||||
return render_template(
|
return (
|
||||||
"sco_page.j2",
|
html_sco_header.sco_header()
|
||||||
title="Renommer une partition",
|
+ "\n".join(H)
|
||||||
content=("\n".join(H) + "\n" + tf[1]),
|
+ "\n"
|
||||||
|
+ tf[1]
|
||||||
|
+ html_sco_header.sco_footer()
|
||||||
)
|
)
|
||||||
elif tf[0] == -1:
|
elif tf[0] == -1:
|
||||||
return flask.redirect(
|
return flask.redirect(
|
||||||
@ -1305,8 +1308,6 @@ def groups_auto_repartition(partition: Partition):
|
|||||||
"""Réparti les etudiants dans des groupes dans une partition, en respectant le niveau
|
"""Réparti les etudiants dans des groupes dans une partition, en respectant le niveau
|
||||||
et la mixité.
|
et la mixité.
|
||||||
"""
|
"""
|
||||||
from app.views import ScoData
|
|
||||||
|
|
||||||
if not partition.groups_editable:
|
if not partition.groups_editable:
|
||||||
raise AccessDenied("Partition non éditable")
|
raise AccessDenied("Partition non éditable")
|
||||||
formsemestre = partition.formsemestre
|
formsemestre = partition.formsemestre
|
||||||
@ -1333,6 +1334,9 @@ def groups_auto_repartition(partition: Partition):
|
|||||||
]
|
]
|
||||||
|
|
||||||
H = [
|
H = [
|
||||||
|
html_sco_header.sco_header(
|
||||||
|
page_title="Répartition des groupes", formsemestre_id=formsemestre.id
|
||||||
|
),
|
||||||
f"""<h2>Répartition des groupes de {partition.partition_name}</h2>
|
f"""<h2>Répartition des groupes de {partition.partition_name}</h2>
|
||||||
<p>Semestre {formsemestre.titre_annee()}</p>
|
<p>Semestre {formsemestre.titre_annee()}</p>
|
||||||
<p class="help">Les groupes existants seront <b>effacés</b> et remplacés par
|
<p class="help">Les groupes existants seront <b>effacés</b> et remplacés par
|
||||||
@ -1353,12 +1357,7 @@ def groups_auto_repartition(partition: Partition):
|
|||||||
name="tf",
|
name="tf",
|
||||||
)
|
)
|
||||||
if tf[0] == 0:
|
if tf[0] == 0:
|
||||||
return render_template(
|
return "\n".join(H) + "\n" + tf[1] + html_sco_header.sco_footer()
|
||||||
"sco_page.j2",
|
|
||||||
title="Répartition des groupes",
|
|
||||||
content="\n".join(H) + "\n" + tf[1],
|
|
||||||
sco=ScoData(formsemestre=formsemestre),
|
|
||||||
)
|
|
||||||
elif tf[0] == -1:
|
elif tf[0] == -1:
|
||||||
return flask.redirect(dest_url)
|
return flask.redirect(dest_url)
|
||||||
else:
|
else:
|
||||||
|
@ -32,13 +32,14 @@ from flask import flash, g, render_template, request, url_for
|
|||||||
|
|
||||||
from app.models import FormSemestre, GroupDescr, Partition
|
from app.models import FormSemestre, GroupDescr, Partition
|
||||||
from app.models import GROUPNAME_STR_LEN
|
from app.models import GROUPNAME_STR_LEN
|
||||||
|
from app.scodoc import html_sco_header
|
||||||
from app.scodoc.sco_exceptions import AccessDenied
|
from app.scodoc.sco_exceptions import AccessDenied
|
||||||
import app.scodoc.sco_utils as scu
|
import app.scodoc.sco_utils as scu
|
||||||
from app.scodoc.TrivialFormulator import TrivialFormulator
|
from app.scodoc.TrivialFormulator import TrivialFormulator
|
||||||
|
|
||||||
|
|
||||||
def affect_groups(partition_id):
|
def affect_groups(partition_id):
|
||||||
"""(ancien) formulaire affectation des etudiants aux groupes de la partition.
|
"""Formulaire affectation des etudiants aux groupes de la partition.
|
||||||
Permet aussi la creation et la suppression de groupes.
|
Permet aussi la creation et la suppression de groupes.
|
||||||
"""
|
"""
|
||||||
# réécrit pour 9.0.47 avec un template
|
# réécrit pour 9.0.47 avec un template
|
||||||
@ -49,9 +50,12 @@ def affect_groups(partition_id):
|
|||||||
formsemestre.setup_parcours_groups()
|
formsemestre.setup_parcours_groups()
|
||||||
return render_template(
|
return render_template(
|
||||||
"scolar/affect_groups.j2",
|
"scolar/affect_groups.j2",
|
||||||
title="Affectation aux groupes",
|
sco_header=html_sco_header.sco_header(
|
||||||
javascripts=["js/groupmgr.js"],
|
page_title="Affectation aux groupes",
|
||||||
cssstyles=["css/groups.css"],
|
javascripts=["js/groupmgr.js"],
|
||||||
|
cssstyles=["css/groups.css"],
|
||||||
|
),
|
||||||
|
sco_footer=html_sco_header.sco_footer(),
|
||||||
partition=partition,
|
partition=partition,
|
||||||
# Liste des partitions sans celle par defaut:
|
# Liste des partitions sans celle par defaut:
|
||||||
partitions_list=partition.formsemestre.partitions.filter(
|
partitions_list=partition.formsemestre.partitions.filter(
|
||||||
@ -82,11 +86,9 @@ def group_rename(group_id):
|
|||||||
"size": 12,
|
"size": 12,
|
||||||
"allow_null": False,
|
"allow_null": False,
|
||||||
"validator": lambda val, _: len(val) < GROUPNAME_STR_LEN,
|
"validator": lambda val, _: len(val) < GROUPNAME_STR_LEN,
|
||||||
"explanation": (
|
"explanation": "doit être unique dans cette partition"
|
||||||
"doit être unique dans cette partition"
|
if group.partition.groups_editable
|
||||||
if group.partition.groups_editable
|
else "groupes non modifiables dans cette partition",
|
||||||
else "groupes non modifiables dans cette partition"
|
|
||||||
),
|
|
||||||
"enabled": group.partition.groups_editable,
|
"enabled": group.partition.groups_editable,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@ -115,10 +117,12 @@ def group_rename(group_id):
|
|||||||
edit_partition=1,
|
edit_partition=1,
|
||||||
)
|
)
|
||||||
if tf[0] == 0:
|
if tf[0] == 0:
|
||||||
return render_template(
|
return (
|
||||||
"sco_page.j2",
|
html_sco_header.sco_header()
|
||||||
title="Renommer un groupe",
|
+ "\n".join(H)
|
||||||
content=("\n".join(H) + "\n" + tf[1]),
|
+ "\n"
|
||||||
|
+ tf[1]
|
||||||
|
+ html_sco_header.sco_footer()
|
||||||
)
|
)
|
||||||
elif tf[0] == -1:
|
elif tf[0] == -1:
|
||||||
return flask.redirect(dest_url)
|
return flask.redirect(dest_url)
|
||||||
|
@ -33,7 +33,7 @@ import os
|
|||||||
import re
|
import re
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from flask import g, render_template, url_for
|
from flask import g, url_for
|
||||||
|
|
||||||
from app import db, log
|
from app import db, log
|
||||||
from app.models import Identite, GroupDescr, ScolarNews
|
from app.models import Identite, GroupDescr, ScolarNews
|
||||||
@ -46,6 +46,7 @@ from app.scodoc.sco_exceptions import (
|
|||||||
ScoException,
|
ScoException,
|
||||||
ScoValueError,
|
ScoValueError,
|
||||||
)
|
)
|
||||||
|
from app.scodoc import html_sco_header
|
||||||
from app.scodoc import sco_cache
|
from app.scodoc import sco_cache
|
||||||
from app.scodoc import sco_etud
|
from app.scodoc import sco_etud
|
||||||
from app.scodoc import sco_groups
|
from app.scodoc import sco_groups
|
||||||
@ -230,7 +231,7 @@ def students_import_excel(
|
|||||||
check_homonyms=True,
|
check_homonyms=True,
|
||||||
require_ine=False,
|
require_ine=False,
|
||||||
return_html=True,
|
return_html=True,
|
||||||
) -> str:
|
):
|
||||||
"import students from Excel file"
|
"import students from Excel file"
|
||||||
diag = scolars_import_excel_file(
|
diag = scolars_import_excel_file(
|
||||||
csvfile,
|
csvfile,
|
||||||
@ -249,20 +250,18 @@ def students_import_excel(
|
|||||||
if formsemestre_id
|
if formsemestre_id
|
||||||
else url_for("notes.index_html", scodoc_dept=g.scodoc_dept)
|
else url_for("notes.index_html", scodoc_dept=g.scodoc_dept)
|
||||||
)
|
)
|
||||||
H = ["<ul>"]
|
H = [html_sco_header.sco_header(page_title="Import etudiants")]
|
||||||
|
H.append("<ul>")
|
||||||
for d in diag:
|
for d in diag:
|
||||||
H.append(f"<li>{d}</li>")
|
H.append(f"<li>{d}</li>")
|
||||||
H.append(
|
H.append(
|
||||||
f"""
|
f"""
|
||||||
</ul>)
|
</ul>)
|
||||||
<p>Import terminé !</p>
|
<p>Import terminé !</p>
|
||||||
<p><a class="stdlink" href="{dest_url}">Continuer</a></p>
|
<p><a class="stdlink" href="{dest_url}">Continuer</a></p>
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
return render_template(
|
return "\n".join(H) + html_sco_header.sco_footer()
|
||||||
"sco_page.j2", title="Import etudiants", content="\n".join(H)
|
|
||||||
)
|
|
||||||
return ""
|
|
||||||
|
|
||||||
|
|
||||||
def scolars_import_excel_file(
|
def scolars_import_excel_file(
|
||||||
@ -519,7 +518,8 @@ def students_import_admission(
|
|||||||
use_etudid=use_etudid,
|
use_etudid=use_etudid,
|
||||||
)
|
)
|
||||||
if return_html:
|
if return_html:
|
||||||
H = ["<p>Import terminé !</p>"]
|
H = [html_sco_header.sco_header(page_title="Import données admissions")]
|
||||||
|
H.append("<p>Import terminé !</p>")
|
||||||
H.append(
|
H.append(
|
||||||
f"""<p><a class="stdlink" href="{ url_for(
|
f"""<p><a class="stdlink" href="{ url_for(
|
||||||
"notes.formsemestre_status",
|
"notes.formsemestre_status",
|
||||||
@ -536,9 +536,7 @@ def students_import_admission(
|
|||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
|
||||||
return render_template(
|
return "\n".join(H) + html_sco_header.sco_footer()
|
||||||
"sco_page.j2", title="Import données admissions", content="\n".join(H)
|
|
||||||
)
|
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
|
||||||
|
@ -28,16 +28,14 @@
|
|||||||
"""Rapports sur lycées d'origine des étudiants d'un semestre.
|
"""Rapports sur lycées d'origine des étudiants d'un semestre.
|
||||||
- statistiques decisions
|
- statistiques decisions
|
||||||
- suivi cohortes
|
- suivi cohortes
|
||||||
|
|
||||||
|
|
||||||
TODO: remplacer Google Map par https://leafletjs.com/
|
|
||||||
"""
|
"""
|
||||||
from operator import itemgetter
|
from operator import itemgetter
|
||||||
|
|
||||||
from flask import url_for, g, render_template, request
|
from flask import url_for, g, request
|
||||||
|
|
||||||
import app
|
import app
|
||||||
from app.scodoc import (
|
from app.scodoc import (
|
||||||
|
html_sco_header,
|
||||||
sco_formsemestre,
|
sco_formsemestre,
|
||||||
sco_groups_view,
|
sco_groups_view,
|
||||||
sco_preferences,
|
sco_preferences,
|
||||||
@ -93,16 +91,24 @@ def scodoc_table_etuds_lycees(fmt="html"):
|
|||||||
no_links=True,
|
no_links=True,
|
||||||
)
|
)
|
||||||
tab.base_url = request.base_url
|
tab.base_url = request.base_url
|
||||||
table_html = tab.make_page(fmt=fmt, with_html_headers=False)
|
t = tab.make_page(fmt=fmt, with_html_headers=False)
|
||||||
if fmt != "html":
|
if fmt != "html":
|
||||||
return table_html
|
return t
|
||||||
return render_template(
|
H = [
|
||||||
"formsemestre/etuds_lycees.j2",
|
html_sco_header.sco_header(
|
||||||
table_html=table_html,
|
page_title=tab.page_title,
|
||||||
title=tab.page_title,
|
init_google_maps=True,
|
||||||
title_h2=f"Lycées d'origine des {len(etuds)} étudiants ({len(semdepts)} semestres)",
|
javascripts=["js/map_lycees.js"],
|
||||||
js_coords_lycees=js_coords_lycees(etuds_by_lycee),
|
),
|
||||||
)
|
"""<h2 class="formsemestre">Lycées d'origine des %d étudiants (%d semestres)</h2>"""
|
||||||
|
% (len(etuds), len(semdepts)),
|
||||||
|
t,
|
||||||
|
"""<div id="lyc_map_canvas"></div>
|
||||||
|
""",
|
||||||
|
js_coords_lycees(etuds_by_lycee),
|
||||||
|
html_sco_header.sco_footer(),
|
||||||
|
]
|
||||||
|
return "\n".join(H)
|
||||||
|
|
||||||
|
|
||||||
def _table_etuds_lycees(etuds, group_lycees, title, preferences, no_links=False):
|
def _table_etuds_lycees(etuds, group_lycees, title, preferences, no_links=False):
|
||||||
@ -200,19 +206,30 @@ def formsemestre_etuds_lycees(
|
|||||||
tab.base_url += "&only_primo=1"
|
tab.base_url += "&only_primo=1"
|
||||||
if no_grouping:
|
if no_grouping:
|
||||||
tab.base_url += "&no_grouping=1"
|
tab.base_url += "&no_grouping=1"
|
||||||
table_html = tab.make_page(fmt=fmt, with_html_headers=False)
|
t = tab.make_page(fmt=fmt, with_html_headers=False)
|
||||||
if fmt != "html":
|
if fmt != "html":
|
||||||
return table_html
|
return t
|
||||||
return render_template(
|
F = [
|
||||||
"formsemestre/etuds_lycees.j2",
|
sco_report.tsp_form_primo_group(
|
||||||
form_primo_group=sco_report.tsp_form_primo_group(
|
|
||||||
only_primo, no_grouping, formsemestre_id, fmt, groups_infos=groups_infos
|
only_primo, no_grouping, formsemestre_id, fmt, groups_infos=groups_infos
|
||||||
|
)
|
||||||
|
]
|
||||||
|
H = [
|
||||||
|
html_sco_header.sco_header(
|
||||||
|
page_title=tab.page_title,
|
||||||
|
init_google_maps=True,
|
||||||
|
cssstyles=sco_groups_view.CSSSTYLES,
|
||||||
|
javascripts=sco_groups_view.JAVASCRIPTS + ["js/map_lycees.js"],
|
||||||
),
|
),
|
||||||
table_html=table_html,
|
"""<h2 class="formsemestre">Lycées d'origine des étudiants</h2>""",
|
||||||
title=tab.page_title,
|
"\n".join(F),
|
||||||
title_h2="Lycées d'origine des étudiants",
|
t,
|
||||||
js_coords_lycees=js_coords_lycees(etuds_by_lycee),
|
"""<div id="lyc_map_canvas"></div>
|
||||||
)
|
""",
|
||||||
|
js_coords_lycees(etuds_by_lycee),
|
||||||
|
html_sco_header.sco_footer(),
|
||||||
|
]
|
||||||
|
return "\n".join(H)
|
||||||
|
|
||||||
|
|
||||||
def qjs(txt): # quote for JS
|
def qjs(txt): # quote for JS
|
||||||
|
@ -3,12 +3,15 @@
|
|||||||
|
|
||||||
"""Functions checking permissions for some common operations
|
"""Functions checking permissions for some common operations
|
||||||
"""
|
"""
|
||||||
from flask import g, render_template
|
from flask import g
|
||||||
from flask_login import current_user
|
from flask_login import current_user
|
||||||
|
|
||||||
|
from app import db
|
||||||
from app.auth.models import User
|
from app.auth.models import User
|
||||||
from app.models import EtudAnnotation, FormSemestre, Identite
|
import app.scodoc.notesdb as ndb
|
||||||
from app.scodoc.sco_permissions import Permission
|
from app.scodoc.sco_permissions import Permission
|
||||||
|
from app.scodoc import html_sco_header
|
||||||
|
from app.scodoc import sco_etud
|
||||||
from app.scodoc import sco_exceptions
|
from app.scodoc import sco_exceptions
|
||||||
|
|
||||||
|
|
||||||
@ -17,15 +20,12 @@ def can_suppress_annotation(annotation_id):
|
|||||||
Seuls l'auteur de l'annotation et le chef de dept peuvent supprimer
|
Seuls l'auteur de l'annotation et le chef de dept peuvent supprimer
|
||||||
une annotation.
|
une annotation.
|
||||||
"""
|
"""
|
||||||
annotation = (
|
cnx = ndb.GetDBConnexion()
|
||||||
EtudAnnotation.query.filter_by(id=annotation_id)
|
annos = sco_etud.etud_annotations_list(cnx, args={"id": annotation_id})
|
||||||
.join(Identite)
|
if len(annos) != 1:
|
||||||
.filter_by(dept_id=g.scodoc_dept_id)
|
|
||||||
.first_or_404()
|
|
||||||
)
|
|
||||||
if not annotation:
|
|
||||||
raise sco_exceptions.ScoValueError("annotation inexistante !")
|
raise sco_exceptions.ScoValueError("annotation inexistante !")
|
||||||
return (current_user.user_name == annotation.author) or current_user.has_permission(
|
anno = annos[0]
|
||||||
|
return (current_user.user_name == anno["author"]) or current_user.has_permission(
|
||||||
Permission.EtudAddAnnotations
|
Permission.EtudAddAnnotations
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -35,35 +35,49 @@ def can_edit_suivi():
|
|||||||
return current_user.has_permission(Permission.EtudChangeAdr)
|
return current_user.has_permission(Permission.EtudChangeAdr)
|
||||||
|
|
||||||
|
|
||||||
|
def is_chef_or_diretud(sem): # remplacé par formsemestre.est_chef_or_diretud
|
||||||
|
"Vrai si utilisateur est admin, chef dept ou responsable du semestre"
|
||||||
|
if (
|
||||||
|
current_user.has_permission(Permission.EditFormSemestre)
|
||||||
|
or current_user.id in sem["responsables"]
|
||||||
|
):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def check_access_diretud(
|
def check_access_diretud(
|
||||||
formsemestre_id, required_permission=Permission.EditFormSemestre
|
formsemestre_id, required_permission=Permission.EditFormSemestre
|
||||||
):
|
):
|
||||||
"""Check if access granted: responsable or EditFormSemestre
|
"""Check if access granted: responsable or EditFormSemestre
|
||||||
Return True|False, HTML_error_page
|
Return True|False, HTML_error_page
|
||||||
"""
|
"""
|
||||||
formsemestre = FormSemestre.get_formsemestre(formsemestre_id)
|
from app.scodoc import sco_formsemestre
|
||||||
if (not current_user.has_permission(required_permission)) and (
|
|
||||||
current_user.id not in (u.id for u in formsemestre.responsables)
|
sem = sco_formsemestre.get_formsemestre(formsemestre_id)
|
||||||
|
header = html_sco_header.sco_header(page_title="Accès interdit")
|
||||||
|
footer = html_sco_header.sco_footer()
|
||||||
|
if (current_user.id not in sem["responsables"]) and not current_user.has_permission(
|
||||||
|
required_permission
|
||||||
):
|
):
|
||||||
return (
|
return (
|
||||||
False,
|
False,
|
||||||
render_template(
|
"\n".join(
|
||||||
"sco_page.j2",
|
[
|
||||||
title="Accès interdit",
|
header,
|
||||||
content=f"""<h2>Opération non autorisée pour {current_user}</h2>
|
"<h2>Opération non autorisée pour %s</h2>" % current_user,
|
||||||
|
"<p>Responsable de ce semestre : <b>%s</b></p>"
|
||||||
<p>Responsable(s) de ce semestre : <b>{
|
% ", ".join(
|
||||||
', '.join(
|
|
||||||
[
|
[
|
||||||
u.get_prenomnom()
|
db.session.get(User, i).get_prenomnom()
|
||||||
for u in formsemestre.responsables
|
for i in sem["responsables"]
|
||||||
])
|
]
|
||||||
}</b>
|
),
|
||||||
</p>
|
footer,
|
||||||
""",
|
]
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
return True, ""
|
else:
|
||||||
|
return True, ""
|
||||||
|
|
||||||
|
|
||||||
def can_handle_passwd(user: User, allow_admindepts=False) -> bool:
|
def can_handle_passwd(user: User, allow_admindepts=False) -> bool:
|
||||||
|
@ -51,7 +51,7 @@ from wtforms import (
|
|||||||
from app.models import Evaluation, ModuleImpl
|
from app.models import Evaluation, ModuleImpl
|
||||||
import app.scodoc.sco_utils as scu
|
import app.scodoc.sco_utils as scu
|
||||||
import app.scodoc.notesdb as ndb
|
import app.scodoc.notesdb as ndb
|
||||||
from app.scodoc import sco_preferences
|
from app.scodoc import html_sco_header, sco_preferences
|
||||||
from app.scodoc import sco_edit_module
|
from app.scodoc import sco_edit_module
|
||||||
from app.scodoc import sco_evaluations
|
from app.scodoc import sco_evaluations
|
||||||
from app.scodoc import sco_excel
|
from app.scodoc import sco_excel
|
||||||
@ -204,14 +204,14 @@ def placement_eval_selectetuds(evaluation_id):
|
|||||||
% runner.__dict__
|
% runner.__dict__
|
||||||
)
|
)
|
||||||
return runner.exec_placement() # calcul et generation du fichier
|
return runner.exec_placement() # calcul et generation du fichier
|
||||||
|
htmls = [
|
||||||
return render_template(
|
html_sco_header.sco_header(),
|
||||||
"scodoc/forms/placement.j2",
|
sco_evaluations.evaluation_describe(evaluation_id=evaluation_id),
|
||||||
evaluations_description=sco_evaluations.evaluation_describe(
|
"<h3>Placement et émargement des étudiants</h3>",
|
||||||
evaluation_id=evaluation_id
|
render_template("scodoc/forms/placement.j2", form=form),
|
||||||
),
|
]
|
||||||
form=form,
|
footer = html_sco_header.sco_footer()
|
||||||
)
|
return "\n".join(htmls) + "<p>" + footer
|
||||||
|
|
||||||
|
|
||||||
class PlacementRunner:
|
class PlacementRunner:
|
||||||
|
@ -37,7 +37,7 @@ import time
|
|||||||
import datetime
|
import datetime
|
||||||
from operator import itemgetter
|
from operator import itemgetter
|
||||||
|
|
||||||
from flask import url_for, g, render_template, request
|
from flask import url_for, g, request
|
||||||
import pydot
|
import pydot
|
||||||
|
|
||||||
from app import log
|
from app import log
|
||||||
@ -50,6 +50,7 @@ from app.models.etudiants import Identite
|
|||||||
|
|
||||||
from app.scodoc import (
|
from app.scodoc import (
|
||||||
codes_cursus,
|
codes_cursus,
|
||||||
|
html_sco_header,
|
||||||
sco_etud,
|
sco_etud,
|
||||||
sco_formsemestre,
|
sco_formsemestre,
|
||||||
sco_formsemestre_inscriptions,
|
sco_formsemestre_inscriptions,
|
||||||
@ -410,6 +411,11 @@ def formsemestre_report_counts(
|
|||||||
if fmt != "html":
|
if fmt != "html":
|
||||||
return tableau
|
return tableau
|
||||||
H = [
|
H = [
|
||||||
|
html_sco_header.sco_header(
|
||||||
|
cssstyles=sco_groups_view.CSSSTYLES,
|
||||||
|
javascripts=sco_groups_view.JAVASCRIPTS,
|
||||||
|
page_title=title,
|
||||||
|
),
|
||||||
tableau,
|
tableau,
|
||||||
"\n".join(F),
|
"\n".join(F),
|
||||||
"""<p class="help">Le tableau affiche le nombre d'étudiants de ce semestre dans chacun
|
"""<p class="help">Le tableau affiche le nombre d'étudiants de ce semestre dans chacun
|
||||||
@ -417,14 +423,9 @@ def formsemestre_report_counts(
|
|||||||
pour les lignes et les colonnes. Le <tt>codedecision</tt> est le code de la décision
|
pour les lignes et les colonnes. Le <tt>codedecision</tt> est le code de la décision
|
||||||
du jury.
|
du jury.
|
||||||
</p>""",
|
</p>""",
|
||||||
|
html_sco_header.sco_footer(),
|
||||||
]
|
]
|
||||||
return render_template(
|
return "\n".join(H)
|
||||||
"sco_page.j2",
|
|
||||||
cssstyles=sco_groups_view.CSSSTYLES,
|
|
||||||
javascripts=sco_groups_view.JAVASCRIPTS,
|
|
||||||
title=title,
|
|
||||||
content="\n".join(H),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
# --------------------------------------------------------------------------
|
# --------------------------------------------------------------------------
|
||||||
@ -812,6 +813,11 @@ def formsemestre_suivi_cohorte(
|
|||||||
href="{burl}&percent=1">Afficher les résultats en pourcentages</a></p>"""
|
href="{burl}&percent=1">Afficher les résultats en pourcentages</a></p>"""
|
||||||
|
|
||||||
H = [
|
H = [
|
||||||
|
html_sco_header.sco_header(
|
||||||
|
cssstyles=sco_groups_view.CSSSTYLES,
|
||||||
|
javascripts=sco_groups_view.JAVASCRIPTS,
|
||||||
|
page_title=tab.page_title,
|
||||||
|
),
|
||||||
"""<h2 class="formsemestre">Suivi cohorte: devenir des étudiants de ce semestre</h2>""",
|
"""<h2 class="formsemestre">Suivi cohorte: devenir des étudiants de ce semestre</h2>""",
|
||||||
_gen_form_selectetuds(
|
_gen_form_selectetuds(
|
||||||
formsemestre.id,
|
formsemestre.id,
|
||||||
@ -847,14 +853,9 @@ def formsemestre_suivi_cohorte(
|
|||||||
</p>
|
</p>
|
||||||
""",
|
""",
|
||||||
expl,
|
expl,
|
||||||
|
html_sco_header.sco_footer(),
|
||||||
]
|
]
|
||||||
return render_template(
|
return "\n".join(H)
|
||||||
"sco_page.j2",
|
|
||||||
cssstyles=sco_groups_view.CSSSTYLES,
|
|
||||||
javascripts=sco_groups_view.JAVASCRIPTS,
|
|
||||||
title=tab.page_title,
|
|
||||||
content="\n".join(H),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def _gen_form_selectetuds(
|
def _gen_form_selectetuds(
|
||||||
@ -1364,11 +1365,15 @@ def formsemestre_suivi_cursus(
|
|||||||
]
|
]
|
||||||
|
|
||||||
H = [
|
H = [
|
||||||
|
html_sco_header.sco_header(
|
||||||
|
page_title=tab.page_title,
|
||||||
|
),
|
||||||
"""<h2 class="formsemestre">Cursus suivis par les étudiants de ce semestre</h2>""",
|
"""<h2 class="formsemestre">Cursus suivis par les étudiants de ce semestre</h2>""",
|
||||||
"\n".join(F),
|
"\n".join(F),
|
||||||
t,
|
t,
|
||||||
|
html_sco_header.sco_footer(),
|
||||||
]
|
]
|
||||||
return render_template("sco_page.j2", title=tab.page_title, content="\n".join(H))
|
return "\n".join(H)
|
||||||
|
|
||||||
|
|
||||||
# -------------
|
# -------------
|
||||||
@ -1737,6 +1742,12 @@ def formsemestre_graph_cursus(
|
|||||||
)
|
)
|
||||||
|
|
||||||
H = [
|
H = [
|
||||||
|
html_sco_header.sco_header(
|
||||||
|
cssstyles=sco_groups_view.CSSSTYLES,
|
||||||
|
javascripts=sco_groups_view.JAVASCRIPTS,
|
||||||
|
page_title="Graphe cursus de %(titreannee)s" % sem,
|
||||||
|
no_sidebar=True,
|
||||||
|
),
|
||||||
"""<h2 class="formsemestre">Cursus des étudiants de ce semestre</h2>""",
|
"""<h2 class="formsemestre">Cursus des étudiants de ce semestre</h2>""",
|
||||||
doc,
|
doc,
|
||||||
f"<p>{len(etuds)} étudiants sélectionnés</p>",
|
f"<p>{len(etuds)} étudiants sélectionnés</p>",
|
||||||
@ -1760,12 +1771,11 @@ def formsemestre_graph_cursus(
|
|||||||
),
|
),
|
||||||
"""<p>Origine et devenir des étudiants inscrits dans %(titreannee)s"""
|
"""<p>Origine et devenir des étudiants inscrits dans %(titreannee)s"""
|
||||||
% sem,
|
% sem,
|
||||||
f"""(<a href="{
|
"""(<a href="%s">version pdf</a>"""
|
||||||
url_for("notes.formsemestre_graph_cursus", fmt="pdf", **url_kw)
|
% url_for("notes.formsemestre_graph_cursus", fmt="pdf", **url_kw),
|
||||||
}">version pdf</a>,
|
""", <a href="%s">image PNG</a>)"""
|
||||||
<a href="{
|
% url_for("notes.formsemestre_graph_cursus", fmt="png", **url_kw),
|
||||||
url_for("notes.formsemestre_graph_cursus", fmt="png", **url_kw)}">image PNG</a>)
|
f"""
|
||||||
|
|
||||||
</p>
|
</p>
|
||||||
<p class="help">Le graphe permet de suivre les étudiants inscrits dans le semestre
|
<p class="help">Le graphe permet de suivre les étudiants inscrits dans le semestre
|
||||||
sélectionné (dessiné en vert). Chaque rectangle représente un semestre (cliquez dedans
|
sélectionné (dessiné en vert). Chaque rectangle représente un semestre (cliquez dedans
|
||||||
@ -1778,14 +1788,8 @@ def formsemestre_graph_cursus(
|
|||||||
étudiants appartenant aux groupes indiqués <em>dans le semestre d'origine</em>.
|
étudiants appartenant aux groupes indiqués <em>dans le semestre d'origine</em>.
|
||||||
</p>
|
</p>
|
||||||
""",
|
""",
|
||||||
|
html_sco_header.sco_footer(),
|
||||||
]
|
]
|
||||||
return render_template(
|
return "\n".join(H)
|
||||||
"sco_page.j2",
|
|
||||||
cssstyles=sco_groups_view.CSSSTYLES,
|
|
||||||
javascripts=sco_groups_view.JAVASCRIPTS,
|
|
||||||
page_title=f"Graphe cursus de {sem['titreannee']}",
|
|
||||||
no_sidebar=True,
|
|
||||||
content="\n".join(H),
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
raise ValueError(f"invalid format: {fmt}")
|
raise ValueError(f"invalid format: {fmt}")
|
||||||
|
@ -31,18 +31,21 @@
|
|||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
|
||||||
|
|
||||||
from flask import render_template, request
|
from flask import request
|
||||||
|
|
||||||
from app import db
|
from app import db
|
||||||
from app.but import jury_but
|
from app.but import jury_but
|
||||||
from app.models import FormSemestre
|
from app.models import FormSemestre
|
||||||
from app.models.formsemestre import FormSemestreInscription
|
from app.models.formsemestre import FormSemestreInscription
|
||||||
|
|
||||||
import app.scodoc.sco_utils as scu
|
import app.scodoc.sco_utils as scu
|
||||||
|
from app.scodoc import html_sco_header
|
||||||
from app.scodoc import codes_cursus
|
from app.scodoc import codes_cursus
|
||||||
from app.scodoc.sco_exceptions import ScoValueError
|
from app.scodoc.sco_exceptions import ScoValueError
|
||||||
|
|
||||||
from app.scodoc import sco_preferences
|
from app.scodoc import sco_preferences
|
||||||
from app.scodoc.gen_tables import GenTable
|
|
||||||
import sco_version
|
import sco_version
|
||||||
|
from app.scodoc.gen_tables import GenTable
|
||||||
|
|
||||||
|
|
||||||
# Titres, ordonnés
|
# Titres, ordonnés
|
||||||
@ -104,11 +107,13 @@ def formsemestre_but_indicateurs(formsemestre_id: int, fmt="html"):
|
|||||||
if fmt != "html":
|
if fmt != "html":
|
||||||
return t
|
return t
|
||||||
H = [
|
H = [
|
||||||
|
html_sco_header.sco_header(page_title=title),
|
||||||
t,
|
t,
|
||||||
"""<p class="help">
|
"""<p class="help">
|
||||||
</p>""",
|
</p>""",
|
||||||
|
html_sco_header.sco_footer(),
|
||||||
]
|
]
|
||||||
return render_template("sco_page.j2", title=title, content="\n".join(H))
|
return "\n".join(H)
|
||||||
|
|
||||||
|
|
||||||
def but_indicateurs_by_bac(formsemestre: FormSemestre) -> dict[str:dict]:
|
def but_indicateurs_by_bac(formsemestre: FormSemestre) -> dict[str:dict]:
|
||||||
|
@ -928,7 +928,7 @@ def _get_sheet_evaluations(
|
|||||||
i, r = _xls_search_sheet_code(rows, diag)
|
i, r = _xls_search_sheet_code(rows, diag)
|
||||||
if isinstance(r, int): # mono-eval
|
if isinstance(r, int): # mono-eval
|
||||||
sheet_eval_id = r
|
sheet_eval_id = r
|
||||||
if (evaluation is None) or (sheet_eval_id != evaluation.id):
|
if sheet_eval_id != evaluation.id:
|
||||||
diag.append(
|
diag.append(
|
||||||
f"""Erreur: fichier invalide: le code d'évaluation de correspond pas ! ('{
|
f"""Erreur: fichier invalide: le code d'évaluation de correspond pas ! ('{
|
||||||
sheet_eval_id or ('non trouvé')}' != '{evaluation.id}')"""
|
sheet_eval_id or ('non trouvé')}' != '{evaluation.id}')"""
|
||||||
|
@ -40,15 +40,17 @@ sem_set_list()
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import flask
|
import flask
|
||||||
from flask import g, render_template, url_for
|
from flask import g, url_for
|
||||||
|
|
||||||
from app import db, log
|
from app import db, log
|
||||||
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
|
||||||
|
from app.scodoc import html_sco_header
|
||||||
from app.scodoc import sco_etape_apogee
|
from app.scodoc import sco_etape_apogee
|
||||||
from app.scodoc import sco_formsemestre
|
from app.scodoc import sco_formsemestre
|
||||||
from app.scodoc import sco_formsemestre_status
|
from app.scodoc import sco_formsemestre_status
|
||||||
|
from app.scodoc import sco_portal_apogee
|
||||||
from app.scodoc import sco_preferences
|
from app.scodoc import sco_preferences
|
||||||
from app.scodoc.gen_tables import GenTable
|
from app.scodoc.gen_tables import GenTable
|
||||||
from app.scodoc.sco_etape_bilan import EtapeBilan
|
from app.scodoc.sco_etape_bilan import EtapeBilan
|
||||||
@ -410,7 +412,7 @@ def do_semset_delete(semset_id, dialog_confirmed=False):
|
|||||||
s = SemSet(semset_id=semset_id)
|
s = SemSet(semset_id=semset_id)
|
||||||
if not dialog_confirmed:
|
if not dialog_confirmed:
|
||||||
return scu.confirm_dialog(
|
return scu.confirm_dialog(
|
||||||
f"<h2>Suppression de l'ensemble {s['title']} ?</h2>",
|
"<h2>Suppression de l'ensemble %(title)s ?</h2>" % s,
|
||||||
dest_url="",
|
dest_url="",
|
||||||
parameters={"semset_id": semset_id},
|
parameters={"semset_id": semset_id},
|
||||||
cancel_url="semset_page",
|
cancel_url="semset_page",
|
||||||
@ -419,14 +421,14 @@ def do_semset_delete(semset_id, dialog_confirmed=False):
|
|||||||
return flask.redirect("semset_page")
|
return flask.redirect("semset_page")
|
||||||
|
|
||||||
|
|
||||||
def edit_semset_set_title(oid=None, value=None):
|
def edit_semset_set_title(id=None, value=None):
|
||||||
"""Change title of semset"""
|
"""Change title of semset"""
|
||||||
title = value.strip()
|
title = value.strip()
|
||||||
if not oid:
|
if not id:
|
||||||
raise ScoValueError("empty semset_id")
|
raise ScoValueError("empty semset_id")
|
||||||
SemSet(semset_id=oid)
|
SemSet(semset_id=id)
|
||||||
cnx = ndb.GetDBConnexion()
|
cnx = ndb.GetDBConnexion()
|
||||||
semset_edit(cnx, {"semset_id": oid, "title": title})
|
semset_edit(cnx, {"semset_id": id, "title": title})
|
||||||
return title
|
return title
|
||||||
|
|
||||||
|
|
||||||
@ -515,18 +517,22 @@ def semset_page(fmt="html"):
|
|||||||
|
|
||||||
page_title = "Ensembles de semestres"
|
page_title = "Ensembles de semestres"
|
||||||
H = [
|
H = [
|
||||||
|
html_sco_header.sco_header(
|
||||||
|
page_title=page_title,
|
||||||
|
javascripts=["libjs/jinplace-1.2.1.min.js"],
|
||||||
|
),
|
||||||
"""<script>$(function() {
|
"""<script>$(function() {
|
||||||
$('.inplace_edit').jinplace();
|
$('.inplace_edit').jinplace();
|
||||||
});
|
});
|
||||||
</script>""",
|
</script>""",
|
||||||
f"<h2>{page_title}</h2>",
|
"<h2>%s</h2>" % page_title,
|
||||||
]
|
]
|
||||||
H.append(tab.html())
|
H.append(tab.html())
|
||||||
|
|
||||||
annee_courante = int(scu.annee_scolaire())
|
annee_courante = int(scu.annee_scolaire())
|
||||||
menu_annee = "\n".join(
|
menu_annee = "\n".join(
|
||||||
[
|
[
|
||||||
f"""<option value="{i}">{i}</option>"""
|
'<option value="%s">%s</option>' % (i, i)
|
||||||
for i in range(2014, annee_courante + 1)
|
for i in range(2014, annee_courante + 1)
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
@ -555,8 +561,8 @@ def semset_page(fmt="html"):
|
|||||||
|
|
||||||
H.append(
|
H.append(
|
||||||
"""
|
"""
|
||||||
<div class="scobox space-before-24">
|
<div>
|
||||||
<div class="scobox-title">Autres opérations :</div>
|
<h4>Autres opérations:</h4>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a class="stdlink" href="scodoc_table_results">
|
<li><a class="stdlink" href="scodoc_table_results">
|
||||||
Table des résultats de tous les semestres
|
Table des résultats de tous les semestres
|
||||||
@ -569,9 +575,4 @@ def semset_page(fmt="html"):
|
|||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
|
||||||
return render_template(
|
return "\n".join(H) + html_sco_header.sco_footer()
|
||||||
"sco_page_dept.j2",
|
|
||||||
title=page_title,
|
|
||||||
javascripts=["libjs/jinplace-1.2.1.min.js"],
|
|
||||||
content="\n".join(H),
|
|
||||||
)
|
|
||||||
|
@ -49,6 +49,7 @@ import app.scodoc.sco_utils as scu
|
|||||||
from app.scodoc.TrivialFormulator import TrivialFormulator
|
from app.scodoc.TrivialFormulator import TrivialFormulator
|
||||||
from app.scodoc.sco_exceptions import ScoPDFFormatError, ScoValueError
|
from app.scodoc.sco_exceptions import ScoPDFFormatError, ScoValueError
|
||||||
from app.scodoc.sco_pdf import SU
|
from app.scodoc.sco_pdf import SU
|
||||||
|
from app.scodoc import html_sco_header
|
||||||
from app.scodoc import htmlutils
|
from app.scodoc import htmlutils
|
||||||
from app.scodoc import sco_import_etuds
|
from app.scodoc import sco_import_etuds
|
||||||
from app.scodoc import sco_excel
|
from app.scodoc import sco_excel
|
||||||
@ -89,7 +90,12 @@ def trombino(
|
|||||||
return _listeappel_photos_pdf(groups_infos)
|
return _listeappel_photos_pdf(groups_infos)
|
||||||
elif fmt == "doc":
|
elif fmt == "doc":
|
||||||
return sco_trombino_doc.trombino_doc(groups_infos)
|
return sco_trombino_doc.trombino_doc(groups_infos)
|
||||||
raise ValueError("invalid format")
|
else:
|
||||||
|
raise Exception("invalid format")
|
||||||
|
|
||||||
|
|
||||||
|
def _trombino_html_header():
|
||||||
|
return html_sco_header.sco_header(javascripts=["js/trombino.js"])
|
||||||
|
|
||||||
|
|
||||||
def trombino_html(groups_infos):
|
def trombino_html(groups_infos):
|
||||||
@ -245,18 +251,14 @@ def trombino_copy_photos(group_ids=None, dialog_confirmed=False):
|
|||||||
back_url = "groups_photos?" + str(groups_infos.groups_query_args)
|
back_url = "groups_photos?" + str(groups_infos.groups_query_args)
|
||||||
|
|
||||||
portal_url = sco_portal_apogee.get_portal_url()
|
portal_url = sco_portal_apogee.get_portal_url()
|
||||||
|
header = html_sco_header.sco_header(page_title="Chargement des photos")
|
||||||
|
footer = html_sco_header.sco_footer()
|
||||||
if not portal_url:
|
if not portal_url:
|
||||||
return render_template(
|
return f"""{ header }
|
||||||
"sco_page.j2",
|
|
||||||
content=f"""
|
|
||||||
<p>portail non configuré</p>
|
<p>portail non configuré</p>
|
||||||
<div>
|
<p><a href="{back_url}" class="stdlink">Retour au trombinoscope</a></p>
|
||||||
<a class="stdlink" href="{back_url}" class="stdlink">
|
{ footer }
|
||||||
Retour au trombinoscope
|
"""
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
""",
|
|
||||||
)
|
|
||||||
if not dialog_confirmed:
|
if not dialog_confirmed:
|
||||||
return scu.confirm_dialog(
|
return scu.confirm_dialog(
|
||||||
f"""<h2>Copier les photos du portail vers ScoDoc ?</h2>
|
f"""<h2>Copier les photos du portail vers ScoDoc ?</h2>
|
||||||
@ -283,18 +285,14 @@ def trombino_copy_photos(group_ids=None, dialog_confirmed=False):
|
|||||||
|
|
||||||
msg.append(f"<b>{nok} photos correctement chargées</b>")
|
msg.append(f"<b>{nok} photos correctement chargées</b>")
|
||||||
|
|
||||||
return render_template(
|
return f"""{ header }
|
||||||
"sco_page.j2",
|
|
||||||
content=f"""
|
|
||||||
<h2>Chargement des photos depuis le portail</h2>
|
<h2>Chargement des photos depuis le portail</h2>
|
||||||
<ul><li>
|
<ul><li>
|
||||||
{ '</li><li>'.join(msg) }
|
{ '</li><li>'.join(msg) }
|
||||||
</li></ul>
|
</li></ul>
|
||||||
<div class="space-before-24">
|
<p><a href="{back_url}">retour au trombinoscope</a>
|
||||||
<a class="stdlink" href="{back_url}">retour au trombinoscope</a>
|
{ footer }
|
||||||
</div>
|
"""
|
||||||
""",
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def _get_etud_platypus_image(t, image_width=2 * cm):
|
def _get_etud_platypus_image(t, image_width=2 * cm):
|
||||||
@ -508,6 +506,7 @@ def photos_import_files_form(group_ids=()):
|
|||||||
back_url = f"groups_photos?{groups_infos.groups_query_args}"
|
back_url = f"groups_photos?{groups_infos.groups_query_args}"
|
||||||
|
|
||||||
H = [
|
H = [
|
||||||
|
html_sco_header.sco_header(page_title="Import des photos des étudiants"),
|
||||||
f"""<h2 class="formsemestre">Téléchargement des photos des étudiants</h2>
|
f"""<h2 class="formsemestre">Téléchargement des photos des étudiants</h2>
|
||||||
<p><b>Vous pouvez aussi charger les photos individuellement via la fiche
|
<p><b>Vous pouvez aussi charger les photos individuellement via la fiche
|
||||||
de chaque étudiant (menu "Étudiant" / "Changer la photo").</b>
|
de chaque étudiant (menu "Étudiant" / "Changer la photo").</b>
|
||||||
@ -527,6 +526,7 @@ def photos_import_files_form(group_ids=()):
|
|||||||
<li style="padding-top: 2em;">
|
<li style="padding-top: 2em;">
|
||||||
""",
|
""",
|
||||||
]
|
]
|
||||||
|
F = html_sco_header.sco_footer()
|
||||||
vals = scu.get_request_args()
|
vals = scu.get_request_args()
|
||||||
vals["group_ids"] = groups_infos.group_ids
|
vals["group_ids"] = groups_infos.group_ids
|
||||||
tf = TrivialFormulator(
|
tf = TrivialFormulator(
|
||||||
@ -540,40 +540,37 @@ def photos_import_files_form(group_ids=()):
|
|||||||
)
|
)
|
||||||
|
|
||||||
if tf[0] == 0:
|
if tf[0] == 0:
|
||||||
return render_template(
|
return "\n".join(H) + tf[1] + "</li></ol>" + F
|
||||||
"sco_page.j2",
|
elif tf[0] == -1:
|
||||||
title="Import des photos des étudiants",
|
|
||||||
content="\n".join(H) + tf[1] + "</li></ol>",
|
|
||||||
)
|
|
||||||
if tf[0] == -1:
|
|
||||||
return flask.redirect(back_url)
|
return flask.redirect(back_url)
|
||||||
|
else:
|
||||||
|
|
||||||
def callback(etud: Identite, data, filename):
|
def callback(etud: Identite, data, filename):
|
||||||
return sco_photos.store_photo(etud, data, filename)
|
return sco_photos.store_photo(etud, data, filename)
|
||||||
|
|
||||||
(
|
(
|
||||||
ignored_zipfiles,
|
ignored_zipfiles,
|
||||||
unmatched_files,
|
unmatched_files,
|
||||||
stored_etud_filename,
|
stored_etud_filename,
|
||||||
) = zip_excel_import_files(
|
) = zip_excel_import_files(
|
||||||
xlsfile=tf[2]["xlsfile"],
|
xlsfile=tf[2]["xlsfile"],
|
||||||
zipfile=tf[2]["zipfile"],
|
zipfile=tf[2]["zipfile"],
|
||||||
callback=callback,
|
callback=callback,
|
||||||
filename_title="fichier_photo",
|
filename_title="fichier_photo",
|
||||||
back_url=back_url,
|
back_url=back_url,
|
||||||
)
|
)
|
||||||
return render_template(
|
return render_template(
|
||||||
"scolar/photos_import_files.j2",
|
"scolar/photos_import_files.j2",
|
||||||
page_title="Téléchargement des photos des étudiants",
|
page_title="Téléchargement des photos des étudiants",
|
||||||
ignored_zipfiles=ignored_zipfiles,
|
ignored_zipfiles=ignored_zipfiles,
|
||||||
unmatched_files=unmatched_files,
|
unmatched_files=unmatched_files,
|
||||||
stored_etud_filename=stored_etud_filename,
|
stored_etud_filename=stored_etud_filename,
|
||||||
next_page=url_for(
|
next_page=url_for(
|
||||||
"scolar.groups_photos",
|
"scolar.groups_photos",
|
||||||
scodoc_dept=g.scodoc_dept,
|
scodoc_dept=g.scodoc_dept,
|
||||||
formsemestre_id=groups_infos.formsemestre_id,
|
formsemestre_id=groups_infos.formsemestre_id,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def _norm_zip_filename(fn, lowercase=True):
|
def _norm_zip_filename(fn, lowercase=True):
|
||||||
|
@ -39,6 +39,7 @@ from app import Departement
|
|||||||
|
|
||||||
from app.auth.models import Permission, Role, User, UserRole
|
from app.auth.models import Permission, Role, User, UserRole
|
||||||
from app.models import ScoDocSiteConfig, USERNAME_STR_LEN
|
from app.models import ScoDocSiteConfig, USERNAME_STR_LEN
|
||||||
|
from app.scodoc import html_sco_header
|
||||||
from app.scodoc import sco_preferences
|
from app.scodoc import sco_preferences
|
||||||
from app.scodoc.gen_tables import GenTable
|
from app.scodoc.gen_tables import GenTable
|
||||||
from app import cache
|
from app import cache
|
||||||
|
@ -59,11 +59,11 @@ div.sco-app-content {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.space-before-18 {
|
.space-before-18 {
|
||||||
margin-top: 18px !important;
|
margin-top: 18px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.space-before-24 {
|
.space-before-24 {
|
||||||
margin-top: 24px !important;
|
margin-top: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.scobox.maxwidth {
|
div.scobox.maxwidth {
|
||||||
@ -2476,10 +2476,6 @@ li.notes_formation_list {
|
|||||||
padding-top: 10px;
|
padding-top: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dt-scroll-body {
|
|
||||||
overflow: initial !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
table.dataTable.formation_list_table.gt_table {
|
table.dataTable.formation_list_table.gt_table {
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
margin-right: 12px;
|
margin-right: 12px;
|
||||||
|
10
app/static/js/trombino.js
Normal file
10
app/static/js/trombino.js
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
// Affichage progressif du trombinoscope html
|
||||||
|
|
||||||
|
$().ready(function () {
|
||||||
|
var spans = $(".unloaded_img");
|
||||||
|
for (var i = 0; i < spans.size(); i++) {
|
||||||
|
var sp = spans[i];
|
||||||
|
var etudid = sp.id;
|
||||||
|
$(sp).load(SCO_URL + "etud_photo_html?etudid=" + etudid);
|
||||||
|
}
|
||||||
|
});
|
@ -10,7 +10,7 @@
|
|||||||
<br />
|
<br />
|
||||||
Ces utilisateurs peuvent être réactivés à tout moment.
|
Ces utilisateurs peuvent être réactivés à tout moment.
|
||||||
</div>
|
</div>
|
||||||
<div class="row space-before-24">
|
<div class="row">
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
{{ wtf.quick_form(form, button_map={'submit':'secondary'}) }}
|
{{ wtf.quick_form(form, button_map={'submit':'secondary'}) }}
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,32 +0,0 @@
|
|||||||
{% extends "sco_page.j2" %}
|
|
||||||
|
|
||||||
{% block styles %}
|
|
||||||
{{super()}}
|
|
||||||
<style>
|
|
||||||
|
|
||||||
</style>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block app_content %}
|
|
||||||
<h2 class="formsemestre">{{title_h2}}</h2>
|
|
||||||
|
|
||||||
<div class="help warning">
|
|
||||||
Page non fonctionnelle dans cette version (modif. API Google)
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{{form_primo_group|safe}}
|
|
||||||
|
|
||||||
{{table_html|safe}}
|
|
||||||
|
|
||||||
<div id="lyc_map_canvas"></div>
|
|
||||||
|
|
||||||
{{js_coords_lycees|safe}}
|
|
||||||
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block scripts %}
|
|
||||||
{{super()}}
|
|
||||||
<script src="{{scu.STATIC_DIR}}/libjs/jquery.ui.map.full.min.js"></script>
|
|
||||||
<script src="https://maps.google.com/maps/api/js"></script>
|
|
||||||
<script src="{{scu.STATIC_DIR}}/js/map_lycees.js"></script>
|
|
||||||
{% endblock %}
|
|
@ -3,13 +3,15 @@
|
|||||||
|
|
||||||
{% block styles %}
|
{% block styles %}
|
||||||
{{super()}}
|
{{super()}}
|
||||||
<link type="text/css" rel="stylesheet" href="{{scu.STATIC_DIR}}/libjs/qtip/jquery.qtip-3.0.3.min.css" />
|
|
||||||
<link rel="stylesheet" type="text/css" href="{{scu.STATIC_DIR}}/DataTables/datatables.min.css" />
|
|
||||||
<link rel="stylesheet" href="{{scu.STATIC_DIR}}/css/scodoc.css">
|
<link rel="stylesheet" href="{{scu.STATIC_DIR}}/css/scodoc.css">
|
||||||
<link rel="stylesheet" href="{{scu.STATIC_DIR}}/css/scodoc97.css">
|
<link rel="stylesheet" href="{{scu.STATIC_DIR}}/css/scodoc97.css">
|
||||||
<link rel="stylesheet" href="{{scu.STATIC_DIR}}/css/scodoc9_mobile.css">
|
<link rel="stylesheet" href="{{scu.STATIC_DIR}}/css/scodoc9_mobile.css">
|
||||||
<link href="{{scu.STATIC_DIR}}/css/menu.css" rel="stylesheet" type="text/css" />
|
<link href="{{scu.STATIC_DIR}}/css/menu.css" rel="stylesheet" type="text/css" />
|
||||||
<link href="{{scu.STATIC_DIR}}/css/gt_table.css" rel="stylesheet" type="text/css" />
|
<link href="{{scu.STATIC_DIR}}/css/gt_table.css" rel="stylesheet" type="text/css" />
|
||||||
|
<link type="text/css" rel="stylesheet" href="{{scu.STATIC_DIR}}/libjs/qtip/jquery.qtip-3.0.3.min.css" />
|
||||||
|
{#
|
||||||
|
<link href="{{scu.STATIC_DIR}}/css/tooltip.css" rel="stylesheet" type="text/css" /> #}
|
||||||
|
<link rel="stylesheet" type="text/css" href="{{scu.STATIC_DIR}}/DataTables/datatables.min.css" />
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block title %}
|
{% block title %}
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
{% extends 'sco_page.j2' %}
|
|
||||||
|
|
||||||
{% import 'wtf.j2' as wtf %}
|
{% import 'wtf.j2' as wtf %}
|
||||||
|
|
||||||
{% macro render_field(field) %}
|
{% macro render_field(field) %}
|
||||||
@ -17,12 +15,6 @@
|
|||||||
</tr>
|
</tr>
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|
||||||
{% block app_content %}
|
|
||||||
|
|
||||||
{{ evaluations_description|safe}}
|
|
||||||
|
|
||||||
<h3 class="space-before-24">Placement et émargement des étudiants</h3>
|
|
||||||
|
|
||||||
<div class="saisienote_etape1 form_placement">
|
<div class="saisienote_etape1 form_placement">
|
||||||
<form method=post>
|
<form method=post>
|
||||||
{{ form.evaluation_id }}
|
{{ form.evaluation_id }}
|
||||||
@ -86,4 +78,3 @@
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
|
@ -1,7 +1,5 @@
|
|||||||
{# -*- mode: jinja-html -*- #}
|
{# -*- mode: jinja-html -*- #}
|
||||||
{% extends "sco_page.j2" %}
|
{{ sco_header|safe }}
|
||||||
|
|
||||||
{% block app_content %}
|
|
||||||
<h2 class="formsemestre">Affectation aux groupes de {{ partition.partition_name }}</h2>
|
<h2 class="formsemestre">Affectation aux groupes de {{ partition.partition_name }}</h2>
|
||||||
|
|
||||||
<p class="help">
|
<p class="help">
|
||||||
@ -56,4 +54,4 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% endblock %}
|
{{ sco_footer|safe }}
|
@ -1,5 +1,5 @@
|
|||||||
{# -*- mode: jinja-html -*- #}
|
{# -*- mode: jinja-html -*- #}
|
||||||
{% extends 'sco_page.j2' %}
|
{% extends 'base.j2' %}
|
||||||
|
|
||||||
{% block app_content %}
|
{% block app_content %}
|
||||||
|
|
||||||
|
@ -24,8 +24,7 @@
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Module absences: remplacé par assiduité en août 2023,
|
Module absences: remplacé par assiduité en août 2023, reste ici seulement la gestion des "billets"
|
||||||
reste ici seulement la gestion des "billets"
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -33,7 +32,8 @@ import dateutil
|
|||||||
import dateutil.parser
|
import dateutil.parser
|
||||||
|
|
||||||
import flask
|
import flask
|
||||||
from flask import abort, flash, g, render_template, request, url_for
|
from flask import g, request
|
||||||
|
from flask import abort, flash, url_for
|
||||||
from flask_login import current_user
|
from flask_login import current_user
|
||||||
|
|
||||||
from app import db, log
|
from app import db, log
|
||||||
@ -54,8 +54,11 @@ from app.scodoc import sco_utils as scu
|
|||||||
from app.scodoc.sco_permissions import Permission
|
from app.scodoc.sco_permissions import Permission
|
||||||
from app.scodoc.sco_exceptions import ScoValueError
|
from app.scodoc.sco_exceptions import ScoValueError
|
||||||
from app.scodoc.TrivialFormulator import TrivialFormulator
|
from app.scodoc.TrivialFormulator import TrivialFormulator
|
||||||
|
from app.scodoc import html_sco_header
|
||||||
|
from app.scodoc import sco_cal
|
||||||
from app.scodoc import sco_assiduites as scass
|
from app.scodoc import sco_assiduites as scass
|
||||||
from app.scodoc import sco_abs_billets
|
from app.scodoc import sco_abs_billets
|
||||||
|
from app.scodoc import sco_etud
|
||||||
from app.scodoc import sco_preferences
|
from app.scodoc import sco_preferences
|
||||||
|
|
||||||
|
|
||||||
@ -74,7 +77,11 @@ from app.scodoc import sco_preferences
|
|||||||
def index_html():
|
def index_html():
|
||||||
"""Gestionnaire absences, page principale"""
|
"""Gestionnaire absences, page principale"""
|
||||||
|
|
||||||
H = []
|
H = [
|
||||||
|
html_sco_header.sco_header(
|
||||||
|
page_title="Billets d'absences",
|
||||||
|
),
|
||||||
|
]
|
||||||
if current_user.has_permission(
|
if current_user.has_permission(
|
||||||
Permission.AbsChange
|
Permission.AbsChange
|
||||||
) and sco_preferences.get_preference("handle_billets_abs"):
|
) and sco_preferences.get_preference("handle_billets_abs"):
|
||||||
@ -86,9 +93,8 @@ def index_html():
|
|||||||
</li></ul>
|
</li></ul>
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
return render_template(
|
H.append(html_sco_header.sco_footer())
|
||||||
"sco_page_dept.j2", title="Billets d'absences", content="\n".join(H)
|
return "\n".join(H)
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
# ----- Gestion des "billets d'absence": signalement par les etudiants eux mêmes (à travers le portail)
|
# ----- Gestion des "billets d'absence": signalement par les etudiants eux mêmes (à travers le portail)
|
||||||
@ -152,8 +158,12 @@ def add_billets_absence_form(etudid):
|
|||||||
"""Formulaire ajout billet (pour tests seulement, le vrai
|
"""Formulaire ajout billet (pour tests seulement, le vrai
|
||||||
formulaire accessible aux etudiants étant sur le portail étudiant).
|
formulaire accessible aux etudiants étant sur le portail étudiant).
|
||||||
"""
|
"""
|
||||||
_ = Identite.get_etud(etudid) # check
|
etud = sco_etud.get_etud_info(filled=True, etudid=etudid)[0]
|
||||||
H = ["""<h2>Formulaire ajout billet (pour tests)</h2>"""]
|
H = [
|
||||||
|
html_sco_header.sco_header(
|
||||||
|
page_title="Billet d'absence de %s" % etud["nomprenom"]
|
||||||
|
)
|
||||||
|
]
|
||||||
tf = TrivialFormulator(
|
tf = TrivialFormulator(
|
||||||
request.base_url,
|
request.base_url,
|
||||||
scu.get_request_args(),
|
scu.get_request_args(),
|
||||||
@ -169,11 +179,7 @@ def add_billets_absence_form(etudid):
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
if tf[0] == 0:
|
if tf[0] == 0:
|
||||||
return render_template(
|
return "\n".join(H) + tf[1] + html_sco_header.sco_footer()
|
||||||
"sco_page_dept.j2",
|
|
||||||
title="""Billet d'absence de {etud["nomprenom"]}""",
|
|
||||||
content="\n".join(H) + tf[1],
|
|
||||||
)
|
|
||||||
elif tf[0] == -1:
|
elif tf[0] == -1:
|
||||||
return flask.redirect(url_for("scolar.index_html", scodoc_dept=g.scodoc_dept))
|
return flask.redirect(url_for("scolar.index_html", scodoc_dept=g.scodoc_dept))
|
||||||
else:
|
else:
|
||||||
@ -236,8 +242,11 @@ def list_billets():
|
|||||||
et formulaire recherche d'un billet.
|
et formulaire recherche d'un billet.
|
||||||
"""
|
"""
|
||||||
table = sco_abs_billets.table_billets_etud(etat=False)
|
table = sco_abs_billets.table_billets_etud(etat=False)
|
||||||
table_html = table.html()
|
T = table.html()
|
||||||
H = [
|
H = [
|
||||||
|
html_sco_header.sco_header(
|
||||||
|
page_title="Billet d'absence non traités",
|
||||||
|
),
|
||||||
f"<h2>Billets d'absence en attente de traitement ({table.get_nb_rows()})</h2>",
|
f"<h2>Billets d'absence en attente de traitement ({table.get_nb_rows()})</h2>",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -248,18 +257,15 @@ def list_billets():
|
|||||||
submitbutton=False,
|
submitbutton=False,
|
||||||
)
|
)
|
||||||
if tf[0] == 0:
|
if tf[0] == 0:
|
||||||
return render_template(
|
return "\n".join(H) + tf[1] + T + html_sco_header.sco_footer()
|
||||||
"sco_page.j2",
|
else:
|
||||||
title="Billet d'absence non traités",
|
return flask.redirect(
|
||||||
content="\n".join(H) + tf[1] + table_html,
|
url_for(
|
||||||
|
"absences.process_billet_absence_form",
|
||||||
|
billet_id=tf[2]["billet_id"],
|
||||||
|
scodoc_dept=g.scodoc_dept,
|
||||||
|
)
|
||||||
)
|
)
|
||||||
return flask.redirect(
|
|
||||||
url_for(
|
|
||||||
"absences.process_billet_absence_form",
|
|
||||||
billet_id=tf[2]["billet_id"],
|
|
||||||
scodoc_dept=g.scodoc_dept,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/delete_billets_absence", methods=["POST", "GET"])
|
@bp.route("/delete_billets_absence", methods=["POST", "GET"])
|
||||||
@ -331,8 +337,7 @@ def _ProcessBilletAbsence(
|
|||||||
def process_billet_absence_form(billet_id: int):
|
def process_billet_absence_form(billet_id: int):
|
||||||
"""Formulaire traitement d'un billet"""
|
"""Formulaire traitement d'un billet"""
|
||||||
if not isinstance(billet_id, int):
|
if not isinstance(billet_id, int):
|
||||||
abort(404, "billet_id invalide")
|
raise abort(404, "billet_id invalide")
|
||||||
return # safety guard
|
|
||||||
billet: BilletAbsence = (
|
billet: BilletAbsence = (
|
||||||
BilletAbsence.query.filter_by(id=billet_id)
|
BilletAbsence.query.filter_by(id=billet_id)
|
||||||
.join(Identite)
|
.join(Identite)
|
||||||
@ -347,6 +352,9 @@ def process_billet_absence_form(billet_id: int):
|
|||||||
etud = billet.etudiant
|
etud = billet.etudiant
|
||||||
|
|
||||||
H = [
|
H = [
|
||||||
|
html_sco_header.sco_header(
|
||||||
|
page_title=f"Traitement billet d'absence de {etud.nomprenom}",
|
||||||
|
),
|
||||||
f"""<h2>Traitement du billet {billet.id} : <a class="discretelink" href="{
|
f"""<h2>Traitement du billet {billet.id} : <a class="discretelink" href="{
|
||||||
url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etud.id)
|
url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etud.id)
|
||||||
}">{etud.nomprenom}</a></h2>
|
}">{etud.nomprenom}</a></h2>
|
||||||
@ -395,11 +403,7 @@ def process_billet_absence_form(billet_id: int):
|
|||||||
</p>
|
</p>
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return render_template(
|
return "\n".join(H) + "<br>" + tf[1] + F + html_sco_header.sco_footer()
|
||||||
"sco_page.j2",
|
|
||||||
title=f"Traitement billet d'absence de {etud.nomprenom}",
|
|
||||||
content="\n".join(H) + "<br>" + tf[1] + F,
|
|
||||||
)
|
|
||||||
elif tf[0] == -1:
|
elif tf[0] == -1:
|
||||||
return flask.redirect(url_for("scolar.index_html", scodoc_dept=g.scodoc_dept))
|
return flask.redirect(url_for("scolar.index_html", scodoc_dept=g.scodoc_dept))
|
||||||
else:
|
else:
|
||||||
@ -410,7 +414,7 @@ def process_billet_absence_form(billet_id: int):
|
|||||||
j = "non justifiées"
|
j = "non justifiées"
|
||||||
H.append('<div class="head_message">')
|
H.append('<div class="head_message">')
|
||||||
if n > 0:
|
if n > 0:
|
||||||
H.append(f"{n} absences (1/2 journées) {j} ajoutées")
|
H.append("%d absences (1/2 journées) %s ajoutées" % (n, j))
|
||||||
elif n == 0:
|
elif n == 0:
|
||||||
H.append("Aucun jour d'absence dans les dates indiquées !")
|
H.append("Aucun jour d'absence dans les dates indiquées !")
|
||||||
elif n < 0:
|
elif n < 0:
|
||||||
@ -430,8 +434,4 @@ def process_billet_absence_form(billet_id: int):
|
|||||||
)
|
)
|
||||||
tab = sco_abs_billets.table_billets(billets, etud=etud)
|
tab = sco_abs_billets.table_billets(billets, etud=etud)
|
||||||
H.append(tab.html())
|
H.append(tab.html())
|
||||||
return render_template(
|
return "\n".join(H) + html_sco_header.sco_footer()
|
||||||
"sco_page.j2",
|
|
||||||
title=f"Traitement billet d'absence de {etud.nomprenom}",
|
|
||||||
content="\n".join(H),
|
|
||||||
)
|
|
||||||
|
@ -1073,10 +1073,10 @@ def signal_assiduites_group():
|
|||||||
select_all_when_unspecified=True,
|
select_all_when_unspecified=True,
|
||||||
)
|
)
|
||||||
if not groups_infos.members:
|
if not groups_infos.members:
|
||||||
return render_template(
|
return (
|
||||||
"sco_page.j2",
|
html_sco_header.sco_header(page_title="Saisie de l'assiduité")
|
||||||
title="Saisie de l'assiduité",
|
+ "<h3>Aucun étudiant ! </h3>"
|
||||||
content="<h3>Aucun étudiant !</h3>",
|
+ html_sco_header.sco_footer()
|
||||||
)
|
)
|
||||||
|
|
||||||
# --- Filtrage par formsemestre ---
|
# --- Filtrage par formsemestre ---
|
||||||
@ -1952,10 +1952,10 @@ def signal_assiduites_hebdo():
|
|||||||
group_ids, formsemestre_id=formsemestre.id, select_all_when_unspecified=True
|
group_ids, formsemestre_id=formsemestre.id, select_all_when_unspecified=True
|
||||||
)
|
)
|
||||||
if not groups_infos.members:
|
if not groups_infos.members:
|
||||||
return render_template(
|
return (
|
||||||
"sco_page.j2",
|
html_sco_header.sco_header(page_title="Assiduité: saisie hebdomadaire")
|
||||||
title="Assiduité: feuille saisie hebdomadaire",
|
+ "<h3>Aucun étudiant ! </h3>"
|
||||||
content="<h3>Aucun étudiant !</h3>",
|
+ html_sco_header.sco_footer()
|
||||||
)
|
)
|
||||||
|
|
||||||
# Récupération des étudiants
|
# Récupération des étudiants
|
||||||
@ -2305,10 +2305,12 @@ def feuille_abs_hebdo():
|
|||||||
group_ids, formsemestre_id=formsemestre.id, select_all_when_unspecified=True
|
group_ids, formsemestre_id=formsemestre.id, select_all_when_unspecified=True
|
||||||
)
|
)
|
||||||
if not groups_infos.members:
|
if not groups_infos.members:
|
||||||
return render_template(
|
return (
|
||||||
"sco_page.j2",
|
html_sco_header.sco_header(
|
||||||
title="Assiduité: feuille saisie hebdomadaire",
|
page_title="Assiduité: feuille saisie hebdomadaire"
|
||||||
content="<h3>Aucun étudiant !</h3>",
|
)
|
||||||
|
+ "<h3>Aucun étudiant ! </h3>"
|
||||||
|
+ html_sco_header.sco_footer()
|
||||||
)
|
)
|
||||||
|
|
||||||
# Gestion des jours
|
# Gestion des jours
|
||||||
|
@ -60,6 +60,7 @@ from app.models import (
|
|||||||
ScoDocSiteConfig,
|
ScoDocSiteConfig,
|
||||||
)
|
)
|
||||||
from app.scodoc import (
|
from app.scodoc import (
|
||||||
|
html_sco_header,
|
||||||
sco_bulletins_json,
|
sco_bulletins_json,
|
||||||
sco_cache,
|
sco_cache,
|
||||||
sco_formsemestre_exterieurs,
|
sco_formsemestre_exterieurs,
|
||||||
@ -250,23 +251,27 @@ def formsemestre_validation_but(
|
|||||||
</div>
|
</div>
|
||||||
"""
|
"""
|
||||||
|
|
||||||
H = ["""<div class="jury_but">"""]
|
H = [
|
||||||
inscription = formsemestre.etuds_inscriptions.get(etudid)
|
html_sco_header.sco_header(
|
||||||
if not inscription:
|
page_title=f"Validation BUT S{formsemestre.semestre_id}",
|
||||||
raise ScoValueError("étudiant non inscrit au semestre")
|
formsemestre_id=formsemestre_id,
|
||||||
if inscription.etat != scu.INSCRIT:
|
etudid=etudid,
|
||||||
return render_template(
|
|
||||||
"sco_page.j2",
|
|
||||||
title=f"Validation BUT S{formsemestre.semestre_id}",
|
|
||||||
sco=ScoData(etud=etud, formsemestre=formsemestre),
|
|
||||||
cssstyles=[
|
cssstyles=[
|
||||||
"css/jury_but.css",
|
"css/jury_but.css",
|
||||||
"css/cursus_but.css",
|
"css/cursus_but.css",
|
||||||
],
|
],
|
||||||
javascripts=("js/jury_but.js",),
|
javascripts=("js/jury_but.js",),
|
||||||
content=(
|
),
|
||||||
"\n".join(H)
|
"""<div class="jury_but">
|
||||||
+ f"""
|
""",
|
||||||
|
]
|
||||||
|
inscription = formsemestre.etuds_inscriptions.get(etudid)
|
||||||
|
if not inscription:
|
||||||
|
raise ScoValueError("étudiant non inscrit au semestre")
|
||||||
|
if inscription.etat != scu.INSCRIT:
|
||||||
|
return (
|
||||||
|
"\n".join(H)
|
||||||
|
+ f"""
|
||||||
<div>
|
<div>
|
||||||
<div class="bull_head">
|
<div class="bull_head">
|
||||||
<div>
|
<div>
|
||||||
@ -286,7 +291,7 @@ def formsemestre_validation_but(
|
|||||||
{navigation_div}
|
{navigation_div}
|
||||||
</div>
|
</div>
|
||||||
"""
|
"""
|
||||||
),
|
+ html_sco_header.sco_footer()
|
||||||
)
|
)
|
||||||
|
|
||||||
deca = jury_but.DecisionsProposeesAnnee(etud, formsemestre)
|
deca = jury_but.DecisionsProposeesAnnee(etud, formsemestre)
|
||||||
@ -336,7 +341,7 @@ def formsemestre_validation_but(
|
|||||||
êtes-vous certain de vouloir enregistrer une décision de jury ?
|
êtes-vous certain de vouloir enregistrer une décision de jury ?
|
||||||
</div>"""
|
</div>"""
|
||||||
if read_only:
|
if read_only:
|
||||||
warning += """<div class="warning">Affichage en lecture seule</div>"""
|
warning += f"""<div class="warning">Affichage en lecture seule</div>"""
|
||||||
|
|
||||||
if deca.formsemestre_impair:
|
if deca.formsemestre_impair:
|
||||||
inscription = deca.formsemestre_impair.etuds_inscriptions.get(etud.id)
|
inscription = deca.formsemestre_impair.etuds_inscriptions.get(etud.id)
|
||||||
@ -502,17 +507,7 @@ def formsemestre_validation_but(
|
|||||||
</div>
|
</div>
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
return render_template(
|
return "\n".join(H) + html_sco_header.sco_footer()
|
||||||
"sco_page.j2",
|
|
||||||
title=f"Validation BUT S{formsemestre.semestre_id}",
|
|
||||||
sco=ScoData(etud=etud, formsemestre=formsemestre),
|
|
||||||
cssstyles=[
|
|
||||||
"css/jury_but.css",
|
|
||||||
"css/cursus_but.css",
|
|
||||||
],
|
|
||||||
javascripts=("js/jury_but.js",),
|
|
||||||
content="\n".join(H),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@bp.route(
|
@bp.route(
|
||||||
|
@ -88,6 +88,7 @@ from app.scodoc.sco_exceptions import (
|
|||||||
ScoInvalidIdType,
|
ScoInvalidIdType,
|
||||||
)
|
)
|
||||||
from app.scodoc import (
|
from app.scodoc import (
|
||||||
|
html_sco_header,
|
||||||
sco_apogee_compare,
|
sco_apogee_compare,
|
||||||
sco_archives_formsemestre,
|
sco_archives_formsemestre,
|
||||||
sco_assiduites,
|
sco_assiduites,
|
||||||
@ -769,10 +770,8 @@ def formation_import_xml_form():
|
|||||||
cancelbutton="Annuler",
|
cancelbutton="Annuler",
|
||||||
)
|
)
|
||||||
if tf[0] == 0:
|
if tf[0] == 0:
|
||||||
return render_template(
|
return f"""
|
||||||
"sco_page_dept.j2",
|
{ html_sco_header.sco_header(page_title="Import d'une formation") }
|
||||||
title="Import d'une formation",
|
|
||||||
content=f"""
|
|
||||||
<h2>Import d'une formation</h2>
|
<h2>Import d'une formation</h2>
|
||||||
<p>Création d'une formation (avec UE, matières, modules)
|
<p>Création d'une formation (avec UE, matières, modules)
|
||||||
à partir un fichier XML (réservé aux utilisateurs avertis).
|
à partir un fichier XML (réservé aux utilisateurs avertis).
|
||||||
@ -784,8 +783,8 @@ def formation_import_xml_form():
|
|||||||
}">page des référentiels</a>).
|
}">page des référentiels</a>).
|
||||||
</p>
|
</p>
|
||||||
{ tf[1] }
|
{ tf[1] }
|
||||||
""",
|
{ html_sco_header.sco_footer() }
|
||||||
)
|
"""
|
||||||
elif tf[0] == -1:
|
elif tf[0] == -1:
|
||||||
return flask.redirect(url_for("notes.index_html", scodoc_dept=g.scodoc_dept))
|
return flask.redirect(url_for("notes.index_html", scodoc_dept=g.scodoc_dept))
|
||||||
else:
|
else:
|
||||||
@ -793,10 +792,8 @@ def formation_import_xml_form():
|
|||||||
tf[2]["xmlfile"].read()
|
tf[2]["xmlfile"].read()
|
||||||
)
|
)
|
||||||
|
|
||||||
return render_template(
|
return f"""
|
||||||
"sco_page_dept.j2",
|
{ html_sco_header.sco_header(page_title="Import d'une formation") }
|
||||||
title="Import d'une formation",
|
|
||||||
content=f"""
|
|
||||||
<h2>Import effectué !</h2>
|
<h2>Import effectué !</h2>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a class="stdlink" href="{
|
<li><a class="stdlink" href="{
|
||||||
@ -809,8 +806,8 @@ def formation_import_xml_form():
|
|||||||
(en cas d'erreur, par exemple pour charger auparavant le référentiel de compétences)
|
(en cas d'erreur, par exemple pour charger auparavant le référentiel de compétences)
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
""",
|
{ html_sco_header.sco_footer() }
|
||||||
)
|
"""
|
||||||
|
|
||||||
|
|
||||||
sco_publish("/module_move", sco_edit_formation.module_move, Permission.EditFormation)
|
sco_publish("/module_move", sco_edit_formation.module_move, Permission.EditFormation)
|
||||||
@ -2185,17 +2182,15 @@ def formsemestre_bulletins_mailetuds(
|
|||||||
if sent:
|
if sent:
|
||||||
nb_sent += 1
|
nb_sent += 1
|
||||||
#
|
#
|
||||||
return render_template(
|
return f"""
|
||||||
"sco_page.j2",
|
{html_sco_header.sco_header()}
|
||||||
title="Mailing bulletins",
|
|
||||||
content=f"""
|
|
||||||
<p>{nb_sent} bulletins sur {len(inscriptions)} envoyés par mail !</p>
|
<p>{nb_sent} bulletins sur {len(inscriptions)} envoyés par mail !</p>
|
||||||
<p><a class="stdlink" href="{url_for('notes.formsemestre_status',
|
<p><a class="stdlink" href="{url_for('notes.formsemestre_status',
|
||||||
scodoc_dept=g.scodoc_dept,
|
scodoc_dept=g.scodoc_dept,
|
||||||
formsemestre_id=formsemestre_id)
|
formsemestre_id=formsemestre_id)
|
||||||
}">continuer</a></p>
|
}">continuer</a></p>
|
||||||
""",
|
{html_sco_header.sco_footer()}
|
||||||
)
|
"""
|
||||||
|
|
||||||
|
|
||||||
sco_publish(
|
sco_publish(
|
||||||
@ -2263,8 +2258,10 @@ def appreciation_add_form(
|
|||||||
else:
|
else:
|
||||||
action = "Ajout"
|
action = "Ajout"
|
||||||
H = [
|
H = [
|
||||||
|
html_sco_header.sco_header(),
|
||||||
f"""<h2>{action} d'une appréciation sur {etud.nomprenom}</h2>""",
|
f"""<h2>{action} d'une appréciation sur {etud.nomprenom}</h2>""",
|
||||||
]
|
]
|
||||||
|
F = html_sco_header.sco_footer()
|
||||||
descr = [
|
descr = [
|
||||||
("edit", {"input_type": "hidden", "default": edit}),
|
("edit", {"input_type": "hidden", "default": edit}),
|
||||||
("etudid", {"input_type": "hidden"}),
|
("etudid", {"input_type": "hidden"}),
|
||||||
@ -2289,7 +2286,7 @@ def appreciation_add_form(
|
|||||||
submitlabel="Ajouter appréciation",
|
submitlabel="Ajouter appréciation",
|
||||||
)
|
)
|
||||||
if tf[0] == 0:
|
if tf[0] == 0:
|
||||||
return render_template("sco_page.j2", content="\n".join(H) + "\n" + tf[1])
|
return "\n".join(H) + "\n" + tf[1] + F
|
||||||
elif tf[0] == -1:
|
elif tf[0] == -1:
|
||||||
return flask.redirect(bul_url)
|
return flask.redirect(bul_url)
|
||||||
else:
|
else:
|
||||||
@ -2646,7 +2643,7 @@ def check_form_integrity(formation_id, fix=False):
|
|||||||
else:
|
else:
|
||||||
txth = "OK"
|
txth = "OK"
|
||||||
log("ok")
|
log("ok")
|
||||||
return render_template("sco_page.j2", content=txth)
|
return html_sco_header.sco_header() + txth + html_sco_header.sco_footer()
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/check_formsemestre_integrity")
|
@bp.route("/check_formsemestre_integrity")
|
||||||
@ -2684,4 +2681,6 @@ def check_formsemestre_integrity(formsemestre_id):
|
|||||||
else:
|
else:
|
||||||
diag = ["OK"]
|
diag = ["OK"]
|
||||||
log("ok")
|
log("ok")
|
||||||
return render_template("sco_page.j2", content="<br>".join(diag))
|
return (
|
||||||
|
html_sco_header.sco_header() + "<br>".join(diag) + html_sco_header.sco_footer()
|
||||||
|
)
|
||||||
|
@ -64,7 +64,7 @@ from app.decorators import (
|
|||||||
permission_required,
|
permission_required,
|
||||||
)
|
)
|
||||||
|
|
||||||
from app.scodoc import sco_import_users, sco_roles_default
|
from app.scodoc import html_sco_header, sco_import_users, sco_roles_default
|
||||||
from app.scodoc import sco_users
|
from app.scodoc import sco_users
|
||||||
from app.scodoc import sco_utils as scu
|
from app.scodoc import sco_utils as scu
|
||||||
from app.scodoc import sco_xml
|
from app.scodoc import sco_xml
|
||||||
@ -74,6 +74,7 @@ from app.scodoc.sco_import_users import generate_password
|
|||||||
from app.scodoc.sco_permissions_check import can_handle_passwd
|
from app.scodoc.sco_permissions_check import can_handle_passwd
|
||||||
from app.scodoc.TrivialFormulator import TrivialFormulator, tf_error_message
|
from app.scodoc.TrivialFormulator import TrivialFormulator, tf_error_message
|
||||||
from app.views import users_bp as bp
|
from app.views import users_bp as bp
|
||||||
|
from app.views import scodoc_bp
|
||||||
|
|
||||||
|
|
||||||
_ = lambda x: x # sans babel
|
_ = lambda x: x # sans babel
|
||||||
@ -91,7 +92,7 @@ class ChangePasswordForm(FlaskForm):
|
|||||||
validators=[
|
validators=[
|
||||||
EqualTo(
|
EqualTo(
|
||||||
"new_password",
|
"new_password",
|
||||||
message="Les deux saisies sont différentes, recommencez",
|
message="Les deux saisies sont " "différentes, recommencez",
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
@ -105,9 +106,9 @@ class ChangePasswordForm(FlaskForm):
|
|||||||
submit = SubmitField()
|
submit = SubmitField()
|
||||||
cancel = SubmitField("Annuler")
|
cancel = SubmitField("Annuler")
|
||||||
|
|
||||||
def validate_email(self, e_mail):
|
def validate_email(self, email):
|
||||||
"vérifie que le mail est unique (inline wtf validator)"
|
"vérifie que le mail est unique"
|
||||||
user = User.query.filter_by(email=e_mail.data.strip()).first()
|
user = User.query.filter_by(email=email.data.strip()).first()
|
||||||
if user is not None and self.user_name.data != user.user_name:
|
if user is not None and self.user_name.data != user.user_name:
|
||||||
raise ValidationError(
|
raise ValidationError(
|
||||||
_("Cette adresse e-mail est déjà attribuée à un autre compte")
|
_("Cette adresse e-mail est déjà attribuée à un autre compte")
|
||||||
@ -119,7 +120,6 @@ class ChangePasswordForm(FlaskForm):
|
|||||||
raise ValidationError("Mot de passe trop simple, recommencez")
|
raise ValidationError("Mot de passe trop simple, recommencez")
|
||||||
|
|
||||||
def validate_old_password(self, old_password):
|
def validate_old_password(self, old_password):
|
||||||
"vérifie password actuel"
|
|
||||||
if not current_user.check_password(old_password.data):
|
if not current_user.check_password(old_password.data):
|
||||||
raise ValidationError("Mot de passe actuel incorrect, ré-essayez")
|
raise ValidationError("Mot de passe actuel incorrect, ré-essayez")
|
||||||
|
|
||||||
@ -855,7 +855,9 @@ def import_users_generate_excel_sample():
|
|||||||
@scodoc7func
|
@scodoc7func
|
||||||
def import_users_form():
|
def import_users_form():
|
||||||
"""Import utilisateurs depuis feuille Excel"""
|
"""Import utilisateurs depuis feuille Excel"""
|
||||||
|
head = html_sco_header.sco_header(page_title="Import utilisateurs")
|
||||||
H = [
|
H = [
|
||||||
|
head,
|
||||||
"""<h2>Téléchargement d'une liste d'utilisateurs</h2>
|
"""<h2>Téléchargement d'une liste d'utilisateurs</h2>
|
||||||
<p style="color: red">A utiliser pour importer de <b>nouveaux</b>
|
<p style="color: red">A utiliser pour importer de <b>nouveaux</b>
|
||||||
utilisateurs (enseignants ou secrétaires)
|
utilisateurs (enseignants ou secrétaires)
|
||||||
@ -884,10 +886,12 @@ def import_users_form():
|
|||||||
<li><b>Étape 1: </b><a class="stdlink" href="{
|
<li><b>Étape 1: </b><a class="stdlink" href="{
|
||||||
url_for("users.import_users_generate_excel_sample", scodoc_dept=g.scodoc_dept)
|
url_for("users.import_users_generate_excel_sample", scodoc_dept=g.scodoc_dept)
|
||||||
}">Obtenir la feuille excel vide à remplir</a>
|
}">Obtenir la feuille excel vide à remplir</a>
|
||||||
|
ou bien la liste complète des utilisateurs.
|
||||||
</li>
|
</li>
|
||||||
<li><b> Étape 2:</b>
|
<li><b> Étape 2:</b>
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
F = html_sco_header.sco_footer()
|
||||||
tf = TrivialFormulator(
|
tf = TrivialFormulator(
|
||||||
request.base_url,
|
request.base_url,
|
||||||
scu.get_request_args(),
|
scu.get_request_args(),
|
||||||
@ -911,11 +915,7 @@ def import_users_form():
|
|||||||
submitlabel="Télécharger",
|
submitlabel="Télécharger",
|
||||||
)
|
)
|
||||||
if tf[0] == 0:
|
if tf[0] == 0:
|
||||||
return render_template(
|
return "\n".join(H) + tf[1] + "</li></ul>" + help_msg + F
|
||||||
"sco_page_dept.j2",
|
|
||||||
title="Import utilisateurs",
|
|
||||||
content="\n".join(H) + tf[1] + "</li></ul>" + help_msg,
|
|
||||||
)
|
|
||||||
elif tf[0] == -1:
|
elif tf[0] == -1:
|
||||||
return flask.redirect(url_for("scolar.index_html", docodc_dept=g.scodoc_dept))
|
return flask.redirect(url_for("scolar.index_html", docodc_dept=g.scodoc_dept))
|
||||||
|
|
||||||
@ -923,10 +923,8 @@ def import_users_form():
|
|||||||
ok, diags, nb_created = sco_import_users.import_excel_file(
|
ok, diags, nb_created = sco_import_users.import_excel_file(
|
||||||
tf[2]["xlsfile"], tf[2]["force"]
|
tf[2]["xlsfile"], tf[2]["force"]
|
||||||
)
|
)
|
||||||
H = [
|
H = [html_sco_header.sco_header(page_title="Import utilisateurs")]
|
||||||
"""<h2>Téléchargement d'une liste d'utilisateurs</h2>
|
H.append("<ul>")
|
||||||
<ul>"""
|
|
||||||
]
|
|
||||||
for diag in diags:
|
for diag in diags:
|
||||||
H.append(f"<li>{diag}</li>")
|
H.append(f"<li>{diag}</li>")
|
||||||
H.append("</ul>")
|
H.append("</ul>")
|
||||||
@ -944,9 +942,7 @@ def import_users_form():
|
|||||||
<p><a class="stdlink" href="{dest_url}">Continuer</a></p>
|
<p><a class="stdlink" href="{dest_url}">Continuer</a></p>
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
return render_template(
|
return "\n".join(H) + html_sco_header.sco_footer()
|
||||||
"sco_page_dept.j2", title="Import utilisateurs", content="\n".join(H)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/user_info_page")
|
@bp.route("/user_info_page")
|
||||||
@ -1065,6 +1061,76 @@ def form_change_password(user_name=None):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route("/change_password", methods=["POST"])
|
||||||
|
@scodoc
|
||||||
|
@permission_required(Permission.ScoView)
|
||||||
|
@scodoc7func
|
||||||
|
def change_password(user_name, password, password2):
|
||||||
|
"Change the password for user given by user_name"
|
||||||
|
if user_name is not None: # scodoc7func converti en int !
|
||||||
|
user_name = str(user_name)
|
||||||
|
u = User.query.filter_by(user_name=user_name).first()
|
||||||
|
# Check access permission
|
||||||
|
if not can_handle_passwd(u):
|
||||||
|
# access denied
|
||||||
|
log(
|
||||||
|
f"change_password: access denied (authuser={current_user}, user_name={user_name})"
|
||||||
|
)
|
||||||
|
raise AccessDenied("vous n'avez pas la permission de changer ce mot de passe")
|
||||||
|
H = []
|
||||||
|
F = html_sco_header.sco_footer()
|
||||||
|
# check password
|
||||||
|
dest_url = url_for(
|
||||||
|
"users.form_change_password", scodoc_dept=g.scodoc_dept, user_name=user_name
|
||||||
|
)
|
||||||
|
if password != password2:
|
||||||
|
H.append(
|
||||||
|
f"""<p>Les deux mots de passes saisis sont différents !</p>
|
||||||
|
<p><a href="{dest_url}" class="stdlink">Recommencer</a></p>
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
if not is_valid_password(password):
|
||||||
|
H.append(
|
||||||
|
f"""<p><b>ce mot de passe n'est pas assez compliqué !</b>
|
||||||
|
<br>(oui, il faut un mot de passe vraiment compliqué !)
|
||||||
|
</p>
|
||||||
|
<p><a href="{dest_url}" class="stdlink">Recommencer</a></p>
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
# ok, strong password
|
||||||
|
db.session.add(u)
|
||||||
|
u.set_password(password)
|
||||||
|
db.session.commit()
|
||||||
|
#
|
||||||
|
# ici page simplifiee car on peut ne plus avoir
|
||||||
|
# le droit d'acceder aux feuilles de style
|
||||||
|
return f"""<?xml version="1.0" encoding="{scu.SCO_ENCODING}"?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Mot de passe changé</title>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset={scu.SCO_ENCODING}" />
|
||||||
|
<body>
|
||||||
|
<h1>Mot de passe changé !</h1>
|
||||||
|
<h2>Changement effectué</h2>
|
||||||
|
<p>Ne notez pas ce mot de passe, mais mémorisez le !</p>
|
||||||
|
<p>Rappel: il est <b>interdit</b> de communiquer son mot de passe à
|
||||||
|
un tiers, même si c'est un collègue de confiance !</p>
|
||||||
|
<p><b>Si vous n'êtes pas administrateur, le système va vous redemander
|
||||||
|
votre login et nouveau mot de passe au prochain accès.</b>
|
||||||
|
</p>
|
||||||
|
<a href="{
|
||||||
|
url_for("scolar.index_html", scodoc_dept=g.scodoc_dept)
|
||||||
|
}" class="stdlink">Continuer</a>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
"""
|
||||||
|
|
||||||
|
return html_sco_header.sco_header() + "\n".join(H) + F
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/toggle_active_user/<user_name>", methods=["GET", "POST"])
|
@bp.route("/toggle_active_user/<user_name>", methods=["GET", "POST"])
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.UsersAdmin)
|
@permission_required(Permission.UsersAdmin)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# -*- mode: python -*-
|
# -*- mode: python -*-
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
SCOVERSION = "9.7.10"
|
SCOVERSION = "9.7.8"
|
||||||
|
|
||||||
SCONAME = "ScoDoc"
|
SCONAME = "ScoDoc"
|
||||||
|
|
||||||
|
0
tools/debian/prerm
Executable file → Normal file
0
tools/debian/prerm
Executable file → Normal file
@ -122,14 +122,3 @@ remove_install_status() {
|
|||||||
rm -f "${SCODOC_INSTALL_STATUS_FILE}"
|
rm -f "${SCODOC_INSTALL_STATUS_FILE}"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
#
|
|
||||||
alarm_admin() {
|
|
||||||
echo "Error: alarm_admin $1"
|
|
||||||
echo "Sending email to admin..."
|
|
||||||
echo "Subject: ScoDoc: $1" | mail -s "ScoDoc: $1" root <<EOF
|
|
||||||
|
|
||||||
Erreur lors de la mise à jour de ScoDoc sur $(hostname --fqdn)
|
|
||||||
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user