Compare commits
4 Commits
072f8b09de
...
861c3ad6ca
Author | SHA1 | Date | |
---|---|---|---|
861c3ad6ca | |||
317252575a | |||
9477caf06a | |||
3ff5fedbf6 |
@ -116,8 +116,7 @@ def sco_import_format(with_codesemestre=True):
|
||||
|
||||
|
||||
def sco_import_format_dict(with_codesemestre=True):
|
||||
""" Attribut: { 'type': , 'table', 'allow_nulls' , 'description' }
|
||||
"""
|
||||
"""Attribut: { 'type': , 'table', 'allow_nulls' , 'description' }"""
|
||||
fmt = sco_import_format(with_codesemestre=with_codesemestre)
|
||||
R = collections.OrderedDict()
|
||||
for l in fmt:
|
||||
@ -260,7 +259,7 @@ def scolars_import_excel_file(
|
||||
if not data: # probably a bug
|
||||
raise ScoException("scolars_import_excel_file: empty file !")
|
||||
|
||||
formsemestre_to_invalidate = Set()
|
||||
formsemestre_to_invalidate = set()
|
||||
|
||||
# 1- --- check title line
|
||||
titles = {}
|
||||
@ -555,18 +554,18 @@ def scolars_import_admission(
|
||||
"""Importe données admission depuis un fichier Excel quelconque
|
||||
par exemple ceux utilisés avec APB
|
||||
|
||||
Cherche dans ce fichier les étudiants qui correspondent à des inscrits du
|
||||
Cherche dans ce fichier les étudiants qui correspondent à des inscrits du
|
||||
semestre formsemestre_id.
|
||||
Le fichier n'a pas l'INE ni le NIP ni l'etudid, la correspondance se fait
|
||||
via les noms/prénoms qui doivent être égaux (la casse, les accents et caractères spéciaux
|
||||
Le fichier n'a pas l'INE ni le NIP ni l'etudid, la correspondance se fait
|
||||
via les noms/prénoms qui doivent être égaux (la casse, les accents et caractères spéciaux
|
||||
étant ignorés).
|
||||
|
||||
On tolère plusieurs variantes pour chaque nom de colonne (ici aussi, la casse, les espaces
|
||||
On tolère plusieurs variantes pour chaque nom de colonne (ici aussi, la casse, les espaces
|
||||
et les caractères spéciaux sont ignorés. Ainsi, la colonne "Prénom:" sera considéré comme "prenom".
|
||||
|
||||
Le parametre type_admission remplace les valeurs vides (dans la base ET dans le fichier importé) du champ type_admission.
|
||||
Si une valeur existe ou est présente dans le fichier importé, ce paramètre est ignoré.
|
||||
|
||||
|
||||
TODO:
|
||||
- choix onglet du classeur
|
||||
"""
|
||||
@ -611,7 +610,7 @@ def scolars_import_admission(
|
||||
% formsemestre_id,
|
||||
)
|
||||
|
||||
modifiable_fields = Set(ADMISSION_MODIFIABLE_FIELDS)
|
||||
modifiable_fields = set(ADMISSION_MODIFIABLE_FIELDS)
|
||||
|
||||
nline = 2 # la premiere ligne de donnees du fichier excel est 2
|
||||
n_import = 0
|
||||
@ -748,8 +747,7 @@ def adm_convert_real(v):
|
||||
|
||||
|
||||
def adm_table_description_format(context):
|
||||
"""Table HTML (ou autre format) decrivant les donnees d'admissions importables
|
||||
"""
|
||||
"""Table HTML (ou autre format) decrivant les donnees d'admissions importables"""
|
||||
Fmt = sco_import_format_dict(with_codesemestre=False)
|
||||
for k in Fmt:
|
||||
Fmt[k]["attribute"] = k
|
||||
|
27
ZNotes.py
27
ZNotes.py
@ -28,8 +28,6 @@
|
||||
"""Interface Zope <-> Notes
|
||||
"""
|
||||
|
||||
from sets import Set
|
||||
|
||||
from sco_zope import *
|
||||
|
||||
# ---------------
|
||||
@ -1616,8 +1614,7 @@ class ZNotes(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Impl
|
||||
security.declareProtected(ScoView, "view_module_abs")
|
||||
|
||||
def view_module_abs(self, REQUEST, moduleimpl_id, format="html"):
|
||||
"""Visulalisation des absences a un module
|
||||
"""
|
||||
"""Visulalisation des absences a un module"""
|
||||
M = self.do_moduleimpl_withmodule_list(moduleimpl_id=moduleimpl_id)[0]
|
||||
sem = sco_formsemestre.get_formsemestre(self, M["formsemestre_id"])
|
||||
debut_sem = DateDMYtoISO(sem["date_debut"])
|
||||
@ -1903,7 +1900,7 @@ class ZNotes(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Impl
|
||||
_formsemestre_inscriptionEditor = EditableTable(
|
||||
"notes_formsemestre_inscription",
|
||||
"formsemestre_inscription_id",
|
||||
("formsemestre_inscription_id", "etudid", "formsemestre_id", "etat"),
|
||||
("formsemestre_inscription_id", "etudid", "formsemestre_id", "etat", "etape"),
|
||||
sortkey="formsemestre_id",
|
||||
)
|
||||
|
||||
@ -2011,7 +2008,7 @@ class ZNotes(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Impl
|
||||
):
|
||||
"""desinscrit l'etudiant de ce semestre (et donc de tous les modules).
|
||||
A n'utiliser qu'en cas d'erreur de saisie.
|
||||
S'il s'agit d'un semestre extérieur et qu'il n'y a plus d'inscrit,
|
||||
S'il s'agit d'un semestre extérieur et qu'il n'y a plus d'inscrit,
|
||||
le semestre sera supprimé.
|
||||
"""
|
||||
sem = sco_formsemestre.get_formsemestre(self, formsemestre_id)
|
||||
@ -2242,7 +2239,7 @@ class ZNotes(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Impl
|
||||
{"moduleimpl_id": moduleimpl_id},
|
||||
)
|
||||
# Inscriptions au module:
|
||||
inmod_set = Set(
|
||||
inmod_set = set(
|
||||
[
|
||||
x["etudid"]
|
||||
for x in self.do_moduleimpl_inscription_list(
|
||||
@ -2264,8 +2261,7 @@ class ZNotes(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Impl
|
||||
security.declareProtected(ScoEtudInscrit, "etud_desinscrit_ue")
|
||||
|
||||
def etud_desinscrit_ue(self, etudid, formsemestre_id, ue_id, REQUEST=None):
|
||||
"""Desinscrit l'etudiant de tous les modules de cette UE dans ce semestre.
|
||||
"""
|
||||
"""Desinscrit l'etudiant de tous les modules de cette UE dans ce semestre."""
|
||||
sco_moduleimpl_inscriptions.do_etud_desinscrit_ue(
|
||||
self, etudid, formsemestre_id, ue_id, REQUEST=REQUEST
|
||||
)
|
||||
@ -2278,8 +2274,7 @@ class ZNotes(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Impl
|
||||
security.declareProtected(ScoEtudInscrit, "etud_inscrit_ue")
|
||||
|
||||
def etud_inscrit_ue(self, etudid, formsemestre_id, ue_id, REQUEST=None):
|
||||
"""Inscrit l'etudiant de tous les modules de cette UE dans ce semestre.
|
||||
"""
|
||||
"""Inscrit l'etudiant de tous les modules de cette UE dans ce semestre."""
|
||||
sco_moduleimpl_inscriptions.do_etud_inscrit_ue(
|
||||
self, etudid, formsemestre_id, ue_id, REQUEST=REQUEST
|
||||
)
|
||||
@ -2411,8 +2406,7 @@ class ZNotes(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Impl
|
||||
REQUEST=None,
|
||||
**kw
|
||||
):
|
||||
"""Create an evaluation
|
||||
"""
|
||||
"""Create an evaluation"""
|
||||
args = locals()
|
||||
log("do_evaluation_create: args=" + str(args))
|
||||
self._evaluation_check_write_access(REQUEST, moduleimpl_id=moduleimpl_id)
|
||||
@ -2758,8 +2752,8 @@ class ZNotes(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Impl
|
||||
def can_edit_notes(self, authuser, moduleimpl_id, allow_ens=True):
|
||||
"""True if authuser can enter or edit notes in this module.
|
||||
If allow_ens, grant access to all ens in this module
|
||||
|
||||
Si des décisions de jury ont déjà été saisies dans ce semestre,
|
||||
|
||||
Si des décisions de jury ont déjà été saisies dans ce semestre,
|
||||
seul le directeur des études peut saisir des notes (et il ne devrait pas).
|
||||
"""
|
||||
uid = str(authuser)
|
||||
@ -3319,8 +3313,7 @@ class ZNotes(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Impl
|
||||
def formsemestre_validation_suppress_etud(
|
||||
self, formsemestre_id, etudid, REQUEST=None, dialog_confirmed=False
|
||||
):
|
||||
"""Suppression des decisions de jury pour un etudiant.
|
||||
"""
|
||||
"""Suppression des decisions de jury pour un etudiant."""
|
||||
if not self._can_validate_sem(REQUEST, formsemestre_id):
|
||||
return self.confirmDialog(
|
||||
message="<p>Opération non autorisée pour %s</h2>"
|
||||
|
22
ZScoDoc.py
22
ZScoDoc.py
@ -101,8 +101,7 @@ class ZScoDoc(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Imp
|
||||
return self.absolute_url()
|
||||
|
||||
def _check_admin_perm(self, REQUEST):
|
||||
"""Check if user has permission to add/delete departements
|
||||
"""
|
||||
"""Check if user has permission to add/delete departements"""
|
||||
authuser = REQUEST.AUTHENTICATED_USER
|
||||
if authuser.has_role("manager") or authuser.has_permission(ScoSuperAdmin, self):
|
||||
return ""
|
||||
@ -110,8 +109,7 @@ class ZScoDoc(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Imp
|
||||
return """<h2>Vous n'avez pas le droit d'accéder à cette page</h2>"""
|
||||
|
||||
def _check_users_folder(self, REQUEST=None):
|
||||
"""Vérifie UserFolder et le crée s'il le faut
|
||||
"""
|
||||
"""Vérifie UserFolder et le crée s'il le faut"""
|
||||
try:
|
||||
udb = self.UsersDB
|
||||
return "<!-- uf ok -->"
|
||||
@ -127,8 +125,7 @@ class ZScoDoc(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Imp
|
||||
security.declareProtected("View", "create_users_folder")
|
||||
|
||||
def create_users_folder(self, REQUEST=None):
|
||||
"""Create Zope user folder
|
||||
"""
|
||||
"""Create Zope user folder"""
|
||||
e = self._check_admin_perm(REQUEST)
|
||||
if e:
|
||||
return e
|
||||
@ -304,8 +301,7 @@ class ZScoDoc(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Imp
|
||||
security.declareProtected("View", "delete_dept")
|
||||
|
||||
def delete_dept(self, REQUEST=None, DeptId="", force=False):
|
||||
"""Supprime un departement (de Zope seulement, ne touche pas la BD)
|
||||
"""
|
||||
"""Supprime un departement (de Zope seulement, ne touche pas la BD)"""
|
||||
e = self._check_admin_perm(REQUEST)
|
||||
if e:
|
||||
return e
|
||||
@ -373,8 +369,7 @@ class ZScoDoc(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Imp
|
||||
security.declareProtected("View", "index_html")
|
||||
|
||||
def index_html(self, REQUEST=None, message=None):
|
||||
"""Top level page for ScoDoc
|
||||
"""
|
||||
"""Top level page for ScoDoc"""
|
||||
authuser = REQUEST.AUTHENTICATED_USER
|
||||
deptList = self.list_depts()
|
||||
self._fix_users_folder() # fix our exUserFolder
|
||||
@ -825,8 +820,7 @@ subversion: %(svn_version)s
|
||||
security.declareProtected("View", "scodoc_admin")
|
||||
|
||||
def scodoc_admin(self, REQUEST=None):
|
||||
"""Page Operations d'administration
|
||||
"""
|
||||
"""Page Operations d'administration"""
|
||||
e = self._check_admin_perm(REQUEST)
|
||||
if e:
|
||||
return e
|
||||
@ -847,8 +841,8 @@ subversion: %(svn_version)s
|
||||
]
|
||||
|
||||
deptList = [x.id for x in self.list_depts()] # definis dans Zope
|
||||
deptIds = Set(self._list_depts_ids()) # definis sur le filesystem
|
||||
existingDepts = Set(deptList)
|
||||
deptIds = set(self._list_depts_ids()) # definis sur le filesystem
|
||||
existingDepts = set(deptList)
|
||||
addableDepts = deptIds - existingDepts
|
||||
|
||||
if not addableDepts:
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -487,6 +487,7 @@ CREATE TABLE notes_formsemestre_inscription (
|
||||
etudid text REFERENCES identite(etudid),
|
||||
formsemestre_id text REFERENCES notes_formsemestre(formsemestre_id),
|
||||
etat text, -- I inscrit, D demission en cours de semestre, DEF si "defaillant"
|
||||
etape text, -- etape apogee d'inscription (experimental 2020)
|
||||
UNIQUE(formsemestre_id, etudid)
|
||||
) WITH OIDS;
|
||||
|
||||
|
@ -402,7 +402,7 @@ enregistrés et non modifiables, on peut les retrouver ultérieurement.
|
||||
),
|
||||
("sep", {"input_type": "separator", "title": "Informations sur PV de jury"}),
|
||||
]
|
||||
descr += sco_pvjury.descrform_pvjury(sem)
|
||||
descr += sco_pvjury.descrform_pvjury(context, sem)
|
||||
descr += [
|
||||
(
|
||||
"signature",
|
||||
|
@ -98,7 +98,7 @@ def formsemestre_bulletinetud_dict(
|
||||
):
|
||||
"""Collecte informations pour bulletin de notes
|
||||
Retourne un dictionnaire (avec valeur par défaut chaine vide).
|
||||
Le contenu du dictionnaire dépend des options (rangs, ...)
|
||||
Le contenu du dictionnaire dépend des options (rangs, ...)
|
||||
et de la version choisie (short, long, selectedevals).
|
||||
|
||||
Cette fonction est utilisée pour les bulletins HTML et PDF, mais pas ceux en XML.
|
||||
@ -131,9 +131,11 @@ def formsemestre_bulletinetud_dict(
|
||||
I["etud"] = context.getEtudInfo(etudid=etudid, filled=1)[0]
|
||||
I["descr_situation"] = I["etud"]["inscriptionstr"]
|
||||
if I["etud"]["inscription_formsemestre_id"]:
|
||||
I["descr_situation_html"] = (
|
||||
"""<a href="formsemestre_status?formsemestre_id=%s">%s</a>"""
|
||||
% (I["etud"]["inscription_formsemestre_id"], I["descr_situation"])
|
||||
I[
|
||||
"descr_situation_html"
|
||||
] = """<a href="formsemestre_status?formsemestre_id=%s">%s</a>""" % (
|
||||
I["etud"]["inscription_formsemestre_id"],
|
||||
I["descr_situation"],
|
||||
)
|
||||
else:
|
||||
I["descr_situation_html"] = I["descr_situation"]
|
||||
@ -314,14 +316,13 @@ def formsemestre_bulletinetud_dict(
|
||||
u["ue_descr_txt"] = "Capitalisée le %s" % DateISOtoDMY(
|
||||
ue_status["event_date"]
|
||||
)
|
||||
u["ue_descr_html"] = (
|
||||
'<a href="formsemestre_bulletinetud?formsemestre_id=%s&etudid=%s" title="%s" class="bull_link">%s</a>'
|
||||
% (
|
||||
sem_origin["formsemestre_id"],
|
||||
etudid,
|
||||
sem_origin["titreannee"],
|
||||
u["ue_descr_txt"],
|
||||
)
|
||||
u[
|
||||
"ue_descr_html"
|
||||
] = '<a href="formsemestre_bulletinetud?formsemestre_id=%s&etudid=%s" title="%s" class="bull_link">%s</a>' % (
|
||||
sem_origin["formsemestre_id"],
|
||||
etudid,
|
||||
sem_origin["titreannee"],
|
||||
u["ue_descr_txt"],
|
||||
)
|
||||
# log('cap details %s' % ue_status['moy'])
|
||||
if ue_status["moy"] != "NA" and ue_status["formsemestre_id"]:
|
||||
@ -539,7 +540,7 @@ def _ue_mod_bulletin(context, etudid, formsemestre_id, ue_id, modimpls, nt, vers
|
||||
# Evaluations incomplètes ou futures:
|
||||
mod["evaluations_incompletes"] = []
|
||||
if context.get_preference("bul_show_all_evals", formsemestre_id):
|
||||
complete_eval_ids = Set([e["evaluation_id"] for e in evals])
|
||||
complete_eval_ids = set([e["evaluation_id"] for e in evals])
|
||||
all_evals = context.do_evaluation_list(
|
||||
args={"moduleimpl_id": modimpl["moduleimpl_id"]}
|
||||
)
|
||||
@ -578,8 +579,7 @@ def _ue_mod_bulletin(context, etudid, formsemestre_id, ue_id, modimpls, nt, vers
|
||||
def get_etud_rangs_groups(
|
||||
context, etudid, formsemestre_id, partitions, partitions_etud_groups, nt
|
||||
):
|
||||
"""Ramene rang et nb inscrits dans chaque partition
|
||||
"""
|
||||
"""Ramene rang et nb inscrits dans chaque partition"""
|
||||
rang_gr, ninscrits_gr, gr_name = {}, {}, {}
|
||||
for partition in partitions:
|
||||
if partition["partition_name"] != None:
|
||||
@ -616,7 +616,7 @@ def etud_descr_situation_semestre(
|
||||
|
||||
situation : chaine résumant en français la situation de l'étudiant.
|
||||
Par ex. "Inscrit le 31/12/1999. Décision jury: Validé. ..."
|
||||
|
||||
|
||||
date_inscription : (vide si show_date_inscr est faux)
|
||||
date_demission : (vide si pas demission ou si show_date_inscr est faux)
|
||||
descr_inscription : "Inscrit" ou "Pas inscrit[e]"
|
||||
@ -820,8 +820,7 @@ def formsemestre_bulletinetud(
|
||||
|
||||
|
||||
def can_send_bulletin_by_mail(context, formsemestre_id, REQUEST):
|
||||
"""True if current user is allowed to send a bulletin by mail
|
||||
"""
|
||||
"""True if current user is allowed to send a bulletin by mail"""
|
||||
authuser = REQUEST.AUTHENTICATED_USER
|
||||
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
|
||||
return (
|
||||
@ -1177,8 +1176,7 @@ def _formsemestre_bulletinetud_header_html(
|
||||
def formsemestre_bulletins_choice(
|
||||
context, REQUEST, formsemestre_id, title="", explanation="", choose_mail=False
|
||||
):
|
||||
"""Choix d'une version de bulletin
|
||||
"""
|
||||
"""Choix d'une version de bulletin"""
|
||||
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
|
||||
H = [
|
||||
context.html_sem_header(REQUEST, title, sem),
|
||||
|
@ -273,7 +273,7 @@ def formsemestre_bulletinetud_published_dict(
|
||||
)
|
||||
)
|
||||
# Evaluations incomplètes ou futures:
|
||||
complete_eval_ids = Set([e["evaluation_id"] for e in evals])
|
||||
complete_eval_ids = set([e["evaluation_id"] for e in evals])
|
||||
if context.get_preference("bul_show_all_evals", formsemestre_id):
|
||||
all_evals = context.do_evaluation_list(
|
||||
args={"moduleimpl_id": modimpl["moduleimpl_id"]}
|
||||
|
@ -265,7 +265,7 @@ def make_xml_formsemestre_bulletinetud(
|
||||
doc.note(value=val)
|
||||
doc._pop()
|
||||
# Evaluations incomplètes ou futures:
|
||||
complete_eval_ids = Set([e["evaluation_id"] for e in evals])
|
||||
complete_eval_ids = set([e["evaluation_id"] for e in evals])
|
||||
if context.get_preference("bul_show_all_evals", formsemestre_id):
|
||||
all_evals = context.do_evaluation_list(
|
||||
args={"moduleimpl_id": modimpl["moduleimpl_id"]}
|
||||
|
@ -381,7 +381,7 @@ class ParcoursLP2014(TypeParcours):
|
||||
|
||||
def check_barre_ues(self, ues_status):
|
||||
"""True si la ou les conditions sur les UE sont valides
|
||||
Article 10: "une moyenne égale ou supérieure à 10 sur 20 à l'ensemble constitué
|
||||
Article 10: "une moyenne égale ou supérieure à 10 sur 20 à l'ensemble constitué
|
||||
du projet tutoré et du stage."
|
||||
"""
|
||||
# Les UE de type "projet ou stage" ayant des notes
|
||||
@ -410,7 +410,7 @@ class ParcoursLP2014(TypeParcours):
|
||||
register_parcours(ParcoursLP2014())
|
||||
|
||||
|
||||
class ParcoursLP2sem(ParcoursLP):
|
||||
class ParcoursLP2sem2014(ParcoursLP):
|
||||
"""Licence Pro (en deux "semestres", selon arrêté du 22/01/2014)"""
|
||||
|
||||
TYPE_PARCOURS = 240
|
||||
@ -418,7 +418,7 @@ class ParcoursLP2sem(ParcoursLP):
|
||||
NB_SEM = 2
|
||||
|
||||
|
||||
register_parcours(ParcoursLP2sem())
|
||||
register_parcours(ParcoursLP2sem2014())
|
||||
|
||||
|
||||
# Masters: M2 en deux semestres
|
||||
|
@ -28,7 +28,6 @@
|
||||
"""Calcul des moyennes de module
|
||||
"""
|
||||
|
||||
from sets import Set
|
||||
import traceback
|
||||
|
||||
from sco_utils import *
|
||||
@ -92,8 +91,7 @@ formsemestre_ue_computation_expr_edit = _formsemestre_ue_computation_exprEditor.
|
||||
|
||||
|
||||
def get_ue_expression(formsemestre_id, ue_id, cnx, html_quote=False):
|
||||
"""Returns UE expression (formula), or None if no expression has been defined
|
||||
"""
|
||||
"""Returns UE expression (formula), or None if no expression has been defined"""
|
||||
el = formsemestre_ue_computation_expr_list(
|
||||
cnx, {"formsemestre_id": formsemestre_id, "ue_id": ue_id}
|
||||
)
|
||||
@ -196,7 +194,7 @@ def do_moduleimpl_moyennes(context, nt, mod):
|
||||
moduleimpl_id
|
||||
) # tous, y compris demissions
|
||||
# Inscrits au semestre (pour traiter les demissions):
|
||||
inssem_set = Set(
|
||||
inssem_set = set(
|
||||
[
|
||||
x["etudid"]
|
||||
for x in context.do_formsemestre_inscription_listinscrits(
|
||||
|
@ -27,7 +27,6 @@
|
||||
|
||||
"""Evaluations
|
||||
"""
|
||||
from sets import Set
|
||||
|
||||
from notes_log import log, logCallStack
|
||||
from sco_utils import *
|
||||
@ -117,7 +116,7 @@ def do_evaluation_etat(
|
||||
context, evaluation_id, partition_id=None, select_first_partition=False
|
||||
):
|
||||
"""donne infos sur l'etat du evaluation
|
||||
{ nb_inscrits, nb_notes, nb_abs, nb_neutre, nb_att,
|
||||
{ nb_inscrits, nb_notes, nb_abs, nb_neutre, nb_att,
|
||||
moyenne, mediane, mini, maxi,
|
||||
date_last_modif, gr_complets, gr_incomplets, evalcomplete }
|
||||
evalcomplete est vrai si l'eval est complete (tous les inscrits
|
||||
@ -176,7 +175,7 @@ def do_evaluation_etat(
|
||||
# au module (pour gerer les modules optionnels correctement)
|
||||
insem = context.do_formsemestre_inscription_listinscrits(formsemestre_id)
|
||||
insmod = context.do_moduleimpl_inscription_list(moduleimpl_id=E["moduleimpl_id"])
|
||||
insmodset = Set([x["etudid"] for x in insmod])
|
||||
insmodset = set([x["etudid"] for x in insmod])
|
||||
# retire de insem ceux qui ne sont pas inscrits au module
|
||||
ins = [i for i in insem if i["etudid"] in insmodset]
|
||||
|
||||
@ -292,50 +291,50 @@ def do_evaluation_etat(
|
||||
|
||||
def do_evaluation_list_in_sem(context, formsemestre_id):
|
||||
"""Liste les evaluations de tous les modules de ce semestre.
|
||||
Donne pour chaque eval son état (voir do_evaluation_etat)
|
||||
{ evaluation_id,nb_inscrits, nb_notes, nb_abs, nb_neutre, moy, median, last_modif ... }
|
||||
Donne pour chaque eval son état (voir do_evaluation_etat)
|
||||
{ evaluation_id,nb_inscrits, nb_notes, nb_abs, nb_neutre, moy, median, last_modif ... }
|
||||
|
||||
Exemple:
|
||||
[ {
|
||||
'coefficient': 1.0,
|
||||
'description': 'QCM et cas pratiques',
|
||||
'etat': {'evalattente': False,
|
||||
'evalcomplete': True,
|
||||
'evaluation_id': 'GEAEVAL82883',
|
||||
'gr_incomplets': [],
|
||||
'gr_moyennes': [{'gr_median': '12.00',
|
||||
'gr_median_num' : 12.,
|
||||
'gr_moy': '11.88',
|
||||
'gr_moy_num' : 11.88,
|
||||
'gr_nb_att': 0,
|
||||
'gr_nb_notes': 166,
|
||||
'group_id': 'GEAG266762',
|
||||
'group_name': None}],
|
||||
'groups': {'GEAG266762': {'etudid': 'GEAEID80603',
|
||||
'group_id': 'GEAG266762',
|
||||
'group_name': None,
|
||||
'partition_id': 'GEAP266761'}
|
||||
},
|
||||
'last_modif': datetime.datetime(2015, 12, 3, 15, 15, 16),
|
||||
'median': '12.00',
|
||||
'moy': '11.84',
|
||||
'nb_abs': 2,
|
||||
'nb_att': 0,
|
||||
'nb_inscrits': 166,
|
||||
'nb_neutre': 0,
|
||||
'nb_notes': 168,
|
||||
'nb_notes_total': 169
|
||||
},
|
||||
'evaluation_id': 'GEAEVAL82883',
|
||||
'evaluation_type': 0,
|
||||
'heure_debut': datetime.time(8, 0),
|
||||
'heure_fin': datetime.time(9, 30),
|
||||
'jour': datetime.date(2015, 11, 3), // vide => 1/1/1
|
||||
'moduleimpl_id': 'GEAMIP80490',
|
||||
'note_max': 20.0,
|
||||
'numero': 0,
|
||||
'publish_incomplete': 0,
|
||||
'visibulletin': 1} ]
|
||||
Exemple:
|
||||
[ {
|
||||
'coefficient': 1.0,
|
||||
'description': 'QCM et cas pratiques',
|
||||
'etat': {'evalattente': False,
|
||||
'evalcomplete': True,
|
||||
'evaluation_id': 'GEAEVAL82883',
|
||||
'gr_incomplets': [],
|
||||
'gr_moyennes': [{'gr_median': '12.00',
|
||||
'gr_median_num' : 12.,
|
||||
'gr_moy': '11.88',
|
||||
'gr_moy_num' : 11.88,
|
||||
'gr_nb_att': 0,
|
||||
'gr_nb_notes': 166,
|
||||
'group_id': 'GEAG266762',
|
||||
'group_name': None}],
|
||||
'groups': {'GEAG266762': {'etudid': 'GEAEID80603',
|
||||
'group_id': 'GEAG266762',
|
||||
'group_name': None,
|
||||
'partition_id': 'GEAP266761'}
|
||||
},
|
||||
'last_modif': datetime.datetime(2015, 12, 3, 15, 15, 16),
|
||||
'median': '12.00',
|
||||
'moy': '11.84',
|
||||
'nb_abs': 2,
|
||||
'nb_att': 0,
|
||||
'nb_inscrits': 166,
|
||||
'nb_neutre': 0,
|
||||
'nb_notes': 168,
|
||||
'nb_notes_total': 169
|
||||
},
|
||||
'evaluation_id': 'GEAEVAL82883',
|
||||
'evaluation_type': 0,
|
||||
'heure_debut': datetime.time(8, 0),
|
||||
'heure_fin': datetime.time(9, 30),
|
||||
'jour': datetime.date(2015, 11, 3), // vide => 1/1/1
|
||||
'moduleimpl_id': 'GEAMIP80490',
|
||||
'note_max': 20.0,
|
||||
'numero': 0,
|
||||
'publish_incomplete': 0,
|
||||
'visibulletin': 1} ]
|
||||
|
||||
"""
|
||||
req = "select E.* from notes_evaluation E, notes_moduleimpl MI where MI.formsemestre_id = %(formsemestre_id)s and MI.moduleimpl_id = E.moduleimpl_id"
|
||||
@ -410,8 +409,7 @@ def do_evaluation_etat_in_sem(context, formsemestre_id, REQUEST=None):
|
||||
|
||||
|
||||
def do_evaluation_etat_in_mod(context, nt, moduleimpl_id):
|
||||
"""
|
||||
"""
|
||||
""""""
|
||||
evals = nt.get_mod_evaluation_etat_list(moduleimpl_id)
|
||||
etat = _eval_etat(evals)
|
||||
etat["attente"] = moduleimpl_id in [
|
||||
@ -522,7 +520,7 @@ def evaluation_date_first_completion(context, evaluation_id):
|
||||
# au module (pour gerer les modules optionnels correctement)
|
||||
insem = context.do_formsemestre_inscription_listinscrits(formsemestre_id)
|
||||
insmod = context.do_moduleimpl_inscription_list(moduleimpl_id=E["moduleimpl_id"])
|
||||
insmodset = Set([x["etudid"] for x in insmod])
|
||||
insmodset = set([x["etudid"] for x in insmod])
|
||||
# retire de insem ceux qui ne sont pas inscrits au module
|
||||
ins = [i for i in insem if i["etudid"] in insmodset]
|
||||
|
||||
|
@ -28,12 +28,13 @@
|
||||
"""Opérations d'inscriptions aux semestres et modules
|
||||
"""
|
||||
|
||||
from sco_utils import ScoEtudInscrit, log, ScoValueError, DictDefault
|
||||
from sco_utils import UE_STANDARD, UE_SPORT, UE_TYPE_NAME
|
||||
from notesdb import ScoDocCursor, DateISOtoDMY, DateDMYtoISO
|
||||
|
||||
from notesdb import *
|
||||
from sco_utils import *
|
||||
from notes_log import log
|
||||
from TrivialFormulator import TrivialFormulator, TF
|
||||
from notes_table import *
|
||||
|
||||
# from notes_table import *
|
||||
import sco_find_etud
|
||||
import sco_formsemestre
|
||||
import sco_groups
|
||||
@ -45,10 +46,11 @@ def do_formsemestre_inscription_with_modules(
|
||||
etudid,
|
||||
group_ids=[],
|
||||
etat="I",
|
||||
etape=None,
|
||||
REQUEST=None,
|
||||
method="inscription_with_modules",
|
||||
):
|
||||
"""Inscrit cet etudiant a ce semestre et TOUS ses modules STANDARDS
|
||||
"""Inscrit cet etudiant à ce semestre et TOUS ses modules STANDARDS
|
||||
(donc sauf le sport)
|
||||
"""
|
||||
# inscription au semestre
|
||||
@ -258,8 +260,7 @@ def formsemestre_inscription_with_modules(
|
||||
|
||||
|
||||
def formsemestre_inscription_option(context, etudid, formsemestre_id, REQUEST=None):
|
||||
"""Dialogue pour (des)inscription a des modules optionnels
|
||||
"""
|
||||
"""Dialogue pour (dés)inscription à des modules optionnels."""
|
||||
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
|
||||
if sem["etat"] != "1":
|
||||
raise ScoValueError("Modification impossible: semestre verrouille")
|
||||
@ -283,7 +284,7 @@ def formsemestre_inscription_option(context, etudid, formsemestre_id, REQUEST=No
|
||||
modimpls_by_ue_ids = DictDefault(defaultvalue=[]) # ue_id : [ moduleimpl_id ]
|
||||
modimpls_by_ue_names = DictDefault(defaultvalue=[]) # ue_id : [ moduleimpl_name ]
|
||||
ues = []
|
||||
ue_ids = Set()
|
||||
ue_ids = set()
|
||||
initvalues = {}
|
||||
for mod in mods:
|
||||
ue_id = mod["ue"]["ue_id"]
|
||||
@ -320,14 +321,11 @@ def formsemestre_inscription_option(context, etudid, formsemestre_id, REQUEST=No
|
||||
sem_origin = sco_formsemestre.get_formsemestre(
|
||||
context, ue_status["formsemestre_id"]
|
||||
)
|
||||
ue_descr += (
|
||||
' <a class="discretelink" href="formsemestre_bulletinetud?formsemestre_id=%s&etudid=%s" title="%s">(capitalisée le %s)'
|
||||
% (
|
||||
sem_origin["formsemestre_id"],
|
||||
etudid,
|
||||
sem_origin["titreannee"],
|
||||
DateISOtoDMY(ue_status["event_date"]),
|
||||
)
|
||||
ue_descr += ' <a class="discretelink" href="formsemestre_bulletinetud?formsemestre_id=%s&etudid=%s" title="%s">(capitalisée le %s)' % (
|
||||
sem_origin["formsemestre_id"],
|
||||
etudid,
|
||||
sem_origin["titreannee"],
|
||||
DateISOtoDMY(ue_status["event_date"]),
|
||||
)
|
||||
descr.append(
|
||||
(
|
||||
@ -405,7 +403,7 @@ function chkbx_select(field_id, state) {
|
||||
if not insdict.has_key(moduleimpl_id):
|
||||
del a_desinscrire[moduleimpl_id]
|
||||
|
||||
a_inscrire = Set()
|
||||
a_inscrire = set()
|
||||
for ue in ues:
|
||||
ue_id = ue["ue_id"]
|
||||
a_inscrire.update(tf[2]["moduleimpls_%s" % ue_id])
|
||||
@ -529,7 +527,7 @@ def do_moduleimpl_incription_options(
|
||||
)
|
||||
if not inscr:
|
||||
raise ScoValueError(
|
||||
"pas inscrit a ce module ! (etudid=%s, moduleimpl_id=%)"
|
||||
"pas inscrit a ce module ! (etudid=%s, moduleimpl_id=%s)"
|
||||
% (etudid, moduleimpl_id)
|
||||
)
|
||||
oid = inscr[0]["moduleimpl_inscription_id"]
|
||||
|
@ -28,7 +28,6 @@
|
||||
"""Une classe "vecteur" pour les formules utilisateurs de calcul des moyennes
|
||||
"""
|
||||
|
||||
from sets import Set
|
||||
import operator
|
||||
import traceback
|
||||
from types import FloatType, IntType, LongType, StringType
|
||||
@ -174,8 +173,7 @@ formula_builtins = {
|
||||
|
||||
|
||||
def eval_user_expression(context, expression, variables):
|
||||
"""Evalue l'expression (formule utilisateur) avec les variables (dict) données.
|
||||
"""
|
||||
"""Evalue l'expression (formule utilisateur) avec les variables (dict) données."""
|
||||
variables["__builtins__"] = formula_builtins
|
||||
# log('Evaluating %s with %s' % (expression, variables))
|
||||
# may raise exception if user expression is invalid
|
||||
|
@ -63,7 +63,7 @@ def checkGroupName(
|
||||
): # XXX unused: now allow any string as a group or partition name
|
||||
"Raises exception if not a valid group name"
|
||||
if groupName and (
|
||||
not re.match("^\w+$", groupName) or (simplesqlquote(groupName) != groupName)
|
||||
not re.match(r"^\w+$", groupName) or (simplesqlquote(groupName) != groupName)
|
||||
):
|
||||
log("!!! invalid group name: " + groupName)
|
||||
raise ValueError("invalid group name: " + groupName)
|
||||
@ -103,8 +103,7 @@ def get_group(context, group_id):
|
||||
|
||||
|
||||
def group_delete(context, group, force=False):
|
||||
"""Delete a group.
|
||||
"""
|
||||
"""Delete a group."""
|
||||
# if not group['group_name'] and not force:
|
||||
# raise ValueError('cannot suppress this group')
|
||||
# remove memberships:
|
||||
@ -156,8 +155,7 @@ def get_default_partition(context, formsemestre_id):
|
||||
|
||||
|
||||
def get_formsemestre_groups(context, formsemestre_id, with_default=False):
|
||||
"""Returns ( partitions, { partition_id : { etudid : group } } )
|
||||
"""
|
||||
"""Returns ( partitions, { partition_id : { etudid : group } } )."""
|
||||
partitions = get_partitions_list(
|
||||
context, formsemestre_id, with_default=with_default
|
||||
)
|
||||
@ -179,8 +177,7 @@ def get_partition_groups(context, partition):
|
||||
|
||||
|
||||
def get_default_group(context, formsemestre_id, fix_if_missing=False, REQUEST=None):
|
||||
"""Returns group_id for default ('tous') group
|
||||
"""
|
||||
"""Returns group_id for default ('tous') group"""
|
||||
r = SimpleDictFetch(
|
||||
context,
|
||||
"SELECT gd.group_id FROM group_descr gd, partition p WHERE p.formsemestre_id=%(formsemestre_id)s AND p.partition_name is NULL AND p.partition_id = gd.partition_id",
|
||||
@ -261,10 +258,8 @@ def get_group_members(context, group_id, etat=None):
|
||||
|
||||
|
||||
def get_group_infos(context, group_id, etat=None): # was _getlisteetud
|
||||
"""legacy code: used by group_list and trombino
|
||||
"""
|
||||
"""legacy code: used by group_list and trombino"""
|
||||
cnx = context.GetDBConnexion()
|
||||
cursor = cnx.cursor(cursor_factory=ScoDocCursor)
|
||||
group = get_group(context, group_id)
|
||||
sem = sco_formsemestre.get_formsemestre(context, group["formsemestre_id"])
|
||||
|
||||
@ -370,8 +365,7 @@ def formsemestre_get_etud_groupnames(context, formsemestre_id, attr="group_name"
|
||||
|
||||
|
||||
def etud_add_group_infos(context, etud, sem, sep=" "):
|
||||
"""Add informations on partitions and group memberships to etud (a dict with an etudid)
|
||||
"""
|
||||
"""Add informations on partitions and group memberships to etud (a dict with an etudid)"""
|
||||
etud[
|
||||
"partitions"
|
||||
] = collections.OrderedDict() # partition_id : group + partition_name
|
||||
@ -553,8 +547,7 @@ def set_group(context, etudid, group_id):
|
||||
def change_etud_group_in_partition(
|
||||
context, etudid, group_id, partition=None, REQUEST=None
|
||||
):
|
||||
"""Inscrit etud au groupe de cette partition, et le desinscrit d'autres groupes de cette partition.
|
||||
"""
|
||||
"""Inscrit etud au groupe de cette partition, et le desinscrit d'autres groupes de cette partition."""
|
||||
log("change_etud_group_in_partition: etudid=%s group_id=%s" % (etudid, group_id))
|
||||
|
||||
# 0- La partition
|
||||
@ -700,7 +693,7 @@ def createGroup(context, partition_id, group_name="", default=False, REQUEST=Non
|
||||
"""
|
||||
partition = get_partition(context, partition_id)
|
||||
formsemestre_id = partition["formsemestre_id"]
|
||||
if not context.Notes.can_change_groups(REQUEST, formsemestre_id):
|
||||
if REQUEST and not context.Notes.can_change_groups(REQUEST, formsemestre_id):
|
||||
raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !")
|
||||
#
|
||||
if group_name:
|
||||
@ -756,7 +749,7 @@ def partition_create(
|
||||
redirect=1,
|
||||
):
|
||||
"""Create a new partition"""
|
||||
if not context.Notes.can_change_groups(REQUEST, formsemestre_id):
|
||||
if REQUEST and not context.Notes.can_change_groups(REQUEST, formsemestre_id):
|
||||
raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !")
|
||||
if partition_name:
|
||||
partition_name = partition_name.strip()
|
||||
@ -800,7 +793,8 @@ def getArrowIconsTags(context, REQUEST):
|
||||
def editPartitionForm(context, formsemestre_id=None, REQUEST=None):
|
||||
"""Form to create/suppress partitions"""
|
||||
# ad-hoc form
|
||||
canedit = context.Notes.can_change_groups(REQUEST, formsemestre_id)
|
||||
if not context.Notes.can_change_groups(REQUEST, formsemestre_id):
|
||||
raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !")
|
||||
partitions = get_partitions_list(context, formsemestre_id)
|
||||
arrow_up, arrow_down, arrow_none = getArrowIconsTags(context, REQUEST)
|
||||
suppricon = icontag(
|
||||
@ -1294,6 +1288,48 @@ def get_prev_moy(context, etudid, formsemestre_id):
|
||||
return 0.0
|
||||
|
||||
|
||||
def create_etapes_partition(context, formsemestre_id, partition_name="apo_etapes"):
|
||||
"""Crée une partition "apo_etapes" avec un groupe par étape Apogée.
|
||||
Cette partition n'est crée que si plusieurs étapes différentes existent dans ce
|
||||
semestre.
|
||||
Si la partition existe déjà, ses groupes sont mis à jour (les groupes devenant
|
||||
vides ne sont pas supprimés).
|
||||
"""
|
||||
log("create_etapes_partition(%s)" % formsemestre_id)
|
||||
ins = context.do_formsemestre_inscription_list(
|
||||
args={"formsemestre_id": formsemestre_id}
|
||||
)
|
||||
etapes = {i["etape"] for i in ins if i["etape"]}
|
||||
partitions = get_partitions_list(context, formsemestre_id, with_default=False)
|
||||
partition = None
|
||||
for p in partitions:
|
||||
if p["partition_name"] == partition_name:
|
||||
partition = p
|
||||
break
|
||||
if len(etapes) < 2 and not partition:
|
||||
return # moins de deux étapes, pas de création
|
||||
if partition:
|
||||
pid = partition["partition_id"]
|
||||
else:
|
||||
pid = partition_create(
|
||||
context, formsemestre_id, partition_name=partition_name, redirect=False
|
||||
)
|
||||
partition = get_partition(context, pid)
|
||||
groups = get_partition_groups(context, partition)
|
||||
groups_by_names = {g["group_name"]: g for g in groups}
|
||||
for etape in etapes:
|
||||
if not (etape in groups_by_names):
|
||||
gid = createGroup(context, pid, etape)
|
||||
g = get_group(context, gid)
|
||||
groups_by_names[etape] = g
|
||||
# Place les etudiants dans les groupes
|
||||
for i in ins:
|
||||
if i["etape"]:
|
||||
change_etud_group_in_partition(
|
||||
context, i["etudid"], groups_by_names[i["etape"]]["group_id"], partition
|
||||
)
|
||||
|
||||
|
||||
def do_evaluation_listeetuds_groups(
|
||||
context, evaluation_id, groups=None, getallstudents=False, include_dems=False
|
||||
):
|
||||
@ -1340,7 +1376,7 @@ def do_evaluation_listeetuds_groups(
|
||||
|
||||
|
||||
def do_evaluation_listegroupes(context, evaluation_id, include_default=False):
|
||||
"""Donne la liste des groupes dans lesquels figurent des etudiants inscrits
|
||||
"""Donne la liste des groupes dans lesquels figurent des etudiants inscrits
|
||||
au module/semestre auquel appartient cette evaluation.
|
||||
Si include_default, inclue aussi le groupe par defaut ('tous')
|
||||
[ group ]
|
||||
|
@ -47,8 +47,6 @@ def affectGroups(context, partition_id, REQUEST=None):
|
||||
if not context.Notes.can_change_groups(REQUEST, formsemestre_id):
|
||||
raise AccessDenied("vous n'avez pas la permission d'effectuer cette opération")
|
||||
|
||||
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
|
||||
|
||||
H = [
|
||||
context.sco_header(
|
||||
REQUEST,
|
||||
|
@ -429,8 +429,12 @@ def groups_table(
|
||||
):
|
||||
"""liste etudiants inscrits dans ce semestre
|
||||
format: csv, json, xml, xls, allxls, xlsappel, moodlecsv, pdf
|
||||
Si with_codes, ajoute 3 colonnes avec les codes etudid, NIP, INE
|
||||
Si with_codes, ajoute 4 colonnes avec les codes etudid, NIP, INE et etape
|
||||
"""
|
||||
log(
|
||||
"enter groups_table %s: %s"
|
||||
% (groups_infos.members[0]["nom"], groups_infos.members[0].get("etape", "-"))
|
||||
)
|
||||
authuser = REQUEST.AUTHENTICATED_USER
|
||||
|
||||
with_codes = int(with_codes)
|
||||
@ -784,8 +788,7 @@ def groups_table(
|
||||
|
||||
|
||||
def tab_absences_html(context, groups_infos, etat=None, REQUEST=None):
|
||||
"""contenu du tab "absences et feuilles diverses"
|
||||
"""
|
||||
"""contenu du tab "absences et feuilles diverses" """
|
||||
authuser = REQUEST.AUTHENTICATED_USER
|
||||
H = ['<div class="tab-content">']
|
||||
if not groups_infos.members:
|
||||
@ -841,8 +844,7 @@ def tab_absences_html(context, groups_infos, etat=None, REQUEST=None):
|
||||
|
||||
|
||||
def tab_photos_html(context, groups_infos, etat=None, REQUEST=None):
|
||||
"""contenu du tab "photos"
|
||||
"""
|
||||
"""contenu du tab "photos" """
|
||||
if not groups_infos.members:
|
||||
return '<div class="tab-content"><h3>Aucun étudiant !</h3></div>'
|
||||
|
||||
@ -850,8 +852,7 @@ def tab_photos_html(context, groups_infos, etat=None, REQUEST=None):
|
||||
|
||||
|
||||
def form_choix_jour_saisie_hebdo(context, groups_infos, REQUEST=None):
|
||||
"""Formulaire choix jour semaine pour saisie.
|
||||
"""
|
||||
"""Formulaire choix jour semaine pour saisie."""
|
||||
authuser = REQUEST.AUTHENTICATED_USER
|
||||
if not authuser.has_permission(ScoAbsChange, context):
|
||||
return ""
|
||||
@ -893,7 +894,7 @@ def export_groups_as_moodle_csv(context, formsemestre_id=None, REQUEST=None):
|
||||
jo@univ.fr,S3-A
|
||||
jo@univ.fr,S3-B1
|
||||
if jo belongs to group A in a partition, and B1 in another one.
|
||||
Caution: if groups in different partitions share the same name, there will be
|
||||
Caution: if groups in different partitions share the same name, there will be
|
||||
duplicates... should we prefix the group names with the partition's name ?
|
||||
"""
|
||||
if not formsemestre_id:
|
||||
|
@ -28,7 +28,6 @@
|
||||
"""Form. pour inscription rapide des etudiants d'un semestre dans un autre
|
||||
Utilise les autorisations d'inscription délivrées en jury.
|
||||
"""
|
||||
from sets import Set
|
||||
|
||||
from gen_tables import GenTable
|
||||
|
||||
@ -117,8 +116,7 @@ def list_inscrits(context, formsemestre_id, with_dems=False):
|
||||
|
||||
|
||||
def list_etuds_from_sem(context, src, dst):
|
||||
"""Liste des etudiants du semestre src qui sont autorisés à passer dans le semestre dst.
|
||||
"""
|
||||
"""Liste des etudiants du semestre src qui sont autorisés à passer dans le semestre dst."""
|
||||
target = dst["semestre_id"]
|
||||
dpv = sco_pvjury.dict_pvjury(context, src["formsemestre_id"])
|
||||
if not dpv:
|
||||
@ -274,7 +272,7 @@ def formsemestre_inscr_passage(
|
||||
- on peut choisir les groupes TD, TP, TA
|
||||
- seuls les etudiants non inscrits changent (de groupe)
|
||||
- les etudiants inscrit qui se trouvent décochés sont désinscrits
|
||||
- Confirmation: indiquer les étudiants inscrits et ceux désinscrits, le total courant.
|
||||
- Confirmation: indiquer les étudiants inscrits et ceux désinscrits, le total courant.
|
||||
|
||||
"""
|
||||
inscrit_groupes = int(inscrit_groupes)
|
||||
@ -292,11 +290,11 @@ def formsemestre_inscr_passage(
|
||||
etuds = etuds.split(",") # vient du form de confirmation
|
||||
|
||||
auth_etuds_by_sem, inscrits, candidats = list_authorized_etuds_by_sem(context, sem)
|
||||
etuds_set = Set(etuds)
|
||||
candidats_set = Set(candidats)
|
||||
inscrits_set = Set(inscrits)
|
||||
etuds_set = set(etuds)
|
||||
candidats_set = set(candidats)
|
||||
inscrits_set = set(inscrits)
|
||||
candidats_non_inscrits = candidats_set - inscrits_set
|
||||
inscrits_ailleurs = Set(list_inscrits_date(context, sem))
|
||||
inscrits_ailleurs = set(list_inscrits_date(context, sem))
|
||||
|
||||
def set_to_sorted_etud_list(etudset):
|
||||
etuds = [candidats[etudid] for etudid in etudset]
|
||||
@ -489,7 +487,7 @@ def etuds_select_boxes(
|
||||
"""Boites pour selection étudiants par catégorie
|
||||
auth_etuds_by_cat = { category : { 'info' : {}, 'etuds' : ... }
|
||||
inscrits_ailleurs =
|
||||
sel_inscrits=
|
||||
sel_inscrits=
|
||||
export_cat_xls =
|
||||
"""
|
||||
if export_cat_xls:
|
||||
@ -619,11 +617,8 @@ def etuds_select_box_xls(context, src_cat):
|
||||
"export a box to excel"
|
||||
etuds = src_cat["etuds"]
|
||||
columns_ids = ["etudid", "sexe", "nom", "prenom", "etape"]
|
||||
titles = {}
|
||||
map(
|
||||
lambda x, titles=titles: titles.__setitem__(x[0], x[1]),
|
||||
zip(columns_ids, columns_ids),
|
||||
)
|
||||
titles = {x: x for x in columns_ids}
|
||||
|
||||
# Ajoute colonne paiement inscription
|
||||
columns_ids.append("paiementinscription_str")
|
||||
titles["paiementinscription_str"] = "paiement inscription"
|
||||
|
@ -41,14 +41,12 @@ import sco_excel
|
||||
from gen_tables import GenTable
|
||||
from htmlutils import histogram_notes
|
||||
|
||||
from sets import Set
|
||||
|
||||
|
||||
def do_evaluation_listenotes(context, REQUEST):
|
||||
"""
|
||||
Affichage des notes d'une évaluation
|
||||
|
||||
args: evaluation_id
|
||||
args: evaluation_id
|
||||
"""
|
||||
cnx = context.GetDBConnexion()
|
||||
mode = None
|
||||
@ -267,8 +265,8 @@ def _make_table_notes(
|
||||
"prenom": "Prénom",
|
||||
"nomprenom": "Nom",
|
||||
"expl_key": "Rem.",
|
||||
"email" : "e-mail",
|
||||
"emailperso" : "e-mail perso"
|
||||
"email": "e-mail",
|
||||
"emailperso": "e-mail perso",
|
||||
}
|
||||
|
||||
rows = []
|
||||
@ -323,8 +321,8 @@ def _make_table_notes(
|
||||
"prenom": strcapitalize(strlower(etud["prenom"])),
|
||||
"nomprenom": etud["nomprenom"],
|
||||
"group": grc,
|
||||
"email" : etud["email"],
|
||||
"emailperso" : etud["emailperso"],
|
||||
"email": etud["email"],
|
||||
"emailperso": etud["emailperso"],
|
||||
"_css_row_class": css_row_class or "",
|
||||
}
|
||||
)
|
||||
@ -381,7 +379,7 @@ def _make_table_notes(
|
||||
|
||||
# Si module, ajoute moyenne du module:
|
||||
if len(evals) > 1:
|
||||
notes = _add_moymod_column(
|
||||
_add_moymod_column(
|
||||
context,
|
||||
sem["formsemestre_id"],
|
||||
e,
|
||||
@ -397,7 +395,7 @@ def _make_table_notes(
|
||||
|
||||
# Ajoute colonnes emails tout à droite:
|
||||
if with_emails:
|
||||
columns_ids += [ "email", "emailperso" ]
|
||||
columns_ids += ["email", "emailperso"]
|
||||
# Ajoute lignes en tête et moyennes
|
||||
if len(evals) > 0:
|
||||
rows = [coefs, note_max] + rows
|
||||
@ -646,6 +644,7 @@ def _add_moymod_column(
|
||||
note_sur_20,
|
||||
keep_numeric,
|
||||
):
|
||||
"""Ajoute la colonne moymod à rows"""
|
||||
col_id = "moymod"
|
||||
nt = context._getNotesCache().get_NotesTable(
|
||||
context, formsemestre_id
|
||||
@ -701,7 +700,7 @@ def _eval_demijournee(E):
|
||||
def evaluation_check_absences(context, evaluation_id):
|
||||
"""Vérifie les absences au moment de cette évaluation.
|
||||
Cas incohérents que l'on peut rencontrer pour chaque étudiant:
|
||||
note et absent
|
||||
note et absent
|
||||
ABS et pas noté absent
|
||||
ABS et absent justifié
|
||||
EXC et pas noté absent
|
||||
@ -722,13 +721,13 @@ def evaluation_check_absences(context, evaluation_id):
|
||||
|
||||
# Liste les absences à ce moment:
|
||||
A = context.Absences.ListeAbsJour(DateDMYtoISO(E["jour"]), am=am, pm=pm)
|
||||
As = Set([x["etudid"] for x in A]) # ensemble des etudiants absents
|
||||
As = set([x["etudid"] for x in A]) # ensemble des etudiants absents
|
||||
NJ = context.Absences.ListeAbsNonJustJour(DateDMYtoISO(E["jour"]), am=am, pm=pm)
|
||||
NJs = Set([x["etudid"] for x in NJ]) # ensemble des etudiants absents non justifies
|
||||
NJs = set([x["etudid"] for x in NJ]) # ensemble des etudiants absents non justifies
|
||||
Just = context.Absences.ListeAbsJour(
|
||||
DateDMYtoISO(E["jour"]), am=am, pm=pm, is_abs=None, is_just=True
|
||||
)
|
||||
Justs = Set([x["etudid"] for x in Just]) # ensemble des etudiants avec justif
|
||||
Justs = set([x["etudid"] for x in Just]) # ensemble des etudiants avec justif
|
||||
|
||||
# Les notes:
|
||||
NotesDB = context._notes_getall(evaluation_id)
|
||||
@ -860,8 +859,7 @@ def evaluation_check_absences_html(
|
||||
|
||||
|
||||
def formsemestre_check_absences_html(context, formsemestre_id, REQUEST=None):
|
||||
"""Affiche etat verification absences pour toutes les evaluations du semestre !
|
||||
"""
|
||||
"""Affiche etat verification absences pour toutes les evaluations du semestre !"""
|
||||
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
|
||||
H = [
|
||||
context.html_sem_header(
|
||||
|
@ -27,7 +27,6 @@
|
||||
|
||||
"""Tableau de bord module
|
||||
"""
|
||||
from sets import Set
|
||||
|
||||
from notesdb import *
|
||||
from sco_utils import *
|
||||
|
@ -80,8 +80,7 @@ class DecisionSem:
|
||||
|
||||
|
||||
def SituationEtudParcours(context, etud, formsemestre_id):
|
||||
"""renvoie une instance de SituationEtudParcours (ou sous-classe spécialisée)
|
||||
"""
|
||||
"""renvoie une instance de SituationEtudParcours (ou sous-classe spécialisée)"""
|
||||
nt = context._getNotesCache().get_NotesTable(
|
||||
context, formsemestre_id
|
||||
) # > get_etud_decision_sem, get_etud_moy_gen, get_ues, get_etud_ue_status, etud_check_conditions_ues
|
||||
@ -248,7 +247,7 @@ class SituationEtudParcoursGeneric:
|
||||
decision = self.nt.get_etud_decision_sem(self.etudid)
|
||||
return decision and code_semestre_validant(decision["code"])
|
||||
else:
|
||||
to_validate = Set(
|
||||
to_validate = set(
|
||||
range(1, self.parcours.NB_SEM + 1)
|
||||
) # ensemble des indices à valider
|
||||
if exclude_current and self.sem["semestre_id"] in to_validate:
|
||||
@ -652,8 +651,7 @@ class SituationEtudParcoursGeneric:
|
||||
|
||||
|
||||
class SituationEtudParcoursECTS(SituationEtudParcoursGeneric):
|
||||
"""Gestion parcours basés sur ECTS
|
||||
"""
|
||||
"""Gestion parcours basés sur ECTS"""
|
||||
|
||||
def __init__(self, context, etud, formsemestre_id, nt):
|
||||
SituationEtudParcoursGeneric.__init__(self, context, etud, formsemestre_id, nt)
|
||||
@ -663,7 +661,7 @@ class SituationEtudParcoursECTS(SituationEtudParcoursGeneric):
|
||||
|
||||
def get_possible_choices(self, assiduite=True):
|
||||
"""Listes de décisions "recommandées" (hors décisions manuelles)
|
||||
|
||||
|
||||
Dans ce type de parcours, on n'utilise que ADM, AJ, et ADJ (?).
|
||||
"""
|
||||
etud_moy_infos = self.nt.get_etud_moy_infos(self.etudid)
|
||||
@ -939,8 +937,7 @@ def do_formsemestre_validate_ue(
|
||||
semestre_id=None,
|
||||
is_external=0,
|
||||
):
|
||||
"""Ajoute ou change validation UE
|
||||
"""
|
||||
"""Ajoute ou change validation UE"""
|
||||
args = {
|
||||
"formsemestre_id": formsemestre_id,
|
||||
"etudid": etudid,
|
||||
@ -1026,17 +1023,17 @@ def formsemestre_get_autorisation_inscription(context, etudid, origin_formsemest
|
||||
|
||||
def formsemestre_get_etud_capitalisation(context, sem, etudid):
|
||||
"""Liste des UE capitalisées (ADM) correspondant au semestre sem et à l'étudiant.
|
||||
|
||||
|
||||
Recherche dans les semestres de la même formation (code) avec le même
|
||||
semestre_id et une date de début antérieure à celle du semestre mentionné.
|
||||
Et aussi les UE externes validées.
|
||||
|
||||
|
||||
Resultat: [ { 'formsemestre_id' :
|
||||
'ue_id' : ue_id dans le semestre origine
|
||||
'ue_code' :
|
||||
'ue_code' :
|
||||
'moy_ue' :
|
||||
'event_date' :
|
||||
'is_external'
|
||||
'event_date' :
|
||||
'is_external'
|
||||
} ]
|
||||
"""
|
||||
cnx = context.GetDBConnexion()
|
||||
|
@ -28,7 +28,16 @@
|
||||
"""Liaison avec le portail ENT (qui donne accès aux infos Apogée)
|
||||
"""
|
||||
|
||||
from sco_utils import *
|
||||
import os, time
|
||||
import urllib
|
||||
import xml
|
||||
import xml.sax.saxutils
|
||||
import xml.dom.minidom
|
||||
import datetime
|
||||
|
||||
import sco_utils
|
||||
from sco_utils import ScoEtudInscrit, log, ScoValueError, DictDefault
|
||||
from sco_utils import SCO_TMPDIR, SCO_ENCODING
|
||||
|
||||
SCO_CACHE_ETAPE_FILENAME = os.path.join(SCO_TMPDIR, "last_etapes.xml")
|
||||
|
||||
@ -153,7 +162,7 @@ def get_inscrits_etape(context, code_etape, anneeapogee=None, ntrials=2):
|
||||
if portal_timeout > 0:
|
||||
actual_timeout = max(1, actual_timeout)
|
||||
for _ntrial in range(ntrials):
|
||||
doc = query_portal(req, timeout=actual_timeout)
|
||||
doc = sco_utils.query_portal(req, timeout=actual_timeout)
|
||||
if doc:
|
||||
break
|
||||
if not doc:
|
||||
@ -194,7 +203,7 @@ def query_apogee_portal(context, **args):
|
||||
return []
|
||||
portal_timeout = context.get_preference("portal_timeout")
|
||||
req = etud_url + "?" + urllib.urlencode(args.items())
|
||||
doc = query_portal(req, timeout=portal_timeout) # sco_utils
|
||||
doc = sco_utils.query_portal(req, timeout=portal_timeout) # sco_utils
|
||||
return xml_to_list_of_dicts(doc, req=req)
|
||||
|
||||
|
||||
@ -250,7 +259,7 @@ def get_infos_apogee_allaccents(context, nom, prenom):
|
||||
"essai recup infos avec differents codages des accents"
|
||||
if nom:
|
||||
unom = unicode(nom, SCO_ENCODING)
|
||||
nom_noaccents = str(suppression_diacritics(unom))
|
||||
nom_noaccents = str(sco_utils.suppression_diacritics(unom))
|
||||
nom_utf8 = unom.encode("utf-8")
|
||||
else:
|
||||
nom_noaccents = nom
|
||||
@ -258,7 +267,7 @@ def get_infos_apogee_allaccents(context, nom, prenom):
|
||||
|
||||
if prenom:
|
||||
uprenom = unicode(prenom, SCO_ENCODING)
|
||||
prenom_noaccents = str(suppression_diacritics(uprenom))
|
||||
prenom_noaccents = str(sco_utils.suppression_diacritics(uprenom))
|
||||
prenom_utf8 = uprenom.encode("utf-8")
|
||||
else:
|
||||
prenom_noaccents = prenom
|
||||
@ -314,7 +323,7 @@ def get_etud_apogee(context, code_nip):
|
||||
return {}
|
||||
portal_timeout = context.get_preference("portal_timeout")
|
||||
req = etud_url + "?" + urllib.urlencode((("nip", code_nip),))
|
||||
doc = query_portal(req, timeout=portal_timeout)
|
||||
doc = sco_utils.query_portal(req, timeout=portal_timeout)
|
||||
d = _normalize_apo_fields(xml_to_list_of_dicts(doc, req=req))
|
||||
if not d:
|
||||
return None
|
||||
@ -378,7 +387,7 @@ def get_etapes_apogee(context):
|
||||
"get_etapes_apogee: requesting '%s' with timeout=%s"
|
||||
% (etapes_url, portal_timeout)
|
||||
)
|
||||
doc = query_portal(etapes_url, timeout=portal_timeout)
|
||||
doc = sco_utils.query_portal(etapes_url, timeout=portal_timeout)
|
||||
try:
|
||||
infos = _parse_etapes_from_xml(context, doc)
|
||||
# cache le resultat (utile si le portail repond de façon intermitente)
|
||||
@ -473,7 +482,7 @@ def _normalize_apo_fields(infolist):
|
||||
for infos in infolist:
|
||||
if infos.has_key("paiementinscription"):
|
||||
infos["paiementinscription"] = (
|
||||
strlower(infos["paiementinscription"]) == "true"
|
||||
sco_utils.strlower(infos["paiementinscription"]) == "true"
|
||||
)
|
||||
if infos["paiementinscription"]:
|
||||
infos["paiementinscription_str"] = "ok"
|
||||
@ -553,5 +562,5 @@ def get_maquette_apogee(context, etape="", annee_scolaire=""):
|
||||
+ "?"
|
||||
+ urllib.urlencode((("etape", etape), ("annee", annee_scolaire)))
|
||||
)
|
||||
doc = query_portal(req, timeout=portal_timeout)
|
||||
doc = sco_utils.query_portal(req, timeout=portal_timeout)
|
||||
return doc
|
||||
|
@ -596,6 +596,8 @@ def formsemestre_pvjury_pdf(
|
||||
Si etudid, PV pour un seul etudiant. Sinon, tout les inscrits au groupe indiqué.
|
||||
"""
|
||||
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
|
||||
# Mise à jour des groupes d'étapes:
|
||||
sco_groups.create_etapes_partition(context, formsemestre_id)
|
||||
groups_infos = None
|
||||
if etudid:
|
||||
# PV pour ce seul étudiant:
|
||||
@ -635,7 +637,7 @@ def formsemestre_pvjury_pdf(
|
||||
</p>""",
|
||||
context.sco_footer(REQUEST),
|
||||
]
|
||||
descr = descrform_pvjury(sem)
|
||||
descr = descrform_pvjury(context, sem)
|
||||
if etudid:
|
||||
descr.append(("etudid", {"input_type": "hidden"}))
|
||||
|
||||
@ -690,6 +692,7 @@ def formsemestre_pvjury_pdf(
|
||||
date_commission=tf[2]["date_commission"],
|
||||
date_jury=tf[2]["date_jury"],
|
||||
showTitle=tf[2]["showTitle"],
|
||||
pv_title=tf[2]["pv_title"],
|
||||
with_paragraph_nom=tf[2]["with_paragraph_nom"],
|
||||
anonymous=tf[2]["anonymous"],
|
||||
)
|
||||
@ -705,8 +708,9 @@ def formsemestre_pvjury_pdf(
|
||||
return sendPDFFile(REQUEST, pdfdoc, filename)
|
||||
|
||||
|
||||
def descrform_pvjury(sem):
|
||||
def descrform_pvjury(context, sem):
|
||||
"""Définition de formulaire pour PV jury PDF"""
|
||||
F = context.Notes.formation_list(formation_id=sem["formation_id"])[0]
|
||||
return [
|
||||
(
|
||||
"date_commission",
|
||||
@ -744,11 +748,21 @@ def descrform_pvjury(sem):
|
||||
"explanation": "VDI et code du diplôme Apogée (format libre, n'est pas vérifié par ScoDoc)",
|
||||
},
|
||||
),
|
||||
(
|
||||
"pv_title",
|
||||
{
|
||||
"input_type": "text",
|
||||
"size": 64,
|
||||
"title": "Titre du PV",
|
||||
"explanation": "par défaut, titre officiel de la formation",
|
||||
"default": F["titre_officiel"],
|
||||
},
|
||||
),
|
||||
(
|
||||
"showTitle",
|
||||
{
|
||||
"input_type": "checkbox",
|
||||
"title": "Indiquer le titre du semestre sur le PV",
|
||||
"title": "Indiquer en plus le titre du semestre sur le PV",
|
||||
"explanation": '(le titre est "%s")' % sem["titre"],
|
||||
"labels": [""],
|
||||
"allowed_values": ("1",),
|
||||
|
@ -592,6 +592,7 @@ def pvjury_pdf(
|
||||
numeroArrete=None,
|
||||
VDICode=None,
|
||||
showTitle=False,
|
||||
pv_title=None,
|
||||
with_paragraph_nom=False,
|
||||
anonymous=False,
|
||||
):
|
||||
@ -613,6 +614,7 @@ def pvjury_pdf(
|
||||
VDICode=VDICode,
|
||||
date_jury=date_jury,
|
||||
showTitle=showTitle,
|
||||
pv_title=pv_title,
|
||||
with_paragraph_nom=with_paragraph_nom,
|
||||
anonymous=anonymous,
|
||||
)
|
||||
@ -635,6 +637,7 @@ def pvjury_pdf(
|
||||
numeroArrete=numeroArrete,
|
||||
VDICode=VDICode,
|
||||
showTitle=showTitle,
|
||||
pv_title=pv_title,
|
||||
with_paragraph_nom=with_paragraph_nom,
|
||||
anonymous=anonymous,
|
||||
)
|
||||
@ -668,6 +671,7 @@ def _pvjury_pdf_type(
|
||||
numeroArrete=None,
|
||||
VDICode=None,
|
||||
showTitle=False,
|
||||
pv_title=None,
|
||||
anonymous=False,
|
||||
with_paragraph_nom=False,
|
||||
):
|
||||
@ -680,7 +684,7 @@ def _pvjury_pdf_type(
|
||||
sem = dpv["formsemestre"]
|
||||
formsemestre_id = sem["formsemestre_id"]
|
||||
titre_jury, titre_court_jury = _descr_jury(sem, diplome)
|
||||
titre_diplome = dpv["formation"]["titre_officiel"]
|
||||
titre_diplome = pv_title or dpv["formation"]["titre_officiel"]
|
||||
objects = []
|
||||
|
||||
style = reportlab.lib.styles.ParagraphStyle({})
|
||||
|
@ -35,6 +35,7 @@ import sco_evaluations
|
||||
import sco_formsemestre
|
||||
import sco_formsemestre_status
|
||||
import sco_bulletins_xml
|
||||
import sco_bulletins_json
|
||||
import sco_codes_parcours
|
||||
import sco_bac
|
||||
|
||||
@ -71,7 +72,7 @@ def formsemestre_recapcomplet(
|
||||
else:
|
||||
hidebac = int(hidebac)
|
||||
xml_with_decisions = int(xml_with_decisions)
|
||||
isFile = tabformat in ("csv", "xls", "xml", "xlsall")
|
||||
isFile = tabformat in ("csv", "xls", "xml", "xlsall", "json")
|
||||
H = []
|
||||
if not isFile:
|
||||
H += [
|
||||
@ -103,6 +104,7 @@ def formsemestre_recapcomplet(
|
||||
("xlsall", "Fichier tableur avec toutes les évals"),
|
||||
("csv", "Fichier tableur (CSV)"),
|
||||
("xml", "Fichier XML"),
|
||||
("json", "JSON"),
|
||||
):
|
||||
if format == tabformat:
|
||||
selected = " selected"
|
||||
@ -129,8 +131,7 @@ def formsemestre_recapcomplet(
|
||||
H.append("checked")
|
||||
H.append(""" >cacher bac</input>""")
|
||||
if tabformat == "xml":
|
||||
REQUEST.RESPONSE.setHeader("content-type", "text/xml")
|
||||
|
||||
REQUEST.RESPONSE.setHeader("content-type", XML_MIMETYPE)
|
||||
H.append(
|
||||
do_formsemestre_recapcomplet(
|
||||
context,
|
||||
@ -181,7 +182,7 @@ def do_formsemestre_recapcomplet(
|
||||
context=None,
|
||||
REQUEST=None,
|
||||
formsemestre_id=None,
|
||||
format="html", # html, xml, xls, xlsall
|
||||
format="html", # html, xml, xls, xlsall, json
|
||||
hidemodules=False, # ne pas montrer les modules (ignoré en XML)
|
||||
hidebac=False, # pas de colonne Bac (ignoré en XML)
|
||||
xml_nodate=False, # format XML sans dates (sert pour debug cache: comparaison de XML)
|
||||
@ -191,8 +192,7 @@ def do_formsemestre_recapcomplet(
|
||||
disable_etudlink=False,
|
||||
rank_partition_id=None, # si None, calcul rang global
|
||||
):
|
||||
"""Calcule et renvoie le tableau récapitulatif.
|
||||
"""
|
||||
"""Calcule et renvoie le tableau récapitulatif."""
|
||||
data, filename, format = make_formsemestre_recapcomplet(**vars())
|
||||
if format == "xml" or format == "html":
|
||||
return data
|
||||
@ -200,6 +200,8 @@ def do_formsemestre_recapcomplet(
|
||||
return sendCSVFile(REQUEST, data, filename)
|
||||
elif format[:3] == "xls":
|
||||
return sco_excel.sendExcelFile(REQUEST, data, filename)
|
||||
elif format == "json":
|
||||
return sendJSON(REQUEST, data)
|
||||
else:
|
||||
raise ValueError("unknown format %s" % format)
|
||||
|
||||
@ -208,7 +210,7 @@ def make_formsemestre_recapcomplet(
|
||||
context=None,
|
||||
REQUEST=None,
|
||||
formsemestre_id=None,
|
||||
format="html", # html, xml, xls, xlsall
|
||||
format="html", # html, xml, xls, xlsall, json
|
||||
hidemodules=False, # ne pas montrer les modules (ignoré en XML)
|
||||
hidebac=False, # pas de colonne Bac (ignoré en XML)
|
||||
xml_nodate=False, # format XML sans dates (sert pour debug cache: comparaison de XML)
|
||||
@ -226,6 +228,10 @@ def make_formsemestre_recapcomplet(
|
||||
return _formsemestre_recapcomplet_xml(
|
||||
context, formsemestre_id, xml_nodate, xml_with_decisions=xml_with_decisions
|
||||
)
|
||||
elif format == "json":
|
||||
return _formsemestre_recapcomplet_json(
|
||||
context, formsemestre_id, xml_nodate, xml_with_decisions=xml_with_decisions
|
||||
)
|
||||
if format[:3] == "xls":
|
||||
keep_numeric = True # pas de conversion des notes en strings
|
||||
else:
|
||||
@ -261,7 +267,7 @@ def make_formsemestre_recapcomplet(
|
||||
else:
|
||||
rank_partition = sco_groups.get_default_partition(context, formsemestre_id)
|
||||
rank_label = "Rg"
|
||||
|
||||
|
||||
T = nt.get_table_moyennes_triees()
|
||||
if not T:
|
||||
return "", "", format
|
||||
@ -556,19 +562,18 @@ def make_formsemestre_recapcomplet(
|
||||
cls = "recap_tit_ue"
|
||||
else:
|
||||
cls = "recap_tit"
|
||||
if i == 0 or F[0][i] == "classement": # Rang: force tri numerique pour sortable
|
||||
if (
|
||||
i == 0 or F[0][i] == "classement"
|
||||
): # Rang: force tri numerique pour sortable
|
||||
cls = cls + " sortnumeric"
|
||||
if cod2mod.has_key(F[0][i]): # lien vers etat module
|
||||
mod = cod2mod[F[0][i]]
|
||||
cells += (
|
||||
'<td class="%s"><a href="moduleimpl_status?moduleimpl_id=%s" title="%s (%s)">%s</a></td>'
|
||||
% (
|
||||
cls,
|
||||
mod["moduleimpl_id"],
|
||||
mod["module"]["titre"],
|
||||
context.Users.user_info(mod["responsable_id"])["nomcomplet"],
|
||||
F[0][i],
|
||||
)
|
||||
cells += '<td class="%s"><a href="moduleimpl_status?moduleimpl_id=%s" title="%s (%s)">%s</a></td>' % (
|
||||
cls,
|
||||
mod["moduleimpl_id"],
|
||||
mod["module"]["titre"],
|
||||
context.Users.user_info(mod["responsable_id"])["nomcomplet"],
|
||||
F[0][i],
|
||||
)
|
||||
else:
|
||||
cells += '<td class="%s">%s</td>' % (cls, F[0][i])
|
||||
@ -788,8 +793,7 @@ def _list_notes_evals_stats(context, evals, key):
|
||||
def _formsemestre_recapcomplet_xml(
|
||||
context, formsemestre_id, xml_nodate, xml_with_decisions=False
|
||||
):
|
||||
"XML export: liste tous les bulletins XML"
|
||||
# REQUEST.RESPONSE.setHeader('content-type', XML_MIMETYPE)
|
||||
"XML export: liste tous les bulletins XML."
|
||||
|
||||
nt = context._getNotesCache().get_NotesTable(
|
||||
context, formsemestre_id
|
||||
@ -827,3 +831,42 @@ def _formsemestre_recapcomplet_xml(
|
||||
)
|
||||
doc._pop()
|
||||
return repr(doc), "", "xml"
|
||||
|
||||
|
||||
def _formsemestre_recapcomplet_json(
|
||||
context, formsemestre_id, xml_nodate, xml_with_decisions=False
|
||||
):
|
||||
"JSON export: liste tous les bulletins JSON"
|
||||
if xml_nodate:
|
||||
docdate = ""
|
||||
else:
|
||||
docdate = datetime.datetime.now().isoformat()
|
||||
evals = sco_evaluations.do_evaluation_etat_in_sem(context, formsemestre_id)
|
||||
J = {
|
||||
"docdate": docdate,
|
||||
"formsemestre_id": formsemestre_id,
|
||||
"evals_info": {
|
||||
"nb_evals_completes": evals["nb_evals_completes"],
|
||||
"nb_evals_en_cours": evals["nb_evals_en_cours"],
|
||||
"nb_evals_vides": evals["nb_evals_vides"],
|
||||
"date_derniere_note": evals["last_modif"],
|
||||
},
|
||||
"bulletins": [],
|
||||
}
|
||||
bulletins = J["bulletins"]
|
||||
nt = context._getNotesCache().get_NotesTable(
|
||||
context, formsemestre_id
|
||||
) # > get_table_moyennes_triees
|
||||
T = nt.get_table_moyennes_triees()
|
||||
for t in T:
|
||||
etudid = t[-1]
|
||||
bulletins.append(
|
||||
sco_bulletins_json.formsemestre_bulletinetud_published_dict(
|
||||
context,
|
||||
formsemestre_id,
|
||||
etudid,
|
||||
force_publishing=True,
|
||||
xml_with_decisions=xml_with_decisions,
|
||||
)
|
||||
)
|
||||
return J, "", "json"
|
||||
|
@ -29,8 +29,8 @@
|
||||
- statistiques decisions
|
||||
- suivi cohortes
|
||||
"""
|
||||
from mx.DateTime import DateTime as mxDateTime
|
||||
import mx.DateTime
|
||||
from mx.DateTime import DateTime as mxDateTime
|
||||
import tempfile, urllib, re
|
||||
|
||||
|
||||
@ -396,12 +396,12 @@ def table_suivi_cohorte(
|
||||
|
||||
logt("A: orig etuds set")
|
||||
S = {formsemestre_id: sem} # ensemble de formsemestre_id
|
||||
orig_set = Set() # ensemble d'etudid du semestre d'origine
|
||||
bacs = Set()
|
||||
bacspecialites = Set()
|
||||
annee_bacs = Set()
|
||||
sexes = Set()
|
||||
statuts = Set()
|
||||
orig_set = set() # ensemble d'etudid du semestre d'origine
|
||||
bacs = set()
|
||||
bacspecialites = set()
|
||||
annee_bacs = set()
|
||||
sexes = set()
|
||||
statuts = set()
|
||||
for etudid in etudids:
|
||||
etud = context.getEtudInfo(etudid=etudid, filled=True)[0]
|
||||
bacspe = etud["bac"] + " / " + etud["specialite"]
|
||||
@ -429,7 +429,7 @@ def table_suivi_cohorte(
|
||||
# tri les semestres par date de debut
|
||||
for s in sems:
|
||||
d, m, y = [int(x) for x in s["date_debut"].split("/")]
|
||||
s["date_debut_mx"] = mxDateTime(y, m, d)
|
||||
s["date_debut_mx"] = mxDateTime(y, m, d) # pylint: disable=not-callable
|
||||
sems.sort(lambda x, y: cmp(x["date_debut_mx"], y["date_debut_mx"]))
|
||||
|
||||
# 2-- Pour chaque semestre, trouve l'ensemble des etudiants venant de sem
|
||||
@ -438,8 +438,8 @@ def table_suivi_cohorte(
|
||||
for s in sems:
|
||||
ins = context.do_formsemestre_inscription_list(
|
||||
args={"formsemestre_id": s["formsemestre_id"]}
|
||||
) # avec dems
|
||||
inset = Set([i["etudid"] for i in ins])
|
||||
) # sans dems
|
||||
inset = set([i["etudid"] for i in ins])
|
||||
s["members"] = orig_set.intersection(inset)
|
||||
nb_dipl = 0 # combien de diplomes dans ce semestre ?
|
||||
if s["semestre_id"] == nt.parcours.NB_SEM:
|
||||
@ -461,7 +461,7 @@ def table_suivi_cohorte(
|
||||
# semestre de depart:
|
||||
porigin = periodsem()
|
||||
d, m, y = [int(x) for x in sem["date_debut"].split("/")]
|
||||
porigin.datedebut = mxDateTime(y, m, d)
|
||||
porigin.datedebut = mxDateTime(y, m, d) # pylint: disable=not-callable
|
||||
porigin.sems = [sem]
|
||||
|
||||
#
|
||||
@ -480,7 +480,7 @@ def table_suivi_cohorte(
|
||||
P.append(p)
|
||||
|
||||
# 4-- regroupe par indice de semestre S_i
|
||||
indices_sems = list(Set([s["semestre_id"] for s in sems]))
|
||||
indices_sems = list(set([s["semestre_id"] for s in sems]))
|
||||
indices_sems.sort()
|
||||
for p in P:
|
||||
p.nb_etuds = 0 # nombre total d'etudiants dans la periode
|
||||
@ -518,7 +518,7 @@ def table_suivi_cohorte(
|
||||
d = {"row_title": "Autre semestre"}
|
||||
|
||||
for p in P:
|
||||
etuds_period = Set()
|
||||
etuds_period = set()
|
||||
for s in p.sems:
|
||||
if s["semestre_id"] == idx_sem:
|
||||
etuds_period = etuds_period.union(s["members"])
|
||||
@ -533,8 +533,8 @@ def table_suivi_cohorte(
|
||||
logt("D: cout dems reos")
|
||||
sem["dems"], sem["reos"] = _count_dem_reo(context, formsemestre_id, sem["members"])
|
||||
for p in P:
|
||||
p.dems = Set()
|
||||
p.reos = Set()
|
||||
p.dems = set()
|
||||
p.reos = set()
|
||||
for s in p.sems:
|
||||
d, r = _count_dem_reo(context, s["formsemestre_id"], s["members"])
|
||||
p.dems.update(d)
|
||||
@ -879,8 +879,8 @@ def _count_dem_reo(context, formsemestre_id, etudids):
|
||||
nt = context._getNotesCache().get_NotesTable(
|
||||
context, formsemestre_id
|
||||
) # > get_etud_etat, get_etud_decision_sem
|
||||
dems = Set()
|
||||
reos = Set()
|
||||
dems = set()
|
||||
reos = set()
|
||||
for etudid in etudids:
|
||||
if nt.get_etud_etat(etudid) == "D":
|
||||
dems.add(etudid)
|
||||
@ -994,11 +994,11 @@ def tsp_etud_list(
|
||||
) # > get_etudids,
|
||||
etudids = nt.get_etudids()
|
||||
etuds = []
|
||||
bacs = Set()
|
||||
bacspecialites = Set()
|
||||
annee_bacs = Set()
|
||||
sexes = Set()
|
||||
statuts = Set()
|
||||
bacs = set()
|
||||
bacspecialites = set()
|
||||
annee_bacs = set()
|
||||
sexes = set()
|
||||
statuts = set()
|
||||
for etudid in etudids:
|
||||
etud = context.getEtudInfo(etudid=etudid, filled=True)[0]
|
||||
bacspe = etud["bac"] + " / " + etud["specialite"]
|
||||
@ -1228,25 +1228,25 @@ def graph_parcours(
|
||||
if not etuds:
|
||||
return "", etuds, bacs, bacspecialites, annee_bacs, sexes, statuts
|
||||
edges = DictDefault(
|
||||
defaultvalue=Set()
|
||||
defaultvalue=set()
|
||||
) # {(formsemestre_id_origin, formsemestre_id_dest) : etud_set}
|
||||
sems = {}
|
||||
effectifs = DictDefault(defaultvalue=Set()) # formsemestre_id : etud_set
|
||||
effectifs = DictDefault(defaultvalue=set()) # formsemestre_id : etud_set
|
||||
decisions = DictDefault(defaultvalue={}) # formsemestre_id : { code : nb_etud }
|
||||
isolated_nodes = []
|
||||
connected_nodes = Set()
|
||||
connected_nodes = set()
|
||||
diploma_nodes = []
|
||||
dem_nodes = {} # formsemestre_id : noeud pour demissionnaires
|
||||
nar_nodes = {} # formsemestre_id : noeud pour NAR
|
||||
for etud in etuds:
|
||||
next = None
|
||||
nxt = None
|
||||
etudid = etud["etudid"]
|
||||
for s in etud["sems"]: # du plus recent au plus ancien
|
||||
nt = context._getNotesCache().get_NotesTable(
|
||||
context, s["formsemestre_id"]
|
||||
) # > get_etud_decision_sem, get_etud_etat
|
||||
dec = nt.get_etud_decision_sem(etudid)
|
||||
if next:
|
||||
if nxt:
|
||||
if (
|
||||
s["semestre_id"] == nt.parcours.NB_SEM
|
||||
and dec
|
||||
@ -1255,17 +1255,17 @@ def graph_parcours(
|
||||
):
|
||||
# cas particulier du diplome puis poursuite etude
|
||||
edges[
|
||||
("_dipl_" + s["formsemestre_id"], next["formsemestre_id"])
|
||||
("_dipl_" + s["formsemestre_id"], nxt["formsemestre_id"])
|
||||
].add(etudid)
|
||||
else:
|
||||
edges[(s["formsemestre_id"], next["formsemestre_id"])].add(etudid)
|
||||
edges[(s["formsemestre_id"], nxt["formsemestre_id"])].add(etudid)
|
||||
connected_nodes.add(s["formsemestre_id"])
|
||||
connected_nodes.add(next["formsemestre_id"])
|
||||
connected_nodes.add(nxt["formsemestre_id"])
|
||||
else:
|
||||
isolated_nodes.append(s["formsemestre_id"])
|
||||
sems[s["formsemestre_id"]] = s
|
||||
effectifs[s["formsemestre_id"]].add(etudid)
|
||||
next = s
|
||||
nxt = s
|
||||
# Compte decisions jury de chaque semestres:
|
||||
dc = decisions[s["formsemestre_id"]]
|
||||
if dec:
|
||||
|
@ -29,8 +29,8 @@
|
||||
"""
|
||||
|
||||
|
||||
from sco_utils import *
|
||||
from notesdb import *
|
||||
from sco_utils import ScoEtudInscrit, annee_scolaire_debut, log, ScoValueError
|
||||
from notesdb import ScoDocCursor
|
||||
|
||||
import sco_portal_apogee
|
||||
import sco_inscr_passage
|
||||
@ -597,6 +597,7 @@ def do_import_etuds_from_portal(context, sem, a_importer, etudsapo_ident, REQUES
|
||||
# Les champs suivants sont facultatifs (pas toujours renvoyés par le portail)
|
||||
"code_ine": etud.get("ine", "").strip(),
|
||||
"sexe": gender2sex(etud["gender"].strip()),
|
||||
"etape": etud.get("etape", None),
|
||||
"email": etud.get("mail", "").strip(),
|
||||
"emailperso": etud.get("mailperso", "").strip(),
|
||||
"date_naissance": etud.get("naissance", "").strip(),
|
||||
@ -619,7 +620,7 @@ def do_import_etuds_from_portal(context, sem, a_importer, etudsapo_ident, REQUES
|
||||
do_import_etud_admission(context, cnx, args["etudid"], etud)
|
||||
|
||||
# Adresse
|
||||
adresse_id = scolars.adresse_create(cnx, args)
|
||||
scolars.adresse_create(cnx, args)
|
||||
|
||||
# Inscription au semestre
|
||||
sco_formsemestre_inscriptions.do_formsemestre_inscription_with_modules(
|
||||
@ -627,6 +628,7 @@ def do_import_etuds_from_portal(context, sem, a_importer, etudsapo_ident, REQUES
|
||||
sem["formsemestre_id"],
|
||||
args["etudid"],
|
||||
etat="I",
|
||||
etape=args["etape"],
|
||||
REQUEST=REQUEST,
|
||||
method="synchro_apogee",
|
||||
)
|
||||
@ -696,7 +698,7 @@ def do_import_etud_admission(
|
||||
log("do_import_etud_admission: etud=%s" % etud)
|
||||
al = scolars.admission_list(cnx, args={"etudid": etudid})
|
||||
if not al:
|
||||
adm_id = scolars.admission_create(cnx, args)
|
||||
scolars.admission_create(cnx, args) # -> adm_id
|
||||
else:
|
||||
# existing data: merge
|
||||
e = al[0]
|
||||
@ -754,6 +756,18 @@ def get_bac(etud):
|
||||
return serie_bac, spe_bac
|
||||
|
||||
|
||||
def update_etape_formsemestre_inscription(context, ins, etud):
|
||||
"""Met à jour l'étape de l'inscription.
|
||||
|
||||
Args:
|
||||
ins (dict): formsemestre_inscription
|
||||
etud (dict): etudiant portail Apo
|
||||
"""
|
||||
if etud["etape"] != ins["etape"]:
|
||||
ins["etape"] = etud["etape"]
|
||||
context.do_formsemestre_inscription_edit(args=ins)
|
||||
|
||||
|
||||
def formsemestre_import_etud_admission(
|
||||
context, formsemestre_id, import_identite=True, import_email=False
|
||||
):
|
||||
@ -797,6 +811,7 @@ def formsemestre_import_etud_admission(
|
||||
# pas vu dans les etudiants de l'étape, tente en individuel
|
||||
etud = sco_portal_apogee.get_etud_apogee(context, code_nip)
|
||||
if etud:
|
||||
update_etape_formsemestre_inscription(context, i, etud)
|
||||
do_import_etud_admission(
|
||||
context,
|
||||
cnx,
|
||||
|
11
sco_utils.py
11
sco_utils.py
@ -61,8 +61,6 @@ except ImportError:
|
||||
# fallback for very old ScoDoc instances
|
||||
STRING_TYPES = StringType
|
||||
|
||||
from sets import Set
|
||||
|
||||
from PIL import Image as PILImage
|
||||
|
||||
# XML generation package (apt-get install jaxml)
|
||||
@ -215,6 +213,7 @@ if SCO_SRCDIR:
|
||||
SCO_SRCDIR += "/"
|
||||
else:
|
||||
SCO_SRCDIR = "/opt/scodoc/Products/ScoDoc/" # debug mode
|
||||
CONFIG = None
|
||||
try:
|
||||
_config_filename = SCO_SRCDIR + "config/scodoc_config.py"
|
||||
_config_text = open(_config_filename).read()
|
||||
@ -512,7 +511,7 @@ def make_filename(name):
|
||||
VALID_CARS = (
|
||||
"-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_.!" # no / !
|
||||
)
|
||||
VALID_CARS_SET = Set(VALID_CARS)
|
||||
VALID_CARS_SET = set(VALID_CARS)
|
||||
VALID_EXP = re.compile("^[" + VALID_CARS + "]+$")
|
||||
|
||||
|
||||
@ -558,12 +557,14 @@ def sendPDFFile(REQUEST, data, filename):
|
||||
|
||||
|
||||
class ScoDocJSONEncoder(json.JSONEncoder):
|
||||
def default(self, o):
|
||||
def default(self, o): # pylint: disable=E0202
|
||||
import sco_formsemestre
|
||||
|
||||
# horrible hack pour encoder les dates
|
||||
# horrible hack pour encoder les dates mx
|
||||
if str(type(o)) == "<type 'mx.DateTime.DateTime'>":
|
||||
return o.strftime("%Y-%m-%dT%H:%M:%S")
|
||||
if isinstance(o, (datetime.date, datetime.datetime)):
|
||||
return o.isoformat()
|
||||
elif isinstance(o, sco_formsemestre.ApoEtapeVDI):
|
||||
return str(o)
|
||||
else:
|
||||
|
Loading…
Reference in New Issue
Block a user