forked from ScoDoc/ScoDoc
sco_placement: feuilles placement étudiants évaluation: modernisation code.
This commit is contained in:
parent
f8db40ffc0
commit
fdc01a5c3b
@ -26,7 +26,8 @@ class MultiSelect:
|
|||||||
HTML : group_ids="val1"&group_ids="val2"...
|
HTML : group_ids="val1"&group_ids="val2"...
|
||||||
JS : ["val1","val2", ...]
|
JS : ["val1","val2", ...]
|
||||||
|
|
||||||
**kwargs: Arguments supplémentaires (appliqué au multiselect en HTML <multi-select key="value" ...>)
|
**kwargs: Arguments supplémentaires (appliqués au multiselect en
|
||||||
|
HTML <multi-select key="value" ...>)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
@ -61,7 +62,8 @@ class MultiSelect:
|
|||||||
for value in values:
|
for value in values:
|
||||||
selected = "selected" if value.get("selected", False) else ""
|
selected = "selected" if value.get("selected", False) else ""
|
||||||
single = "single" if value.get("single", False) else ""
|
single = "single" if value.get("single", False) else ""
|
||||||
opt = f"<option value='{value.get('value')}' {selected} {single} >{value.get('label')}</option>"
|
opt = f"""<option value='{value.get('value')}' {selected} {single} >{
|
||||||
|
value.get('label')}</option>"""
|
||||||
optgroup += opt
|
optgroup += opt
|
||||||
optgroup += "</optgroup>"
|
optgroup += "</optgroup>"
|
||||||
opts.append(optgroup)
|
opts.append(optgroup)
|
||||||
|
@ -48,23 +48,16 @@ from wtforms import (
|
|||||||
HiddenField,
|
HiddenField,
|
||||||
SelectMultipleField,
|
SelectMultipleField,
|
||||||
)
|
)
|
||||||
from app.models import Evaluation, Module, ModuleImpl
|
from app.models import Evaluation, Identite, ModuleImpl
|
||||||
import app.scodoc.sco_utils as scu
|
import app.scodoc.sco_utils as scu
|
||||||
import app.scodoc.notesdb as ndb
|
|
||||||
from app.scodoc import sco_preferences
|
from app.scodoc import sco_preferences
|
||||||
from app.scodoc import sco_evaluations
|
from app.scodoc import sco_evaluations
|
||||||
from app.scodoc import sco_excel
|
from app.scodoc import sco_excel
|
||||||
from app.scodoc.sco_excel import ScoExcelBook, COLORS
|
from app.scodoc.sco_excel import ScoExcelBook, COLORS
|
||||||
from app.scodoc import sco_formsemestre
|
|
||||||
from app.scodoc import sco_groups
|
from app.scodoc import sco_groups
|
||||||
from app.scodoc import sco_moduleimpl
|
|
||||||
from app.scodoc.gen_tables import GenTable
|
from app.scodoc.gen_tables import GenTable
|
||||||
from app.scodoc import sco_etud
|
|
||||||
import sco_version
|
import sco_version
|
||||||
|
|
||||||
_ = lambda x: x # sans babel
|
|
||||||
_l = _
|
|
||||||
|
|
||||||
COORD = "Coordonnées"
|
COORD = "Coordonnées"
|
||||||
SEQ = "Continue"
|
SEQ = "Continue"
|
||||||
|
|
||||||
@ -83,11 +76,9 @@ def _get_group_info(evaluation_id):
|
|||||||
if partition not in groups_tree:
|
if partition not in groups_tree:
|
||||||
groups_tree[partition] = {}
|
groups_tree[partition] = {}
|
||||||
groups_tree[partition][group_name] = group_id
|
groups_tree[partition][group_name] = group_id
|
||||||
if partition != TOUS:
|
has_groups = partition != TOUS
|
||||||
has_groups = True
|
|
||||||
else:
|
nb_groups = sum(len(pg) for pg in groups_tree.values())
|
||||||
has_groups = False
|
|
||||||
nb_groups = sum([len(groups_tree[p]) for p in groups_tree])
|
|
||||||
return groups_tree, has_groups, nb_groups
|
return groups_tree, has_groups, nb_groups
|
||||||
|
|
||||||
|
|
||||||
@ -102,9 +93,9 @@ class PlacementForm(FlaskForm):
|
|||||||
wtforms.validators.DataRequired("indiquez le format du fichier attendu"),
|
wtforms.validators.DataRequired("indiquez le format du fichier attendu"),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
surveillants = StringField("Surveillants", validators=[])
|
surveillants = StringField("Surveillants", validators=[], description="texte libre")
|
||||||
batiment = StringField("Batiment")
|
batiment = StringField("Bâtiment", description="texte libre")
|
||||||
salle = StringField("Salle")
|
salle = StringField("Salle", description="texte libre")
|
||||||
nb_rangs = SelectField(
|
nb_rangs = SelectField(
|
||||||
"nb de places en largeur",
|
"nb de places en largeur",
|
||||||
coerce=int,
|
coerce=int,
|
||||||
@ -139,19 +130,21 @@ class PlacementForm(FlaskForm):
|
|||||||
evaluation_id
|
evaluation_id
|
||||||
)
|
)
|
||||||
choices = []
|
choices = []
|
||||||
for partition in self.groups_tree:
|
for partition, groupes in self.groups_tree.items():
|
||||||
for groupe in self.groups_tree[partition]:
|
for groupe in groupes:
|
||||||
if (
|
if (
|
||||||
groupe == TOUS
|
groupe == TOUS
|
||||||
): # Affichage et valeur spécifique pour le groupe TOUS
|
): # Affichage et valeur spécifique pour le groupe TOUS
|
||||||
self.tous_id = str(self.groups_tree[partition][groupe])
|
self.tous_id = str(groupes[groupe])
|
||||||
choices.append((TOUS, TOUS))
|
choices.append((TOUS, TOUS))
|
||||||
else:
|
else:
|
||||||
groupe_id = str(self.groups_tree[partition][groupe])
|
groupe_id = str(self.groups_tree[partition][groupe])
|
||||||
choices.append((groupe_id, "%s (%s)" % (str(groupe), partition)))
|
choices.append((groupe_id, f"{str(groupe)} ({partition})"))
|
||||||
self.groups.choices = choices
|
self.groups.choices = choices
|
||||||
# self.groups.default = [TOUS] # Ne fonctionnne pas... (ni dans la déclaration de PlaceForm.groups)
|
# self.groups.default = [TOUS] # Ne fonctionnne pas...
|
||||||
# la réponse [] est de toute façon transposée en [ self.tous_id ] lors du traitement (cas du groupe unique)
|
# (ni dans la déclaration de PlaceForm.groups)
|
||||||
|
# la réponse [] est de toute façon transposée en [ self.tous_id ]
|
||||||
|
# lors du traitement (cas du groupe unique)
|
||||||
|
|
||||||
|
|
||||||
class _DistributeurContinu:
|
class _DistributeurContinu:
|
||||||
@ -227,48 +220,34 @@ class PlacementRunner:
|
|||||||
self.file_format = form["file_format"].data
|
self.file_format = form["file_format"].data
|
||||||
if len(form["groups"].data) == 0:
|
if len(form["groups"].data) == 0:
|
||||||
self.groups_ids = [form.tous_id]
|
self.groups_ids = [form.tous_id]
|
||||||
else: # On remplace le mot-clé TOUS le l'identiant de ce groupe
|
else: # On remplace le mot-clé TOUS par l'identifiant de ce groupe
|
||||||
self.groups_ids = [
|
self.groups_ids = [
|
||||||
gid if gid != TOUS else form.tous_id for gid in form["groups"].data
|
gid if gid != TOUS else form.tous_id for gid in form["groups"].data
|
||||||
]
|
]
|
||||||
self.evaluation = Evaluation.get_evaluation(self.evaluation_id)
|
evl = Evaluation.get_evaluation(self.evaluation_id)
|
||||||
|
self.evaluation = evl
|
||||||
self.groups = sco_groups.listgroups(self.groups_ids)
|
self.groups = sco_groups.listgroups(self.groups_ids)
|
||||||
self.gr_title_filename = sco_groups.listgroups_filename(self.groups)
|
self.gr_title_filename = sco_groups.listgroups_filename(self.groups)
|
||||||
# gr_title = sco_groups.listgroups_abbrev(d['groups'])
|
|
||||||
self.current_user = current_user
|
self.current_user = current_user
|
||||||
self.moduleimpl_id = self.evaluation.moduleimpl_id
|
self.moduleimpl_id = evl.moduleimpl_id
|
||||||
self.moduleimpl: ModuleImpl = ModuleImpl.query.get_or_404(self.moduleimpl_id)
|
self.moduleimpl: ModuleImpl = evl.moduleimpl
|
||||||
# TODO: à revoir pour utiliser modèle ModuleImpl
|
self.moduleimpl_data = self.moduleimpl.to_dict()
|
||||||
self.moduleimpl_data = sco_moduleimpl.moduleimpl_list(
|
mod = evl.moduleimpl.module
|
||||||
moduleimpl_id=self.moduleimpl_id
|
self.module_data = mod.to_dict()
|
||||||
)[0]
|
self.evalname = f"""{mod.code or "?"}-{
|
||||||
self.module_data = Module.get_module(
|
evl.date_debut.strftime("%Y-%m-%d_%Hh%M") if evl.date_debut else ""}"""
|
||||||
self.moduleimpl_data["module_id"]
|
if evl.description:
|
||||||
).to_dict()
|
|
||||||
self.sem = sco_formsemestre.get_formsemestre(
|
|
||||||
self.moduleimpl_data["formsemestre_id"]
|
|
||||||
)
|
|
||||||
self.evalname = "%s-%s" % (
|
|
||||||
self.module_data["code"] or "?",
|
|
||||||
(
|
|
||||||
self.evaluation.date_debut.strftime("%Y-%m-%d_%Hh%M")
|
|
||||||
if self.evaluation.date_debut
|
|
||||||
else ""
|
|
||||||
),
|
|
||||||
)
|
|
||||||
if self.evaluation.description:
|
|
||||||
self.evaltitre = self.evaluation.description
|
self.evaltitre = self.evaluation.description
|
||||||
else:
|
else:
|
||||||
self.evaltitre = f"""évaluation{
|
self.evaltitre = f"""évaluation{
|
||||||
self.evaluation.date_debut.strftime(' du %d/%m/%Y à %Hh%M')
|
evl.date_debut.strftime(' du ' + scu.DATEATIME_FMT)
|
||||||
if self.evaluation.date_debut else ''}"""
|
if evl.date_debut else ''}"""
|
||||||
self.desceval = [ # une liste de chaines: description de l'evaluation
|
self.desceval = [ # une liste de chaines: description de l'evaluation
|
||||||
self.sem["titreannee"],
|
evl.moduleimpl.formsemestre.titre_annee(),
|
||||||
"Module : %s - %s"
|
f"""Module : {mod.code or "?"} - {evl.moduleimpl.module.abbrev or ""}""",
|
||||||
% (self.module_data["code"] or "?", self.module_data["abbrev"] or ""),
|
f"Surveillants : {self.surveillants}",
|
||||||
"Surveillants : %s" % self.surveillants,
|
f"Bâtiment : {self.batiment} - Salle : {self.salle}",
|
||||||
"Batiment : %(batiment)s - Salle : %(salle)s" % self.__dict__,
|
f"Évaluation : {self.evaltitre} (coef. {evl.coefficient:g})",
|
||||||
"Controle : %s (coef. %g)" % (self.evaltitre, self.evaluation.coefficient),
|
|
||||||
]
|
]
|
||||||
self.styles = None
|
self.styles = None
|
||||||
self.plan = None
|
self.plan = None
|
||||||
@ -295,26 +274,26 @@ class PlacementRunner:
|
|||||||
self.listetud = self._build_listetud()
|
self.listetud = self._build_listetud()
|
||||||
self.plan = self._affectation_places()
|
self.plan = self._affectation_places()
|
||||||
|
|
||||||
def _build_listetud(self):
|
def _build_listetud(self) -> list[tuple[str, str, int]]:
|
||||||
get_all_students = None in [
|
# tous les etudiants ?
|
||||||
g["group_name"] for g in self.groups
|
get_all_students = None in [g["group_name"] for g in self.groups]
|
||||||
] # tous les etudiants
|
|
||||||
etudid_etats = sco_groups.do_evaluation_listeetuds_groups(
|
etudid_etats = sco_groups.do_evaluation_listeetuds_groups(
|
||||||
self.evaluation_id,
|
self.evaluation_id,
|
||||||
self.groups,
|
self.groups,
|
||||||
getallstudents=get_all_students,
|
getallstudents=get_all_students,
|
||||||
include_demdef=True,
|
include_demdef=True,
|
||||||
)
|
)
|
||||||
listetud = [] # liste de couples (nom,prenom)
|
listetud = [] # liste de tuples (nom, prenom, etudid)
|
||||||
for etudid, etat in etudid_etats:
|
for etudid, etat in etudid_etats:
|
||||||
# infos identite etudiant (xxx sous-optimal: 1/select par etudiant)
|
if etat != scu.DEMISSION:
|
||||||
ident = sco_etud.etudident_list(ndb.GetDBConnexion(), {"etudid": etudid})[0]
|
# infos identite etudiant
|
||||||
if etat != "D":
|
etud = Identite.get_etud(etudid)
|
||||||
nom = ident["nom"].upper()
|
nom = etud.nom.upper()
|
||||||
prenom = ident["prenom"].lower().capitalize()
|
prenom = etud.prenom.lower().capitalize()
|
||||||
etudid = ident["etudid"]
|
listetud.append((nom, prenom, etud.id))
|
||||||
listetud.append((nom, prenom, etudid))
|
|
||||||
random.shuffle(listetud)
|
random.shuffle(listetud)
|
||||||
|
|
||||||
return listetud
|
return listetud
|
||||||
|
|
||||||
def _affectation_places(self):
|
def _affectation_places(self):
|
||||||
@ -328,7 +307,7 @@ class PlacementRunner:
|
|||||||
return plan
|
return plan
|
||||||
|
|
||||||
def _production_xls(self):
|
def _production_xls(self):
|
||||||
filename = "placement_%s_%s" % (self.evalname, self.gr_title_filename)
|
filename = f"placement_{self.evalname}_{self.gr_title_filename}"
|
||||||
xls = self._excel_feuille_placement()
|
xls = self._excel_feuille_placement()
|
||||||
return scu.send_file(xls, filename, scu.XLSX_SUFFIX, mime=scu.XLSX_MIMETYPE)
|
return scu.send_file(xls, filename, scu.XLSX_SUFFIX, mime=scu.XLSX_MIMETYPE)
|
||||||
|
|
||||||
@ -338,10 +317,10 @@ class PlacementRunner:
|
|||||||
if self.evaluation.date_debut else '-'
|
if self.evaluation.date_debut else '-'
|
||||||
} - Horaire : {self.evaluation.heure_debut()} à {self.evaluation.heure_fin()
|
} - Horaire : {self.evaluation.heure_debut()} à {self.evaluation.heure_fin()
|
||||||
}"""
|
}"""
|
||||||
filename = "placement_%(evalname)s_%(gr_title_filename)s" % self.__dict__
|
filename = f"placement_{self.evalname}_{self.gr_title_filename}"
|
||||||
titles = {
|
titles = {
|
||||||
"nom": "Nom",
|
"nom": "Nom",
|
||||||
"prenom": "Prenom",
|
"prenom": "Prénom",
|
||||||
"colonne": "Colonne",
|
"colonne": "Colonne",
|
||||||
"ligne": "Ligne",
|
"ligne": "Ligne",
|
||||||
"place": "Place",
|
"place": "Place",
|
||||||
@ -369,9 +348,7 @@ class PlacementRunner:
|
|||||||
columns_ids=columns_ids,
|
columns_ids=columns_ids,
|
||||||
rows=rows,
|
rows=rows,
|
||||||
filename=filename,
|
filename=filename,
|
||||||
origin="Généré par %s le " % sco_version.SCONAME
|
origin=f"Généré par {sco_version.SCONAME} le {scu.timedate_human_repr()}",
|
||||||
+ scu.timedate_human_repr()
|
|
||||||
+ "",
|
|
||||||
pdf_title=pdf_title,
|
pdf_title=pdf_title,
|
||||||
# pdf_shorttitle = '',
|
# pdf_shorttitle = '',
|
||||||
preferences=sco_preferences.SemPreferences(
|
preferences=sco_preferences.SemPreferences(
|
||||||
@ -476,9 +453,9 @@ class PlacementRunner:
|
|||||||
}
|
}
|
||||||
|
|
||||||
def _titres(self, worksheet):
|
def _titres(self, worksheet):
|
||||||
datetime = time.strftime("%d/%m/%Y a %Hh%M")
|
date_time = time.strftime(scu.DATEATIME_FMT)
|
||||||
worksheet.append_single_cell_row(
|
worksheet.append_single_cell_row(
|
||||||
"Feuille placement etudiants éditée le %s" % datetime, self.styles["titres"]
|
f"Feuille placement etudiants éditée le {date_time}", self.styles["titres"]
|
||||||
)
|
)
|
||||||
for line, desceval in enumerate(self.desceval):
|
for line, desceval in enumerate(self.desceval):
|
||||||
if line in [1, 4, 7]:
|
if line in [1, 4, 7]:
|
||||||
@ -497,7 +474,7 @@ class PlacementRunner:
|
|||||||
# entetes colonnes - feuille0
|
# entetes colonnes - feuille0
|
||||||
cells = [ws0.make_cell()]
|
cells = [ws0.make_cell()]
|
||||||
for col in range(self.nb_rangs):
|
for col in range(self.nb_rangs):
|
||||||
cells.append(ws0.make_cell("colonne %s" % (col + 1), self.styles["2b"]))
|
cells.append(ws0.make_cell(f"colonne {col + 1}", self.styles["2b"]))
|
||||||
ws0.append_row(cells)
|
ws0.append_row(cells)
|
||||||
|
|
||||||
# etudiants - feuille0
|
# etudiants - feuille0
|
||||||
@ -517,7 +494,7 @@ class PlacementRunner:
|
|||||||
if self.etiquetage == COORD:
|
if self.etiquetage == COORD:
|
||||||
cell_c = ws0.make_cell("", self.styles["1bb"])
|
cell_c = ws0.make_cell("", self.styles["1bb"])
|
||||||
else:
|
else:
|
||||||
cell_c = ws0.make_cell("place %s" % place, self.styles["1bb"])
|
cell_c = ws0.make_cell(f"place {place}", self.styles["1bb"])
|
||||||
place = place + 1
|
place = place + 1
|
||||||
cells_c.append(cell_c)
|
cells_c.append(cell_c)
|
||||||
ws0.set_row_dimension_height(row, space / 25)
|
ws0.set_row_dimension_height(row, space / 25)
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
<span class="help">{{field.description}}</span>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
@ -60,6 +61,8 @@
|
|||||||
<input id="gr_cancel" type=submit value="Annuler">
|
<input id="gr_cancel" type=submit value="Annuler">
|
||||||
</script>
|
</script>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
<div class="help">
|
||||||
<h3>Explications</h3>
|
<h3>Explications</h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li>préciser les surveillants et la localisation (bâtiment et salle) et indiquer la largeur de la salle (nombre
|
<li>préciser les surveillants et la localisation (bâtiment et salle) et indiquer la largeur de la salle (nombre
|
||||||
@ -86,4 +89,5 @@
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
"Infos sur version ScoDoc"
|
"Infos sur version ScoDoc"
|
||||||
|
|
||||||
SCOVERSION = "9.7.31"
|
SCOVERSION = "9.7.32"
|
||||||
|
|
||||||
SCONAME = "ScoDoc"
|
SCONAME = "ScoDoc"
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user