forked from ScoDoc/DocScoDoc
WIP migration vues en cours / tout est en vrac !
This commit is contained in:
parent
77f68d1c4c
commit
dcb53e9c35
21
README.md
21
README.md
@ -50,6 +50,27 @@ Installer le bon vieux `pyExcelerator` dans l'environnement:
|
|||||||
|
|
||||||
python -m unittest tests.test_users
|
python -m unittest tests.test_users
|
||||||
|
|
||||||
|
# Work in Progress
|
||||||
|
|
||||||
|
## Migration ZScolar
|
||||||
|
|
||||||
|
### Méthodes qui ne devraient plus être publiées:
|
||||||
|
security.declareProtected(ScoView, "get_preferences")
|
||||||
|
|
||||||
|
def get_preferences(context, formsemestre_id=None):
|
||||||
|
"Get preferences for this instance (a dict-like instance)"
|
||||||
|
return sco_preferences.sem_preferences(context, formsemestre_id)
|
||||||
|
|
||||||
|
security.declareProtected(ScoView, "get_preference")
|
||||||
|
|
||||||
|
def get_preference(context, name, formsemestre_id=None):
|
||||||
|
"""Returns value of named preference.
|
||||||
|
All preferences have a sensible default value (see sco_preferences.py),
|
||||||
|
this function always returns a usable value for all defined preferences names.
|
||||||
|
"""
|
||||||
|
return sco_preferences.get_base_preferences(context).get(formsemestre_id, name)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -904,15 +904,16 @@ class ZAbsences(
|
|||||||
etuds = [e for e in etuds if e["etudid"] in mod_inscrits]
|
etuds = [e for e in etuds if e["etudid"] in mod_inscrits]
|
||||||
if not moduleimpl_id:
|
if not moduleimpl_id:
|
||||||
moduleimpl_id = None
|
moduleimpl_id = None
|
||||||
base_url_noweeks = "SignaleAbsenceGrSemestre?datedebut=%s&datefin=%s&%s&destination=%s" % (
|
base_url_noweeks = (
|
||||||
datedebut,
|
"SignaleAbsenceGrSemestre?datedebut=%s&datefin=%s&%s&destination=%s"
|
||||||
datefin,
|
% (
|
||||||
groups_infos.groups_query_args,
|
datedebut,
|
||||||
urllib.quote(destination),
|
datefin,
|
||||||
|
groups_infos.groups_query_args,
|
||||||
|
urllib.quote(destination),
|
||||||
|
)
|
||||||
)
|
)
|
||||||
base_url = (
|
base_url = base_url_noweeks + "&nbweeks=%s" % nbweeks # sans le moduleimpl_id
|
||||||
base_url_noweeks + "&nbweeks=%s" % nbweeks
|
|
||||||
) # sans le moduleimpl_id
|
|
||||||
|
|
||||||
if etuds:
|
if etuds:
|
||||||
nt = self.Notes._getNotesCache().get_NotesTable(self.Notes, formsemestre_id)
|
nt = self.Notes._getNotesCache().get_NotesTable(self.Notes, formsemestre_id)
|
||||||
|
@ -557,7 +557,8 @@ def formsemestre_delete_archive(
|
|||||||
dest_url = "formsemestre_list_archives?formsemestre_id=%s" % (formsemestre_id)
|
dest_url = "formsemestre_list_archives?formsemestre_id=%s" % (formsemestre_id)
|
||||||
|
|
||||||
if not dialog_confirmed:
|
if not dialog_confirmed:
|
||||||
return context.confirmDialog(
|
return scu.confirm_dialog(
|
||||||
|
context,
|
||||||
"""<h2>Confirmer la suppression de l'archive du %s ?</h2>
|
"""<h2>Confirmer la suppression de l'archive du %s ?</h2>
|
||||||
<p>La suppression sera définitive.</p>"""
|
<p>La suppression sera définitive.</p>"""
|
||||||
% PVArchive.get_archive_date(archive_id).strftime("%d/%m/%Y %H:%M"),
|
% PVArchive.get_archive_date(archive_id).strftime("%d/%m/%Y %H:%M"),
|
||||||
|
@ -201,7 +201,8 @@ def etud_delete_archive(context, REQUEST, etudid, archive_name, dialog_confirmed
|
|||||||
archive_id = EtudsArchive.get_id_from_name(context, etudid, archive_name)
|
archive_id = EtudsArchive.get_id_from_name(context, etudid, archive_name)
|
||||||
dest_url = "ficheEtud?etudid=%s" % etudid
|
dest_url = "ficheEtud?etudid=%s" % etudid
|
||||||
if not dialog_confirmed:
|
if not dialog_confirmed:
|
||||||
return context.confirmDialog(
|
return scu.confirm_dialog(
|
||||||
|
context,
|
||||||
"""<h2>Confirmer la suppression des fichiers ?</h2>
|
"""<h2>Confirmer la suppression des fichiers ?</h2>
|
||||||
<p>Fichier associé le %s à l'étudiant %s</p>
|
<p>Fichier associé le %s à l'étudiant %s</p>
|
||||||
<p>La suppression sera définitive.</p>"""
|
<p>La suppression sera définitive.</p>"""
|
||||||
|
@ -65,7 +65,8 @@ def formation_delete(context, formation_id=None, dialog_confirmed=False, REQUEST
|
|||||||
H.append('</ul><p><a href="%s">Revenir</a></p>' % context.NotesURL())
|
H.append('</ul><p><a href="%s">Revenir</a></p>' % context.NotesURL())
|
||||||
else:
|
else:
|
||||||
if not dialog_confirmed:
|
if not dialog_confirmed:
|
||||||
return context.confirmDialog(
|
return scu.confirm_dialog(
|
||||||
|
context,
|
||||||
"""<h2>Confirmer la suppression de la formation %(titre)s (%(acronyme)s) ?</h2>
|
"""<h2>Confirmer la suppression de la formation %(titre)s (%(acronyme)s) ?</h2>
|
||||||
<p><b>Attention:</b> la suppression d'une formation est <b>irréversible</b> et implique la supression de toutes les UE, matières et modules de la formation !
|
<p><b>Attention:</b> la suppression d'une formation est <b>irréversible</b> et implique la supression de toutes les UE, matières et modules de la formation !
|
||||||
</p>
|
</p>
|
||||||
|
@ -267,7 +267,8 @@ def ue_delete(
|
|||||||
ue = ue[0]
|
ue = ue[0]
|
||||||
|
|
||||||
if not dialog_confirmed:
|
if not dialog_confirmed:
|
||||||
return context.confirmDialog(
|
return scu.confirm_dialog(
|
||||||
|
context,
|
||||||
"<h2>Suppression de l'UE %(titre)s (%(acronyme)s))</h2>" % ue,
|
"<h2>Suppression de l'UE %(titre)s (%(acronyme)s))</h2>" % ue,
|
||||||
dest_url="",
|
dest_url="",
|
||||||
REQUEST=REQUEST,
|
REQUEST=REQUEST,
|
||||||
|
@ -215,9 +215,9 @@ def apo_semset_maq_status(
|
|||||||
)
|
)
|
||||||
|
|
||||||
if apo_dups:
|
if apo_dups:
|
||||||
url_list = (
|
url_list = "view_apo_etuds?semset_id=%s&title=Doublons%%20Apogee&nips=%s" % (
|
||||||
"view_apo_etuds?semset_id=%s&title=Doublons%%20Apogee&nips=%s"
|
semset_id,
|
||||||
% (semset_id, "&nips=".join(apo_dups))
|
"&nips=".join(apo_dups),
|
||||||
)
|
)
|
||||||
H.append(
|
H.append(
|
||||||
'<li><a href="%s">%d étudiants</a> présents dans les <em>plusieurs</em> maquettes Apogée chargées</li>'
|
'<li><a href="%s">%d étudiants</a> présents dans les <em>plusieurs</em> maquettes Apogée chargées</li>'
|
||||||
@ -659,7 +659,8 @@ def view_apo_csv_delete(
|
|||||||
semset = sco_semset.SemSet(context, semset_id=semset_id)
|
semset = sco_semset.SemSet(context, semset_id=semset_id)
|
||||||
dest_url = "apo_semset_maq_status?semset_id=" + semset_id
|
dest_url = "apo_semset_maq_status?semset_id=" + semset_id
|
||||||
if not dialog_confirmed:
|
if not dialog_confirmed:
|
||||||
return context.confirmDialog(
|
return scu.confirm_dialog(
|
||||||
|
context,
|
||||||
"""<h2>Confirmer la suppression du fichier étape <tt>%s</tt>?</h2>
|
"""<h2>Confirmer la suppression du fichier étape <tt>%s</tt>?</h2>
|
||||||
<p>La suppression sera définitive.</p>"""
|
<p>La suppression sera définitive.</p>"""
|
||||||
% (etape_apo,),
|
% (etape_apo,),
|
||||||
|
@ -66,6 +66,12 @@ class FormatError(ScoValueError):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ScoInvalidDept(ScoValueError):
|
||||||
|
"""departement invalide"""
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class ScoConfigurationError(ScoValueError):
|
class ScoConfigurationError(ScoValueError):
|
||||||
"""Configuration invalid"""
|
"""Configuration invalid"""
|
||||||
|
|
||||||
|
@ -1129,7 +1129,8 @@ def formsemestre_associate_new_version(
|
|||||||
% (s["formsemestre_id"], checked, disabled, s["titremois"])
|
% (s["formsemestre_id"], checked, disabled, s["titremois"])
|
||||||
)
|
)
|
||||||
|
|
||||||
return context.confirmDialog(
|
return scu.confirm_dialog(
|
||||||
|
context,
|
||||||
"""<h2>Associer à une nouvelle version de formation non verrouillée ?</h2>
|
"""<h2>Associer à une nouvelle version de formation non verrouillée ?</h2>
|
||||||
<p>Le programme pédagogique ("formation") va être dupliqué pour que vous puissiez le modifier sans affecter les autres semestres. Les autres paramètres (étudiants, notes...) du semestre seront inchangés.</p>
|
<p>Le programme pédagogique ("formation") va être dupliqué pour que vous puissiez le modifier sans affecter les autres semestres. Les autres paramètres (étudiants, notes...) du semestre seront inchangés.</p>
|
||||||
<p>Veillez à ne pas abuser de cette possibilité, car créer trop de versions de formations va vous compliquer la gestion (à vous de garder trace des différences et à ne pas vous tromper par la suite...).
|
<p>Veillez à ne pas abuser de cette possibilité, car créer trop de versions de formations va vous compliquer la gestion (à vous de garder trace des différences et à ne pas vous tromper par la suite...).
|
||||||
@ -1280,7 +1281,8 @@ def formsemestre_delete2(
|
|||||||
"""Delete a formsemestre (confirmation)"""
|
"""Delete a formsemestre (confirmation)"""
|
||||||
# Confirmation dialog
|
# Confirmation dialog
|
||||||
if not dialog_confirmed:
|
if not dialog_confirmed:
|
||||||
return context.confirmDialog(
|
return scu.confirm_dialog(
|
||||||
|
context,
|
||||||
"""<h2>Vous voulez vraiment supprimer ce semestre ???</h2><p>(opération irréversible)</p>""",
|
"""<h2>Vous voulez vraiment supprimer ce semestre ???</h2><p>(opération irréversible)</p>""",
|
||||||
dest_url="",
|
dest_url="",
|
||||||
REQUEST=REQUEST,
|
REQUEST=REQUEST,
|
||||||
@ -1423,7 +1425,8 @@ def formsemestre_change_lock(
|
|||||||
msg = "déverrouillage"
|
msg = "déverrouillage"
|
||||||
else:
|
else:
|
||||||
msg = "verrouillage"
|
msg = "verrouillage"
|
||||||
return context.confirmDialog(
|
return scu.confirm_dialog(
|
||||||
|
context,
|
||||||
"<h2>Confirmer le %s du semestre ?</h2>" % msg,
|
"<h2>Confirmer le %s du semestre ?</h2>" % msg,
|
||||||
helpmsg="""Les notes d'un semestre verrouillé ne peuvent plus être modifiées.
|
helpmsg="""Les notes d'un semestre verrouillé ne peuvent plus être modifiées.
|
||||||
Un semestre verrouillé peut cependant être déverrouillé facilement à tout moment
|
Un semestre verrouillé peut cependant être déverrouillé facilement à tout moment
|
||||||
@ -1462,7 +1465,8 @@ def formsemestre_change_publication_bul(
|
|||||||
msg = "non"
|
msg = "non"
|
||||||
else:
|
else:
|
||||||
msg = ""
|
msg = ""
|
||||||
return context.confirmDialog(
|
return scu.confirm_dialog(
|
||||||
|
context,
|
||||||
"<h2>Confirmer la %s publication des bulletins ?</h2>" % msg,
|
"<h2>Confirmer la %s publication des bulletins ?</h2>" % msg,
|
||||||
helpmsg="""Il est parfois utile de désactiver la diffusion des bulletins,
|
helpmsg="""Il est parfois utile de désactiver la diffusion des bulletins,
|
||||||
par exemple pendant la tenue d'un jury ou avant harmonisation des notes.
|
par exemple pendant la tenue d'un jury ou avant harmonisation des notes.
|
||||||
|
@ -725,12 +725,130 @@ def formsemestre_lists(context, formsemestre_id, REQUEST=None):
|
|||||||
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
|
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
|
||||||
H = [
|
H = [
|
||||||
context.html_sem_header(REQUEST, "", sem),
|
context.html_sem_header(REQUEST, "", sem),
|
||||||
context.make_listes_sem(sem, REQUEST),
|
_make_listes_sem(context, sem, REQUEST),
|
||||||
context.sco_footer(REQUEST),
|
context.sco_footer(REQUEST),
|
||||||
]
|
]
|
||||||
return "\n".join(H)
|
return "\n".join(H)
|
||||||
|
|
||||||
|
|
||||||
|
# genere liste html pour accès aux groupes de ce semestre
|
||||||
|
# XXX #sco8 vérifier si c'est encore utilisé !
|
||||||
|
def _make_listes_sem(context, sem, REQUEST=None, with_absences=True):
|
||||||
|
context = context
|
||||||
|
authuser = REQUEST.AUTHENTICATED_USER
|
||||||
|
r = context.ScoURL() # root url
|
||||||
|
# construit l'URL "destination"
|
||||||
|
# (a laquelle on revient apres saisie absences)
|
||||||
|
query_args = cgi.parse_qs(REQUEST.QUERY_STRING)
|
||||||
|
if "head_message" in query_args:
|
||||||
|
del query_args["head_message"]
|
||||||
|
destination = "%s?%s" % (REQUEST.URL, urllib.urlencode(query_args, True))
|
||||||
|
destination = destination.replace(
|
||||||
|
"%", "%%"
|
||||||
|
) # car ici utilisee dans un format string !
|
||||||
|
|
||||||
|
#
|
||||||
|
H = []
|
||||||
|
# pas de menu absences si pas autorise:
|
||||||
|
if with_absences and not authuser.has_permission(ScoAbsChange, context):
|
||||||
|
with_absences = False
|
||||||
|
|
||||||
|
#
|
||||||
|
H.append(
|
||||||
|
'<h3>Listes de %(titre)s <span class="infostitresem">(%(mois_debut)s - %(mois_fin)s)</span></h3>'
|
||||||
|
% sem
|
||||||
|
)
|
||||||
|
|
||||||
|
formsemestre_id = sem["formsemestre_id"]
|
||||||
|
|
||||||
|
# calcule dates 1er jour semaine pour absences
|
||||||
|
try:
|
||||||
|
if with_absences:
|
||||||
|
first_monday = sco_abs.ddmmyyyy(sem["date_debut"]).prev_monday()
|
||||||
|
FA = [] # formulaire avec menu saisi absences
|
||||||
|
FA.append(
|
||||||
|
'<td><form action="Absences/SignaleAbsenceGrSemestre" method="get">'
|
||||||
|
)
|
||||||
|
FA.append(
|
||||||
|
'<input type="hidden" name="datefin" value="%(date_fin)s"/>' % sem
|
||||||
|
)
|
||||||
|
FA.append('<input type="hidden" name="group_ids" value="%(group_id)s"/>')
|
||||||
|
|
||||||
|
FA.append(
|
||||||
|
'<input type="hidden" name="destination" value="%s"/>' % destination
|
||||||
|
)
|
||||||
|
FA.append('<input type="submit" value="Saisir absences du" />')
|
||||||
|
FA.append('<select name="datedebut" class="noprint">')
|
||||||
|
date = first_monday
|
||||||
|
for jour in sco_abs.day_names(context):
|
||||||
|
FA.append('<option value="%s">%s</option>' % (date, jour))
|
||||||
|
date = date.next()
|
||||||
|
FA.append("</select>")
|
||||||
|
FA.append(
|
||||||
|
'<a href="Absences/EtatAbsencesGr?group_ids=%%(group_id)s&debut=%(date_debut)s&fin=%(date_fin)s">état</a>'
|
||||||
|
% sem
|
||||||
|
)
|
||||||
|
FA.append("</form></td>")
|
||||||
|
FormAbs = "\n".join(FA)
|
||||||
|
else:
|
||||||
|
FormAbs = ""
|
||||||
|
except ScoInvalidDateError: # dates incorrectes dans semestres ?
|
||||||
|
FormAbs = ""
|
||||||
|
#
|
||||||
|
H.append('<div id="grouplists">')
|
||||||
|
# Genere liste pour chaque partition (categorie de groupes)
|
||||||
|
for partition in sco_groups.get_partitions_list(context, sem["formsemestre_id"]):
|
||||||
|
if not partition["partition_name"]:
|
||||||
|
H.append("<h4>Tous les étudiants</h4>" % partition)
|
||||||
|
else:
|
||||||
|
H.append("<h4>Groupes de %(partition_name)s</h4>" % partition)
|
||||||
|
groups = sco_groups.get_partition_groups(context, partition)
|
||||||
|
if groups:
|
||||||
|
H.append("<table>")
|
||||||
|
for group in groups:
|
||||||
|
n_members = len(
|
||||||
|
sco_groups.get_group_members(context, group["group_id"])
|
||||||
|
)
|
||||||
|
group["url"] = r
|
||||||
|
if group["group_name"]:
|
||||||
|
group["label"] = "groupe %(group_name)s" % group
|
||||||
|
else:
|
||||||
|
group["label"] = "liste"
|
||||||
|
H.append('<tr class="listegroupelink">')
|
||||||
|
H.append(
|
||||||
|
"""<td>
|
||||||
|
<a href="%(url)s/groups_view?group_ids=%(group_id)s">%(label)s</a>
|
||||||
|
</td><td>
|
||||||
|
(<a href="%(url)s/groups_view?group_ids=%(group_id)s&format=xls">format tableur</a>)
|
||||||
|
<a href="%(url)s/groups_view?curtab=tab-photos&group_ids=%(group_id)s&etat=I">Photos</a>
|
||||||
|
</td>"""
|
||||||
|
% group
|
||||||
|
)
|
||||||
|
H.append("<td>(%d étudiants)</td>" % n_members)
|
||||||
|
|
||||||
|
if with_absences:
|
||||||
|
H.append(FormAbs % group)
|
||||||
|
|
||||||
|
H.append("</tr>")
|
||||||
|
H.append("</table>")
|
||||||
|
else:
|
||||||
|
H.append('<p class="help indent">Aucun groupe dans cette partition')
|
||||||
|
if sco_groups.can_change_groups(context, REQUEST, formsemestre_id):
|
||||||
|
H.append(
|
||||||
|
' (<a href="affectGroups?partition_id=%s" class="stdlink">créer</a>)'
|
||||||
|
% partition["partition_id"]
|
||||||
|
)
|
||||||
|
H.append("</p>")
|
||||||
|
if sco_groups.can_change_groups(context, REQUEST, formsemestre_id):
|
||||||
|
H.append(
|
||||||
|
'<h4><a href="editPartitionForm?formsemestre_id=%s">Ajouter une partition</a></h4>'
|
||||||
|
% formsemestre_id
|
||||||
|
)
|
||||||
|
|
||||||
|
H.append("</div>")
|
||||||
|
return "\n".join(H)
|
||||||
|
|
||||||
|
|
||||||
def html_expr_diagnostic(context, diagnostics):
|
def html_expr_diagnostic(context, diagnostics):
|
||||||
"""Affiche messages d'erreur des formules utilisateurs"""
|
"""Affiche messages d'erreur des formules utilisateurs"""
|
||||||
H = []
|
H = []
|
||||||
|
@ -973,7 +973,8 @@ def partition_delete(
|
|||||||
grnames = "(" + ", ".join([g["group_name"] or "" for g in groups]) + ")"
|
grnames = "(" + ", ".join([g["group_name"] or "" for g in groups]) + ")"
|
||||||
else:
|
else:
|
||||||
grnames = ""
|
grnames = ""
|
||||||
return context.confirmDialog(
|
return scu.confirm_dialog(
|
||||||
|
context,
|
||||||
"""<h2>Supprimer la partition "%s" ?</h2>
|
"""<h2>Supprimer la partition "%s" ?</h2>
|
||||||
<p>Les groupes %s de cette partition seront supprimés</p>
|
<p>Les groupes %s de cette partition seront supprimés</p>
|
||||||
"""
|
"""
|
||||||
|
@ -340,7 +340,8 @@ def formsemestre_inscr_passage(
|
|||||||
if not a_inscrire and not a_desinscrire:
|
if not a_inscrire and not a_desinscrire:
|
||||||
H.append("""<h3>Il n'y a rien à modifier !</h3>""")
|
H.append("""<h3>Il n'y a rien à modifier !</h3>""")
|
||||||
H.append(
|
H.append(
|
||||||
context.confirmDialog(
|
scu.confirm_dialog(
|
||||||
|
context,
|
||||||
dest_url="formsemestre_inscr_passage",
|
dest_url="formsemestre_inscr_passage",
|
||||||
add_headers=False,
|
add_headers=False,
|
||||||
cancel_url="formsemestre_inscr_passage?formsemestre_id="
|
cancel_url="formsemestre_inscr_passage?formsemestre_id="
|
||||||
|
@ -150,13 +150,27 @@ def _flatten_info(info):
|
|||||||
return ids
|
return ids
|
||||||
|
|
||||||
|
|
||||||
|
def _getEtudInfoGroupes(context, group_ids, etat=None):
|
||||||
|
"""liste triée d'infos (dict) sur les etudiants du groupe indiqué.
|
||||||
|
Attention: lent, car plusieurs requetes SQL par etudiant !
|
||||||
|
"""
|
||||||
|
etuds = []
|
||||||
|
for group_id in group_ids:
|
||||||
|
members = sco_groups.get_group_members(context, group_id, etat=etat)
|
||||||
|
for m in members:
|
||||||
|
etud = context.getEtudInfo(etudid=m["etudid"], filled=True)[0]
|
||||||
|
etuds.append(etud)
|
||||||
|
|
||||||
|
return etuds
|
||||||
|
|
||||||
|
|
||||||
def formsemestre_poursuite_report(
|
def formsemestre_poursuite_report(
|
||||||
context, formsemestre_id, format="html", REQUEST=None
|
context, formsemestre_id, format="html", REQUEST=None
|
||||||
):
|
):
|
||||||
"""Table avec informations "poursuite" """
|
"""Table avec informations "poursuite" """
|
||||||
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
|
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
|
||||||
etuds = context.getEtudInfoGroupes(
|
etuds = _getEtudInfoGroupes(
|
||||||
[sco_groups.get_default_group(context, formsemestre_id)]
|
context, [sco_groups.get_default_group(context, formsemestre_id)]
|
||||||
)
|
)
|
||||||
|
|
||||||
infos = []
|
infos = []
|
||||||
|
@ -88,11 +88,22 @@ def formsemestre_etuds_stats(context, sem, only_primo=False):
|
|||||||
bs.append(etud["specialite"])
|
bs.append(etud["specialite"])
|
||||||
etud["bac-specialite"] = " ".join(bs)
|
etud["bac-specialite"] = " ".join(bs)
|
||||||
#
|
#
|
||||||
if (not only_primo) or context.isPrimoEtud(etud, sem):
|
if (not only_primo) or is_primo_etud(context, etud, sem):
|
||||||
etuds.append(etud)
|
etuds.append(etud)
|
||||||
return etuds
|
return etuds
|
||||||
|
|
||||||
|
|
||||||
|
def is_primo_etud(context, etud, sem):
|
||||||
|
"""Determine si un (filled) etud a ete inscrit avant ce semestre.
|
||||||
|
Regarde la liste des semestres dans lesquels l'étudiant est inscrit
|
||||||
|
"""
|
||||||
|
now = sem["dateord"]
|
||||||
|
for s in etud["sems"]: # le + recent d'abord
|
||||||
|
if s["dateord"] < now:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
def _categories_and_results(etuds, category, result):
|
def _categories_and_results(etuds, category, result):
|
||||||
categories = {}
|
categories = {}
|
||||||
results = {}
|
results = {}
|
||||||
@ -416,7 +427,7 @@ def table_suivi_cohorte(
|
|||||||
and (not annee_bac or (annee_bac == str(etud["annee_bac"])))
|
and (not annee_bac or (annee_bac == str(etud["annee_bac"])))
|
||||||
and (not civilite or (civilite == etud["civilite"]))
|
and (not civilite or (civilite == etud["civilite"]))
|
||||||
and (not statut or (statut == etud["statut"]))
|
and (not statut or (statut == etud["statut"]))
|
||||||
and (not only_primo or context.isPrimoEtud(etud, sem))
|
and (not only_primo or is_primo_etud(context, etud, sem))
|
||||||
):
|
):
|
||||||
orig_set.add(etudid)
|
orig_set.add(etudid)
|
||||||
# semestres suivants:
|
# semestres suivants:
|
||||||
@ -708,14 +719,16 @@ def formsemestre_suivi_cohorte(
|
|||||||
return t
|
return t
|
||||||
|
|
||||||
base_url = REQUEST.URL0
|
base_url = REQUEST.URL0
|
||||||
burl = (
|
burl = "%s?formsemestre_id=%s&bac=%s&bacspecialite=%s&civilite=%s&statut=%s" % (
|
||||||
"%s?formsemestre_id=%s&bac=%s&bacspecialite=%s&civilite=%s&statut=%s"
|
base_url,
|
||||||
% (base_url, formsemestre_id, bac, bacspecialite, civilite, statut)
|
formsemestre_id,
|
||||||
|
bac,
|
||||||
|
bacspecialite,
|
||||||
|
civilite,
|
||||||
|
statut,
|
||||||
)
|
)
|
||||||
if percent:
|
if percent:
|
||||||
pplink = (
|
pplink = '<p><a href="%s&percent=0">Afficher les résultats bruts</a></p>' % burl
|
||||||
'<p><a href="%s&percent=0">Afficher les résultats bruts</a></p>' % burl
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
pplink = (
|
pplink = (
|
||||||
'<p><a href="%s&percent=1">Afficher les résultats en pourcentages</a></p>'
|
'<p><a href="%s&percent=1">Afficher les résultats en pourcentages</a></p>'
|
||||||
@ -1028,7 +1041,7 @@ def tsp_etud_list(
|
|||||||
and (not annee_bac or (annee_bac == str(etud["annee_bac"])))
|
and (not annee_bac or (annee_bac == str(etud["annee_bac"])))
|
||||||
and (not civilite or (civilite == etud["civilite"]))
|
and (not civilite or (civilite == etud["civilite"]))
|
||||||
and (not statut or (statut == etud["statut"]))
|
and (not statut or (statut == etud["statut"]))
|
||||||
and (not only_primo or context.isPrimoEtud(etud, sem))
|
and (not only_primo or is_primo_etud(context, etud, sem))
|
||||||
):
|
):
|
||||||
etuds.append(etud)
|
etuds.append(etud)
|
||||||
|
|
||||||
|
@ -349,7 +349,8 @@ def do_evaluation_set_missing(
|
|||||||
)
|
)
|
||||||
# Confirm action
|
# Confirm action
|
||||||
if not dialog_confirmed:
|
if not dialog_confirmed:
|
||||||
return context.confirmDialog(
|
return scu.confirm_dialog(
|
||||||
|
context,
|
||||||
"""<h2>Mettre toutes les notes manquantes de l'évaluation
|
"""<h2>Mettre toutes les notes manquantes de l'évaluation
|
||||||
à la valeur %s ?</h2>
|
à la valeur %s ?</h2>
|
||||||
<p>Seuls les étudiants pour lesquels aucune note (ni valeur, ni ABS, ni EXC)
|
<p>Seuls les étudiants pour lesquels aucune note (ni valeur, ni ABS, ni EXC)
|
||||||
@ -418,7 +419,8 @@ def evaluation_suppress_alln(context, evaluation_id, REQUEST, dialog_confirmed=F
|
|||||||
msg = "<p>Confirmer la suppression des %d notes ?</p>" % nb_suppress
|
msg = "<p>Confirmer la suppression des %d notes ?</p>" % nb_suppress
|
||||||
if existing_decisions:
|
if existing_decisions:
|
||||||
msg += """<p class="warning">Important: il y a déjà des décisions de jury enregistrées, qui seront potentiellement à revoir suite à cette modification !</p>"""
|
msg += """<p class="warning">Important: il y a déjà des décisions de jury enregistrées, qui seront potentiellement à revoir suite à cette modification !</p>"""
|
||||||
return context.confirmDialog(
|
return scu.confirm_dialog(
|
||||||
|
context,
|
||||||
msg,
|
msg,
|
||||||
dest_url="",
|
dest_url="",
|
||||||
REQUEST=REQUEST,
|
REQUEST=REQUEST,
|
||||||
|
@ -362,7 +362,8 @@ def do_semset_delete(context, semset_id, dialog_confirmed=False, REQUEST=None):
|
|||||||
raise ScoValueError("empty semset_id")
|
raise ScoValueError("empty semset_id")
|
||||||
s = SemSet(context, semset_id=semset_id)
|
s = SemSet(context, semset_id=semset_id)
|
||||||
if not dialog_confirmed:
|
if not dialog_confirmed:
|
||||||
return context.confirmDialog(
|
return scu.confirm_dialog(
|
||||||
|
context,
|
||||||
"<h2>Suppression de l'ensemble %(title)s ?</h2>" % s,
|
"<h2>Suppression de l'ensemble %(title)s ?</h2>" % s,
|
||||||
dest_url="",
|
dest_url="",
|
||||||
REQUEST=REQUEST,
|
REQUEST=REQUEST,
|
||||||
|
@ -205,7 +205,8 @@ def formsemestre_synchro_etuds(
|
|||||||
H.append("""<h3>Il n'y a rien à modifier !</h3>""")
|
H.append("""<h3>Il n'y a rien à modifier !</h3>""")
|
||||||
|
|
||||||
H.append(
|
H.append(
|
||||||
context.confirmDialog(
|
scu.confirm_dialog(
|
||||||
|
context,
|
||||||
dest_url="formsemestre_synchro_etuds",
|
dest_url="formsemestre_synchro_etuds",
|
||||||
add_headers=False,
|
add_headers=False,
|
||||||
cancel_url="formsemestre_synchro_etuds?formsemestre_id="
|
cancel_url="formsemestre_synchro_etuds?formsemestre_id="
|
||||||
|
@ -185,12 +185,12 @@ def check_local_photos_availability(context, groups_infos, REQUEST, format=""):
|
|||||||
parameters = {"group_ids": groups_infos.group_ids, "format": format}
|
parameters = {"group_ids": groups_infos.group_ids, "format": format}
|
||||||
return (
|
return (
|
||||||
False,
|
False,
|
||||||
context.confirmDialog(
|
scu.confirm_dialog(
|
||||||
|
context,
|
||||||
"""<p>Attention: %d photos ne sont pas disponibles et ne peuvent pas être exportées.</p><p>Vous pouvez <a class="stdlink" href="%s">exporter seulement les photos existantes</a>"""
|
"""<p>Attention: %d photos ne sont pas disponibles et ne peuvent pas être exportées.</p><p>Vous pouvez <a class="stdlink" href="%s">exporter seulement les photos existantes</a>"""
|
||||||
% (
|
% (
|
||||||
nb_missing,
|
nb_missing,
|
||||||
groups_infos.base_url
|
groups_infos.base_url + "&dialog_confirmed=1&format=%s" % format,
|
||||||
+ "&dialog_confirmed=1&format=%s" % format,
|
|
||||||
),
|
),
|
||||||
dest_url="trombino",
|
dest_url="trombino",
|
||||||
OK="Exporter seulement les photos existantes",
|
OK="Exporter seulement les photos existantes",
|
||||||
@ -252,7 +252,8 @@ def trombino_copy_photos(context, group_ids=[], REQUEST=None, dialog_confirmed=F
|
|||||||
+ footer
|
+ footer
|
||||||
)
|
)
|
||||||
if not dialog_confirmed:
|
if not dialog_confirmed:
|
||||||
return context.confirmDialog(
|
return scu.confirm_dialog(
|
||||||
|
context,
|
||||||
"""<h2>Copier les photos du portail vers ScoDoc ?</h2>
|
"""<h2>Copier les photos du portail vers ScoDoc ?</h2>
|
||||||
<p>Les photos du groupe %s présentes dans ScoDoc seront remplacées par celles du portail (si elles existent).</p>
|
<p>Les photos du groupe %s présentes dans ScoDoc seront remplacées par celles du portail (si elles existent).</p>
|
||||||
<p>(les photos sont normalement automatiquement copiées lors de leur première utilisation, l'usage de cette fonction n'est nécessaire que si les photos du portail ont été modifiées)</p>
|
<p>(les photos sont normalement automatiquement copiées lors de leur première utilisation, l'usage de cette fonction n'est nécessaire que si les photos du portail ont été modifiées)</p>
|
||||||
|
@ -840,7 +840,25 @@ def log_unknown_etud(context, REQUEST=None, format="html"):
|
|||||||
"unknown student: etudid=%s code_nip=%s code_ine=%s"
|
"unknown student: etudid=%s code_nip=%s code_ine=%s"
|
||||||
% (etudid, code_nip, code_ine)
|
% (etudid, code_nip, code_ine)
|
||||||
)
|
)
|
||||||
return context.ScoErrorResponse("unknown student", format=format, REQUEST=REQUEST)
|
return _sco_error_response("unknown student", format=format, REQUEST=REQUEST)
|
||||||
|
|
||||||
|
|
||||||
|
# XXX #sco8 à tester ou ré-écrire
|
||||||
|
def _sco_error_response(context, msg, format="html", REQUEST=None):
|
||||||
|
"""Send an error message to the client, in html or xml format."""
|
||||||
|
REQUEST.RESPONSE.setStatus(404, reason=msg)
|
||||||
|
if format == "html" or format == "pdf":
|
||||||
|
raise ScoValueError(msg)
|
||||||
|
elif format == "xml":
|
||||||
|
REQUEST.RESPONSE.setHeader("content-type", scu.XML_MIMETYPE)
|
||||||
|
doc = jaxml.XML_document(encoding=scu.SCO_ENCODING)
|
||||||
|
doc.error(msg=msg)
|
||||||
|
return repr(doc)
|
||||||
|
elif format == "json":
|
||||||
|
REQUEST.RESPONSE.setHeader("content-type", scu.JSON_MIMETYPE)
|
||||||
|
return "undefined" # XXX voir quoi faire en cas d'erreur json
|
||||||
|
else:
|
||||||
|
raise ValueError("ScoErrorResponse: invalid format")
|
||||||
|
|
||||||
|
|
||||||
# XXX
|
# XXX
|
||||||
@ -869,3 +887,55 @@ def return_text_if_published(val, REQUEST):
|
|||||||
if REQUEST and not isinstance(val, STRING_TYPES):
|
if REQUEST and not isinstance(val, STRING_TYPES):
|
||||||
return sendJSON(REQUEST, val)
|
return sendJSON(REQUEST, val)
|
||||||
return val
|
return val
|
||||||
|
|
||||||
|
|
||||||
|
def confirm_dialog(
|
||||||
|
context,
|
||||||
|
message="<p>Confirmer ?</p>",
|
||||||
|
OK="OK",
|
||||||
|
Cancel="Annuler",
|
||||||
|
dest_url="",
|
||||||
|
cancel_url="",
|
||||||
|
target_variable="dialog_confirmed",
|
||||||
|
parameters={},
|
||||||
|
add_headers=True, # complete page
|
||||||
|
REQUEST=None, # required
|
||||||
|
helpmsg=None,
|
||||||
|
):
|
||||||
|
# dialog de confirmation simple
|
||||||
|
parameters[target_variable] = 1
|
||||||
|
# Attention: la page a pu etre servie en GET avec des parametres
|
||||||
|
# si on laisse l'url "action" vide, les parametres restent alors que l'on passe en POST...
|
||||||
|
if not dest_url:
|
||||||
|
dest_url = REQUEST.URL
|
||||||
|
# strip remaining parameters from destination url:
|
||||||
|
dest_url = urllib.splitquery(dest_url)[0]
|
||||||
|
H = [
|
||||||
|
"""<form action="%s" method="post">""" % dest_url,
|
||||||
|
message,
|
||||||
|
"""<input type="submit" value="%s"/>""" % OK,
|
||||||
|
]
|
||||||
|
if cancel_url:
|
||||||
|
H.append(
|
||||||
|
"""<input type ="button" value="%s"
|
||||||
|
onClick="document.location='%s';"/>"""
|
||||||
|
% (Cancel, cancel_url)
|
||||||
|
)
|
||||||
|
for param in parameters.keys():
|
||||||
|
if parameters[param] is None:
|
||||||
|
parameters[param] = ""
|
||||||
|
if type(parameters[param]) == type([]):
|
||||||
|
for e in parameters[param]:
|
||||||
|
H.append('<input type="hidden" name="%s" value="%s"/>' % (param, e))
|
||||||
|
else:
|
||||||
|
H.append(
|
||||||
|
'<input type="hidden" name="%s" value="%s"/>'
|
||||||
|
% (param, parameters[param])
|
||||||
|
)
|
||||||
|
H.append("</form>")
|
||||||
|
if helpmsg:
|
||||||
|
H.append('<p class="help">' + helpmsg + "</p>")
|
||||||
|
if add_headers and REQUEST:
|
||||||
|
return context.sco_header(REQUEST) + "\n".join(H) + context.sco_footer(REQUEST)
|
||||||
|
else:
|
||||||
|
return "\n".join(H)
|
||||||
|
@ -357,7 +357,8 @@ def _check_duplicate_code(cnx, args, code_name, context, edit=True, REQUEST=None
|
|||||||
dest_url = ""
|
dest_url = ""
|
||||||
parameters = {}
|
parameters = {}
|
||||||
if context:
|
if context:
|
||||||
err_page = context.confirmDialog(
|
err_page = scu.confirm_dialog(
|
||||||
|
context,
|
||||||
message="""<h3>Code étudiant (%s) dupliqué !</h3>""" % code_name,
|
message="""<h3>Code étudiant (%s) dupliqué !</h3>""" % code_name,
|
||||||
helpmsg="""Le %s %s est déjà utilisé: un seul étudiant peut avoir ce code. Vérifier votre valeur ou supprimer l'autre étudiant avec cette valeur.<p><ul><li>"""
|
helpmsg="""Le %s %s est déjà utilisé: un seul étudiant peut avoir ce code. Vérifier votre valeur ou supprimer l'autre étudiant avec cette valeur.<p><ul><li>"""
|
||||||
% (code_name, args[code_name])
|
% (code_name, args[code_name])
|
||||||
@ -866,3 +867,171 @@ for l in f:
|
|||||||
|
|
||||||
o.close()
|
o.close()
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def list_scolog(context, etudid):
|
||||||
|
"liste des operations effectuees sur cet etudiant"
|
||||||
|
cnx = context.GetDBConnexion()
|
||||||
|
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
|
||||||
|
cursor.execute(
|
||||||
|
"select * from scolog where etudid=%(etudid)s ORDER BY DATE DESC",
|
||||||
|
{"etudid": etudid},
|
||||||
|
)
|
||||||
|
return cursor.dictfetchall()
|
||||||
|
|
||||||
|
|
||||||
|
def fillEtudsInfo(context, etuds):
|
||||||
|
"""etuds est une liste d'etudiants (mappings)
|
||||||
|
Pour chaque etudiant, ajoute ou formatte les champs
|
||||||
|
-> informations pour fiche etudiant ou listes diverses
|
||||||
|
"""
|
||||||
|
cnx = context.GetDBConnexion()
|
||||||
|
# open('/tmp/t','w').write( str(etuds) )
|
||||||
|
for etud in etuds:
|
||||||
|
etudid = etud["etudid"]
|
||||||
|
etud["dept"] = context.DeptId()
|
||||||
|
adrs = adresse_list(cnx, {"etudid": etudid})
|
||||||
|
if not adrs:
|
||||||
|
# certains "vieux" etudiants n'ont pas d'adresse
|
||||||
|
adr = {}.fromkeys(_adresseEditor.dbfields, "")
|
||||||
|
adr["etudid"] = etudid
|
||||||
|
else:
|
||||||
|
adr = adrs[0]
|
||||||
|
if len(adrs) > 1:
|
||||||
|
log("fillEtudsInfo: etudid=%s a %d adresses" % (etudid, len(adrs)))
|
||||||
|
etud.update(adr)
|
||||||
|
format_etud_ident(etud)
|
||||||
|
|
||||||
|
# Semestres dans lesquel il est inscrit
|
||||||
|
ins = context.Notes.do_formsemestre_inscription_list({"etudid": etudid})
|
||||||
|
etud["ins"] = ins
|
||||||
|
sems = []
|
||||||
|
cursem = None # semestre "courant" ou il est inscrit
|
||||||
|
for i in ins:
|
||||||
|
sem = sco_formsemestre.get_formsemestre(context, i["formsemestre_id"])
|
||||||
|
if sco_formsemestre.sem_est_courant(context, sem):
|
||||||
|
cursem = sem
|
||||||
|
curi = i
|
||||||
|
sem["ins"] = i
|
||||||
|
sems.append(sem)
|
||||||
|
# trie les semestres par date de debut, le plus recent d'abord
|
||||||
|
# (important, ne pas changer (suivi cohortes))
|
||||||
|
sems.sort(lambda x, y: cmp(y["dateord"], x["dateord"]))
|
||||||
|
etud["sems"] = sems
|
||||||
|
etud["cursem"] = cursem
|
||||||
|
if cursem:
|
||||||
|
etud["inscription"] = cursem["titremois"]
|
||||||
|
etud["inscriptionstr"] = "Inscrit en " + cursem["titremois"]
|
||||||
|
etud["inscription_formsemestre_id"] = cursem["formsemestre_id"]
|
||||||
|
etud["etatincursem"] = curi["etat"]
|
||||||
|
etud["situation"] = descr_situation_etud(context, etudid, etud["ne"])
|
||||||
|
# XXX est-ce utile ? sco_groups.etud_add_group_infos(context, etud, cursem)
|
||||||
|
else:
|
||||||
|
if etud["sems"]:
|
||||||
|
if etud["sems"][0]["dateord"] > time.strftime(
|
||||||
|
"%Y-%m-%d", time.localtime()
|
||||||
|
):
|
||||||
|
etud["inscription"] = "futur"
|
||||||
|
etud["situation"] = "futur élève"
|
||||||
|
else:
|
||||||
|
etud["inscription"] = "ancien"
|
||||||
|
etud["situation"] = "ancien élève"
|
||||||
|
else:
|
||||||
|
etud["inscription"] = "non inscrit"
|
||||||
|
etud["situation"] = etud["inscription"]
|
||||||
|
etud["inscriptionstr"] = etud["inscription"]
|
||||||
|
etud["inscription_formsemestre_id"] = None
|
||||||
|
# XXXetud['partitions'] = {} # ne va pas chercher les groupes des anciens semestres
|
||||||
|
etud["etatincursem"] = "?"
|
||||||
|
|
||||||
|
# nettoyage champs souvents vides
|
||||||
|
if etud["nomlycee"]:
|
||||||
|
etud["ilycee"] = "Lycée " + format_lycee(etud["nomlycee"])
|
||||||
|
if etud["villelycee"]:
|
||||||
|
etud["ilycee"] += " (%s)" % etud["villelycee"]
|
||||||
|
etud["ilycee"] += "<br/>"
|
||||||
|
else:
|
||||||
|
if etud["codelycee"]:
|
||||||
|
etud["ilycee"] = format_lycee_from_code(etud["codelycee"])
|
||||||
|
else:
|
||||||
|
etud["ilycee"] = ""
|
||||||
|
rap = ""
|
||||||
|
if etud["rapporteur"] or etud["commentaire"]:
|
||||||
|
rap = "Note du rapporteur"
|
||||||
|
if etud["rapporteur"]:
|
||||||
|
rap += " (%s)" % etud["rapporteur"]
|
||||||
|
rap += ": "
|
||||||
|
if etud["commentaire"]:
|
||||||
|
rap += "<em>%s</em>" % etud["commentaire"]
|
||||||
|
etud["rap"] = rap
|
||||||
|
|
||||||
|
# if etud['boursier_prec']:
|
||||||
|
# pass
|
||||||
|
|
||||||
|
if etud["telephone"]:
|
||||||
|
etud["telephonestr"] = "<b>Tél.:</b> " + format_telephone(etud["telephone"])
|
||||||
|
else:
|
||||||
|
etud["telephonestr"] = ""
|
||||||
|
if etud["telephonemobile"]:
|
||||||
|
etud["telephonemobilestr"] = "<b>Mobile:</b> " + format_telephone(
|
||||||
|
etud["telephonemobile"]
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
etud["telephonemobilestr"] = ""
|
||||||
|
etud["debouche"] = etud["debouche"] or ""
|
||||||
|
|
||||||
|
|
||||||
|
def descr_situation_etud(context, etudid, ne=""):
|
||||||
|
"""chaine decrivant la situation actuelle de l'etudiant"""
|
||||||
|
cnx = context.GetDBConnexion()
|
||||||
|
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
|
||||||
|
cursor.execute(
|
||||||
|
"select I.formsemestre_id, I.etat from notes_formsemestre_inscription I, notes_formsemestre S where etudid=%(etudid)s and S.formsemestre_id = I.formsemestre_id and date_debut < now() and date_fin > now() order by S.date_debut desc;",
|
||||||
|
{"etudid": etudid},
|
||||||
|
)
|
||||||
|
r = cursor.dictfetchone()
|
||||||
|
if not r:
|
||||||
|
situation = "non inscrit"
|
||||||
|
else:
|
||||||
|
sem = sco_formsemestre.get_formsemestre(context, r["formsemestre_id"])
|
||||||
|
if r["etat"] == "I":
|
||||||
|
situation = "inscrit%s en %s" % (ne, sem["titremois"])
|
||||||
|
# Cherche la date d'inscription dans scolar_events:
|
||||||
|
events = scolars.scolar_events_list(
|
||||||
|
cnx,
|
||||||
|
args={
|
||||||
|
"etudid": etudid,
|
||||||
|
"formsemestre_id": sem["formsemestre_id"],
|
||||||
|
"event_type": "INSCRIPTION",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if not events:
|
||||||
|
log(
|
||||||
|
"*** situation inconsistante pour %s (inscrit mais pas d'event)"
|
||||||
|
% etudid
|
||||||
|
)
|
||||||
|
date_ins = "???" # ???
|
||||||
|
else:
|
||||||
|
date_ins = events[0]["event_date"]
|
||||||
|
situation += " le " + str(date_ins)
|
||||||
|
else:
|
||||||
|
situation = "démission de %s" % sem["titremois"]
|
||||||
|
# Cherche la date de demission dans scolar_events:
|
||||||
|
events = scolars.scolar_events_list(
|
||||||
|
cnx,
|
||||||
|
args={
|
||||||
|
"etudid": etudid,
|
||||||
|
"formsemestre_id": sem["formsemestre_id"],
|
||||||
|
"event_type": "DEMISSION",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if not events:
|
||||||
|
log(
|
||||||
|
"*** situation inconsistante pour %s (demission mais pas d'event)"
|
||||||
|
% etudid
|
||||||
|
)
|
||||||
|
date_dem = "???" # ???
|
||||||
|
else:
|
||||||
|
date_dem = events[0]["event_date"]
|
||||||
|
situation += " le " + str(date_dem)
|
||||||
|
return situation
|
File diff suppressed because it is too large
Load Diff
@ -130,8 +130,6 @@ from app.scodoc import notes_table as notes_table
|
|||||||
from app.scodoc.notes_table import NOTES_CACHE_INST, CacheNotesTable
|
from app.scodoc.notes_table import NOTES_CACHE_INST, CacheNotesTable
|
||||||
import app.scodoc.VERSION as VERSION
|
import app.scodoc.VERSION as VERSION
|
||||||
|
|
||||||
context = ScoDoc7Context(globals())
|
|
||||||
|
|
||||||
|
|
||||||
def sco_publish(route, function, permission):
|
def sco_publish(route, function, permission):
|
||||||
"""Declare a route for a python function,
|
"""Declare a route for a python function,
|
||||||
@ -687,7 +685,8 @@ def _do_ue_delete(context, ue_id, delete_validations=False, REQUEST=None, force=
|
|||||||
cnx, args={"ue_id": ue_id}
|
cnx, args={"ue_id": ue_id}
|
||||||
)
|
)
|
||||||
if validations and not delete_validations and not force:
|
if validations and not delete_validations and not force:
|
||||||
return context.confirmDialog(
|
return scu.confirm_dialog(
|
||||||
|
context,
|
||||||
"<p>%d étudiants ont validé l'UE %s (%s)</p><p>Si vous supprimez cette UE, ces validations vont être supprimées !</p>"
|
"<p>%d étudiants ont validé l'UE %s (%s)</p><p>Si vous supprimez cette UE, ces validations vont être supprimées !</p>"
|
||||||
% (len(validations), ue["acronyme"], ue["titre"]),
|
% (len(validations), ue["acronyme"], ue["titre"]),
|
||||||
dest_url="",
|
dest_url="",
|
||||||
@ -920,7 +919,8 @@ def do_module_delete(context, oid, REQUEST):
|
|||||||
# S'il y a des moduleimpls, on ne peut pas detruire le module !
|
# S'il y a des moduleimpls, on ne peut pas detruire le module !
|
||||||
mods = sco_moduleimpl.do_moduleimpl_list(context, module_id=oid)
|
mods = sco_moduleimpl.do_moduleimpl_list(context, module_id=oid)
|
||||||
if mods:
|
if mods:
|
||||||
err_page = context.confirmDialog(
|
err_page = scu.confirm_dialog(
|
||||||
|
context,
|
||||||
message="""<h3>Destruction du module impossible car il est utilisé dans des semestres existants !</h3>""",
|
message="""<h3>Destruction du module impossible car il est utilisé dans des semestres existants !</h3>""",
|
||||||
helpmsg="""Il faut d'abord supprimer le semestre. Mais il est peut être préférable de laisser ce programme intact et d'en créer une nouvelle version pour la modifier.""",
|
helpmsg="""Il faut d'abord supprimer le semestre. Mais il est peut être préférable de laisser ce programme intact et d'en créer une nouvelle version pour la modifier.""",
|
||||||
dest_url="ue_list",
|
dest_url="ue_list",
|
||||||
@ -2037,7 +2037,8 @@ def formsemestre_desinscription(
|
|||||||
car il n'a pas d'autre étudiant inscrit.
|
car il n'a pas d'autre étudiant inscrit.
|
||||||
</p>
|
</p>
|
||||||
"""
|
"""
|
||||||
return context.confirmDialog(
|
return scu.confirm_dialog(
|
||||||
|
context,
|
||||||
"""<h2>Confirmer la demande de desinscription ?</h2>""" + msg_ext,
|
"""<h2>Confirmer la demande de desinscription ?</h2>""" + msg_ext,
|
||||||
dest_url="",
|
dest_url="",
|
||||||
REQUEST=REQUEST,
|
REQUEST=REQUEST,
|
||||||
@ -2759,7 +2760,8 @@ def formsemestre_bulletins_mailetuds(
|
|||||||
raise AccessDenied("vous n'avez pas le droit d'envoyer les bulletins")
|
raise AccessDenied("vous n'avez pas le droit d'envoyer les bulletins")
|
||||||
# Confirmation dialog
|
# Confirmation dialog
|
||||||
if not dialog_confirmed:
|
if not dialog_confirmed:
|
||||||
return context.confirmDialog(
|
return scu.confirm_dialog(
|
||||||
|
context,
|
||||||
"<h2>Envoyer les %d bulletins par e-mail aux étudiants ?" % len(etudids),
|
"<h2>Envoyer les %d bulletins par e-mail aux étudiants ?" % len(etudids),
|
||||||
dest_url="",
|
dest_url="",
|
||||||
REQUEST=REQUEST,
|
REQUEST=REQUEST,
|
||||||
@ -2988,7 +2990,8 @@ def formsemestre_validation_etud(
|
|||||||
):
|
):
|
||||||
"Enregistre choix jury pour un étudiant"
|
"Enregistre choix jury pour un étudiant"
|
||||||
if not context._can_validate_sem(REQUEST, formsemestre_id):
|
if not context._can_validate_sem(REQUEST, formsemestre_id):
|
||||||
return context.confirmDialog(
|
return scu.confirm_dialog(
|
||||||
|
context,
|
||||||
message="<p>Opération non autorisée pour %s</h2>"
|
message="<p>Opération non autorisée pour %s</h2>"
|
||||||
% REQUEST.AUTHENTICATED_USER,
|
% REQUEST.AUTHENTICATED_USER,
|
||||||
dest_url=context.ScoURL(),
|
dest_url=context.ScoURL(),
|
||||||
@ -3023,7 +3026,8 @@ def formsemestre_validation_etud_manu(
|
|||||||
):
|
):
|
||||||
"Enregistre choix jury pour un étudiant"
|
"Enregistre choix jury pour un étudiant"
|
||||||
if not context._can_validate_sem(REQUEST, formsemestre_id):
|
if not context._can_validate_sem(REQUEST, formsemestre_id):
|
||||||
return context.confirmDialog(
|
return scu.confirm_dialog(
|
||||||
|
context,
|
||||||
message="<p>Opération non autorisée pour %s</h2>"
|
message="<p>Opération non autorisée pour %s</h2>"
|
||||||
% REQUEST.AUTHENTICATED_USER,
|
% REQUEST.AUTHENTICATED_USER,
|
||||||
dest_url=context.ScoURL(),
|
dest_url=context.ScoURL(),
|
||||||
@ -3052,7 +3056,8 @@ def formsemestre_validate_previous_ue(
|
|||||||
):
|
):
|
||||||
"Form. saisie UE validée hors ScoDoc "
|
"Form. saisie UE validée hors ScoDoc "
|
||||||
if not context._can_validate_sem(REQUEST, formsemestre_id):
|
if not context._can_validate_sem(REQUEST, formsemestre_id):
|
||||||
return context.confirmDialog(
|
return scu.confirm_dialog(
|
||||||
|
context,
|
||||||
message="<p>Opération non autorisée pour %s</h2>"
|
message="<p>Opération non autorisée pour %s</h2>"
|
||||||
% REQUEST.AUTHENTICATED_USER,
|
% REQUEST.AUTHENTICATED_USER,
|
||||||
dest_url=context.ScoURL(),
|
dest_url=context.ScoURL(),
|
||||||
@ -3078,7 +3083,8 @@ def formsemestre_ext_edit_ue_validations(
|
|||||||
):
|
):
|
||||||
"Form. edition UE semestre extérieur"
|
"Form. edition UE semestre extérieur"
|
||||||
if not context._can_validate_sem(REQUEST, formsemestre_id):
|
if not context._can_validate_sem(REQUEST, formsemestre_id):
|
||||||
return context.confirmDialog(
|
return scu.confirm_dialog(
|
||||||
|
context,
|
||||||
message="<p>Opération non autorisée pour %s</h2>"
|
message="<p>Opération non autorisée pour %s</h2>"
|
||||||
% REQUEST.AUTHENTICATED_USER,
|
% REQUEST.AUTHENTICATED_USER,
|
||||||
dest_url=context.ScoURL(),
|
dest_url=context.ScoURL(),
|
||||||
@ -3102,7 +3108,8 @@ sco_publish(
|
|||||||
def etud_ue_suppress_validation(context, etudid, formsemestre_id, ue_id, REQUEST=None):
|
def etud_ue_suppress_validation(context, etudid, formsemestre_id, ue_id, REQUEST=None):
|
||||||
"""Suppress a validation (ue_id, etudid) and redirect to formsemestre"""
|
"""Suppress a validation (ue_id, etudid) and redirect to formsemestre"""
|
||||||
if not context._can_validate_sem(REQUEST, formsemestre_id):
|
if not context._can_validate_sem(REQUEST, formsemestre_id):
|
||||||
return context.confirmDialog(
|
return scu.confirm_dialog(
|
||||||
|
context,
|
||||||
message="<p>Opération non autorisée pour %s</h2>"
|
message="<p>Opération non autorisée pour %s</h2>"
|
||||||
% REQUEST.AUTHENTICATED_USER,
|
% REQUEST.AUTHENTICATED_USER,
|
||||||
dest_url=context.ScoURL(),
|
dest_url=context.ScoURL(),
|
||||||
@ -3119,7 +3126,8 @@ def etud_ue_suppress_validation(context, etudid, formsemestre_id, ue_id, REQUEST
|
|||||||
def formsemestre_validation_auto(context, formsemestre_id, REQUEST):
|
def formsemestre_validation_auto(context, formsemestre_id, REQUEST):
|
||||||
"Formulaire saisie automatisee des decisions d'un semestre"
|
"Formulaire saisie automatisee des decisions d'un semestre"
|
||||||
if not context._can_validate_sem(REQUEST, formsemestre_id):
|
if not context._can_validate_sem(REQUEST, formsemestre_id):
|
||||||
return context.confirmDialog(
|
return scu.confirm_dialog(
|
||||||
|
context,
|
||||||
message="<p>Opération non autorisée pour %s</h2>"
|
message="<p>Opération non autorisée pour %s</h2>"
|
||||||
% REQUEST.AUTHENTICATED_USER,
|
% REQUEST.AUTHENTICATED_USER,
|
||||||
dest_url=context.ScoURL(),
|
dest_url=context.ScoURL(),
|
||||||
@ -3137,7 +3145,8 @@ def formsemestre_validation_auto(context, formsemestre_id, REQUEST):
|
|||||||
def do_formsemestre_validation_auto(context, formsemestre_id, REQUEST):
|
def do_formsemestre_validation_auto(context, formsemestre_id, REQUEST):
|
||||||
"Formulaire saisie automatisee des decisions d'un semestre"
|
"Formulaire saisie automatisee des decisions d'un semestre"
|
||||||
if not context._can_validate_sem(REQUEST, formsemestre_id):
|
if not context._can_validate_sem(REQUEST, formsemestre_id):
|
||||||
return context.confirmDialog(
|
return scu.confirm_dialog(
|
||||||
|
context,
|
||||||
message="<p>Opération non autorisée pour %s</h2>"
|
message="<p>Opération non autorisée pour %s</h2>"
|
||||||
% REQUEST.AUTHENTICATED_USER,
|
% REQUEST.AUTHENTICATED_USER,
|
||||||
dest_url=context.ScoURL(),
|
dest_url=context.ScoURL(),
|
||||||
@ -3155,7 +3164,8 @@ def do_formsemestre_validation_auto(context, formsemestre_id, REQUEST):
|
|||||||
def formsemestre_fix_validation_ues(context, formsemestre_id, REQUEST=None):
|
def formsemestre_fix_validation_ues(context, formsemestre_id, REQUEST=None):
|
||||||
"Verif/reparation codes UE"
|
"Verif/reparation codes UE"
|
||||||
if not context._can_validate_sem(REQUEST, formsemestre_id):
|
if not context._can_validate_sem(REQUEST, formsemestre_id):
|
||||||
return context.confirmDialog(
|
return scu.confirm_dialog(
|
||||||
|
context,
|
||||||
message="<p>Opération non autorisée pour %s</h2>"
|
message="<p>Opération non autorisée pour %s</h2>"
|
||||||
% REQUEST.AUTHENTICATED_USER,
|
% REQUEST.AUTHENTICATED_USER,
|
||||||
dest_url=context.ScoURL(),
|
dest_url=context.ScoURL(),
|
||||||
@ -3175,7 +3185,8 @@ def formsemestre_validation_suppress_etud(
|
|||||||
):
|
):
|
||||||
"""Suppression des decisions de jury pour un etudiant."""
|
"""Suppression des decisions de jury pour un etudiant."""
|
||||||
if not context._can_validate_sem(REQUEST, formsemestre_id):
|
if not context._can_validate_sem(REQUEST, formsemestre_id):
|
||||||
return context.confirmDialog(
|
return scu.confirm_dialog(
|
||||||
|
context,
|
||||||
message="<p>Opération non autorisée pour %s</h2>"
|
message="<p>Opération non autorisée pour %s</h2>"
|
||||||
% REQUEST.AUTHENTICATED_USER,
|
% REQUEST.AUTHENTICATED_USER,
|
||||||
dest_url=context.ScoURL(),
|
dest_url=context.ScoURL(),
|
||||||
@ -3194,7 +3205,8 @@ def formsemestre_validation_suppress_etud(
|
|||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
existing = ""
|
existing = ""
|
||||||
return context.confirmDialog(
|
return scu.confirm_dialog(
|
||||||
|
context,
|
||||||
"""<h2>Confirmer la suppression des décisions du semestre %s (%s - %s) pour %s ?</h2>%s
|
"""<h2>Confirmer la suppression des décisions du semestre %s (%s - %s) pour %s ?</h2>%s
|
||||||
<p>Cette opération est irréversible.
|
<p>Cette opération est irréversible.
|
||||||
</p>
|
</p>
|
||||||
|
2050
app/views/scolar.py
2050
app/views/scolar.py
File diff suppressed because it is too large
Load Diff
@ -2,6 +2,8 @@ alembic==1.5.5
|
|||||||
attrdict==2.0.1
|
attrdict==2.0.1
|
||||||
Babel==2.9.0
|
Babel==2.9.0
|
||||||
blinker==1.4
|
blinker==1.4
|
||||||
|
certifi==2021.5.30
|
||||||
|
chardet==4.0.0
|
||||||
click==7.1.2
|
click==7.1.2
|
||||||
dnspython==1.16.0
|
dnspython==1.16.0
|
||||||
dominate==2.6.0
|
dominate==2.6.0
|
||||||
@ -33,10 +35,12 @@ python-dotenv==0.15.0
|
|||||||
python-editor==1.0.4
|
python-editor==1.0.4
|
||||||
pytz==2021.1
|
pytz==2021.1
|
||||||
reportlab==3.5.59
|
reportlab==3.5.59
|
||||||
|
requests==2.25.1
|
||||||
six==1.15.0
|
six==1.15.0
|
||||||
SQLAlchemy==1.3.23
|
SQLAlchemy==1.3.23
|
||||||
stripogram==1.5
|
stripogram==1.5
|
||||||
typing==3.7.4.3
|
typing==3.7.4.3
|
||||||
|
urllib3==1.26.5
|
||||||
visitor==0.1.3
|
visitor==0.1.3
|
||||||
Werkzeug==1.0.1
|
Werkzeug==1.0.1
|
||||||
WTForms==2.3.3
|
WTForms==2.3.3
|
||||||
|
@ -57,7 +57,7 @@ class ScoDocManager:
|
|||||||
|
|
||||||
def get_dept_ids(self):
|
def get_dept_ids(self):
|
||||||
"get (unsorted) dept ids"
|
"get (unsorted) dept ids"
|
||||||
return [d.dept_id for d in descr_list]
|
return self.dept_descriptions.keys()
|
||||||
|
|
||||||
def get_db_uri(self):
|
def get_db_uri(self):
|
||||||
"""
|
"""
|
||||||
|
Loading…
Reference in New Issue
Block a user