796 lines
26 KiB
Python
796 lines
26 KiB
Python
|
# -*- mode: python -*-
|
||
|
# -*- coding: utf-8 -*-
|
||
|
|
||
|
##############################################################################
|
||
|
#
|
||
|
# Gestion scolarite IUT
|
||
|
#
|
||
|
# Copyright (c) 1999 - 2020 Emmanuel Viennet. All rights reserved.
|
||
|
#
|
||
|
# This program is free software; you can redistribute it and/or modify
|
||
|
# it under the terms of the GNU General Public License as published by
|
||
|
# the Free Software Foundation; either version 2 of the License, or
|
||
|
# (at your option) any later version.
|
||
|
#
|
||
|
# This program is distributed in the hope that it will be useful,
|
||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
# GNU General Public License for more details.
|
||
|
#
|
||
|
# You should have received a copy of the GNU General Public License
|
||
|
# along with this program; if not, write to the Free Software
|
||
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||
|
#
|
||
|
# Emmanuel Viennet emmanuel.viennet@viennet.net
|
||
|
#
|
||
|
##############################################################################
|
||
|
|
||
|
"""ScoDoc: génération feuille émargement et placement
|
||
|
|
||
|
Contribution M. Salomon, UFC / IUT DE BELFORT-MONTBÉLIARD, 2016
|
||
|
|
||
|
"""
|
||
|
|
||
|
from notesdb import *
|
||
|
from sco_utils import *
|
||
|
from notes_log import log
|
||
|
import scolars
|
||
|
import sco_formsemestre
|
||
|
import sco_groups
|
||
|
import sco_evaluations
|
||
|
import sco_excel
|
||
|
from sco_excel import *
|
||
|
from gen_tables import GenTable
|
||
|
import random
|
||
|
|
||
|
|
||
|
def do_placement_selectetuds(context, REQUEST):
|
||
|
"""
|
||
|
Choisi les etudiants et les infos sur la salle pour le placement des etudiants
|
||
|
"""
|
||
|
evaluation_id = REQUEST.form["evaluation_id"]
|
||
|
E = context.do_evaluation_list({"evaluation_id": evaluation_id})
|
||
|
if not E:
|
||
|
raise ScoValueError("invalid evaluation_id")
|
||
|
E = E[0]
|
||
|
M = context.do_moduleimpl_list(moduleimpl_id=E["moduleimpl_id"])[0]
|
||
|
formsemestre_id = M["formsemestre_id"]
|
||
|
# groupes
|
||
|
groups = sco_groups.do_evaluation_listegroupes(
|
||
|
context, evaluation_id, include_default=True
|
||
|
)
|
||
|
grlabs = [g["group_name"] or "tous" for g in groups] # legendes des boutons
|
||
|
grnams = [g["group_id"] for g in groups] # noms des checkbox
|
||
|
no_groups = (len(groups) == 1) and groups[0]["group_name"] is None
|
||
|
|
||
|
# description de l'evaluation
|
||
|
H = [
|
||
|
sco_evaluations.evaluation_describe(
|
||
|
context, evaluation_id=evaluation_id, REQUEST=REQUEST
|
||
|
),
|
||
|
"<h3>Placement et émargement des étudiants</h3>",
|
||
|
]
|
||
|
#
|
||
|
descr = [
|
||
|
("evaluation_id", {"default": evaluation_id, "input_type": "hidden"}),
|
||
|
(
|
||
|
"placement_method",
|
||
|
{
|
||
|
"input_type": "radio",
|
||
|
"default": "xls",
|
||
|
"allow_null": False,
|
||
|
"allowed_values": ["pdf", "xls"],
|
||
|
"labels": ["fichier pdf", "fichier xls"],
|
||
|
"title": "Format de fichier :",
|
||
|
},
|
||
|
),
|
||
|
("teachers", {"size": 25, "title": "Surveillants :"}),
|
||
|
("building", {"size": 25, "title": "Batiment :"}),
|
||
|
("room", {"size": 10, "title": "Salle :"}),
|
||
|
(
|
||
|
"columns",
|
||
|
{
|
||
|
"input_type": "radio",
|
||
|
"default": "5",
|
||
|
"allow_null": False,
|
||
|
"allowed_values": ["3", "4", "5", "6", "7", "8"],
|
||
|
"labels": [
|
||
|
"3 colonnes",
|
||
|
"4 colonnes",
|
||
|
"5 colonnes",
|
||
|
"6 colonnes",
|
||
|
"7 colonnes",
|
||
|
"8 colonnes",
|
||
|
],
|
||
|
"title": "Nombre de colonnes :",
|
||
|
},
|
||
|
),
|
||
|
(
|
||
|
"numbering",
|
||
|
{
|
||
|
"input_type": "radio",
|
||
|
"default": "coordinate",
|
||
|
"allow_null": False,
|
||
|
"allowed_values": ["continuous", "coordinate"],
|
||
|
"labels": ["continue", "coordonnées"],
|
||
|
"title": "Numérotation :",
|
||
|
},
|
||
|
),
|
||
|
]
|
||
|
if no_groups:
|
||
|
submitbuttonattributes = []
|
||
|
descr += [
|
||
|
(
|
||
|
"group_ids",
|
||
|
{
|
||
|
"default": [g["group_id"] for g in groups],
|
||
|
"input_type": "hidden",
|
||
|
"type": "list",
|
||
|
},
|
||
|
)
|
||
|
]
|
||
|
else:
|
||
|
descr += [
|
||
|
(
|
||
|
"group_ids",
|
||
|
{
|
||
|
"input_type": "checkbox",
|
||
|
"title": "Choix groupe(s) d'étudiants :",
|
||
|
"allowed_values": grnams,
|
||
|
"labels": grlabs,
|
||
|
"attributes": ['onchange="gr_change(this);"'],
|
||
|
},
|
||
|
)
|
||
|
]
|
||
|
|
||
|
if not (REQUEST.form.has_key("group_ids") and REQUEST.form["group_ids"]):
|
||
|
submitbuttonattributes = ['disabled="1"']
|
||
|
else:
|
||
|
submitbuttonattributes = [] # groupe(s) preselectionnés
|
||
|
H.append(
|
||
|
# JS pour desactiver le bouton OK si aucun groupe selectionné
|
||
|
"""<script type="text/javascript">
|
||
|
function gr_change(e) {
|
||
|
var boxes = document.getElementsByName("group_ids:list");
|
||
|
var nbchecked = 0;
|
||
|
for (var i=0; i < boxes.length; i++) {
|
||
|
if (boxes[i].checked)
|
||
|
nbchecked++;
|
||
|
}
|
||
|
if (nbchecked > 0) {
|
||
|
document.getElementsByName('gr_submit')[0].disabled=false;
|
||
|
} else {
|
||
|
document.getElementsByName('gr_submit')[0].disabled=true;
|
||
|
}
|
||
|
}
|
||
|
</script>
|
||
|
"""
|
||
|
)
|
||
|
|
||
|
tf = TrivialFormulator(
|
||
|
REQUEST.URL0,
|
||
|
REQUEST.form,
|
||
|
descr,
|
||
|
cancelbutton="Annuler",
|
||
|
submitbuttonattributes=submitbuttonattributes,
|
||
|
submitlabel="OK",
|
||
|
formid="gr",
|
||
|
)
|
||
|
if tf[0] == 0:
|
||
|
# H.append( """<div class="saisienote_etape1">
|
||
|
# <span class="titredivplacementetudiants">Choix du groupe et de la localisation</span>
|
||
|
# """)
|
||
|
H.append("""<div class="saisienote_etape1">""")
|
||
|
return "\n".join(H) + "\n" + tf[1] + "\n</div>"
|
||
|
elif tf[0] == -1:
|
||
|
return REQUEST.RESPONSE.redirect(
|
||
|
"%s/Notes/moduleimpl_status?moduleimpl_id=%s"
|
||
|
% (context.ScoURL(), E["moduleimpl_id"])
|
||
|
)
|
||
|
else:
|
||
|
placement_method = tf[2]["placement_method"]
|
||
|
teachers = tf[2]["teachers"]
|
||
|
building = tf[2]["building"]
|
||
|
room = tf[2]["room"]
|
||
|
group_ids = tf[2]["group_ids"]
|
||
|
columns = tf[2]["columns"]
|
||
|
numbering = tf[2]["numbering"]
|
||
|
if columns in ("3", "4", "5", "6", "7", "8"):
|
||
|
gs = [("group_ids%3Alist=" + urllib.quote_plus(x)) for x in group_ids]
|
||
|
query = "evaluation_id=%s&placement_method=%s&teachers=%s&building=%s&room=%s&columns=%s&numbering=%s&" % (
|
||
|
evaluation_id,
|
||
|
placement_method,
|
||
|
teachers,
|
||
|
building,
|
||
|
room,
|
||
|
columns,
|
||
|
numbering,
|
||
|
) + "&".join(
|
||
|
gs
|
||
|
)
|
||
|
return REQUEST.RESPONSE.redirect(REQUEST.URL1 + "/do_placement?" + query)
|
||
|
else:
|
||
|
raise ValueError(
|
||
|
"invalid placement_method (%s)" % tf[2]["placement_method"]
|
||
|
)
|
||
|
|
||
|
|
||
|
def do_placement(context, REQUEST):
|
||
|
"""
|
||
|
Choisi le placement
|
||
|
"""
|
||
|
authuser = REQUEST.AUTHENTICATED_USER
|
||
|
authusername = str(authuser)
|
||
|
try:
|
||
|
evaluation_id = REQUEST.form["evaluation_id"]
|
||
|
except:
|
||
|
raise ScoValueError(
|
||
|
"Formulaire incomplet ! Vous avez sans doute attendu trop longtemps, veuillez vous reconnecter. Si le problème persiste, contacter l'administrateur. Merci."
|
||
|
)
|
||
|
E = context.do_evaluation_list({"evaluation_id": evaluation_id})[0]
|
||
|
jour_iso = DateDMYtoISO(E["jour"])
|
||
|
|
||
|
# Check access
|
||
|
# (admin, respformation, and responsable_id)
|
||
|
if not context.can_edit_notes(authuser, E["moduleimpl_id"]):
|
||
|
return (
|
||
|
"<h2>Génération du placement impossible pour %s</h2>" % authusername
|
||
|
+ """<p>(vérifiez que le semestre n'est pas verrouillé et que vous
|
||
|
avez l'autorisation d'effectuer cette opération)</p>
|
||
|
<p><a href="moduleimpl_status?moduleimpl_id=%s">Continuer</a></p>
|
||
|
"""
|
||
|
% E["moduleimpl_id"]
|
||
|
)
|
||
|
cnx = context.GetDBConnexion()
|
||
|
# Infos transmises
|
||
|
placement_method = REQUEST.form["placement_method"]
|
||
|
teachers = REQUEST.form["teachers"]
|
||
|
building = REQUEST.form["building"]
|
||
|
room = REQUEST.form["room"]
|
||
|
columns = REQUEST.form["columns"]
|
||
|
numbering = REQUEST.form["numbering"]
|
||
|
|
||
|
# Construit liste des etudiants
|
||
|
group_ids = REQUEST.form.get("group_ids", [])
|
||
|
groups = sco_groups.listgroups(context, group_ids)
|
||
|
gr_title_filename = sco_groups.listgroups_filename(groups)
|
||
|
gr_title = sco_groups.listgroups_abbrev(groups)
|
||
|
|
||
|
if None in [g["group_name"] for g in groups]: # tous les etudiants
|
||
|
getallstudents = True
|
||
|
gr_title = "tous"
|
||
|
gr_title_filename = "tous"
|
||
|
else:
|
||
|
getallstudents = False
|
||
|
etudids = sco_groups.do_evaluation_listeetuds_groups(
|
||
|
context, evaluation_id, groups, getallstudents=getallstudents, include_dems=True
|
||
|
)
|
||
|
if not etudids:
|
||
|
return "<p>Aucun groupe sélectionné !</p>"
|
||
|
|
||
|
M = context.do_moduleimpl_list(moduleimpl_id=E["moduleimpl_id"])[0]
|
||
|
Mod = context.do_module_list(args={"module_id": M["module_id"]})[0]
|
||
|
sem = sco_formsemestre.get_formsemestre(context, M["formsemestre_id"])
|
||
|
evalname = "%s-%s" % (Mod["code"], DateDMYtoISO(E["jour"]))
|
||
|
if E["description"]:
|
||
|
evaltitre = E["description"]
|
||
|
else:
|
||
|
evaltitre = "évaluation du %s" % E["jour"]
|
||
|
|
||
|
desceval = [] # une liste de liste de chaines: description de l'evaluation
|
||
|
desceval.append(["%s" % sem["titreannee"]])
|
||
|
desceval.append(["Module : %s - %s" % (Mod["code"], Mod["abbrev"])])
|
||
|
desceval.append(["Surveillants : %s" % teachers])
|
||
|
desceval.append(["Batiment : %s - Salle : %s" % (building, room)])
|
||
|
desceval.append(["Controle : %s (coef. %g)" % (evaltitre, E["coefficient"])])
|
||
|
|
||
|
listetud = [] # liste de couples (nom,prenom)
|
||
|
for etudid in etudids:
|
||
|
# infos identite etudiant (xxx sous-optimal: 1/select par etudiant)
|
||
|
ident = scolars.etudident_list(cnx, {"etudid": etudid})[
|
||
|
0
|
||
|
] # XXX utiliser ZScolar (parent)
|
||
|
# infos inscription
|
||
|
inscr = context.do_formsemestre_inscription_list(
|
||
|
{"etudid": etudid, "formsemestre_id": M["formsemestre_id"]}
|
||
|
)[0]
|
||
|
if inscr["etat"] != "D":
|
||
|
nom = strupper(ident["nom"])
|
||
|
prenom = strcapitalize(strlower(ident["prenom"]))
|
||
|
listetud.append((nom, prenom))
|
||
|
random.shuffle(listetud)
|
||
|
|
||
|
sem_preferences = context.get_preferences()
|
||
|
space = sem_preferences.get("feuille_placement_emargement")
|
||
|
maxlines = sem_preferences.get("feuille_placement_positions")
|
||
|
|
||
|
if placement_method == "xls":
|
||
|
filename = "placement_%s_%s.xls" % (evalname, gr_title_filename)
|
||
|
xls = Excel_feuille_placement(
|
||
|
E, desceval, listetud, columns, space, maxlines, building, room, numbering
|
||
|
)
|
||
|
return sco_excel.sendExcelFile(REQUEST, xls, filename)
|
||
|
else:
|
||
|
nbcolumns = int(columns)
|
||
|
|
||
|
pdf_title = "%s<br/>" % sem["titreannee"]
|
||
|
pdf_title += "Module : %s - %s<br/>" % (Mod["code"], Mod["abbrev"])
|
||
|
pdf_title += "Surveillants : %s<br/>" % teachers
|
||
|
pdf_title += "Batiment : %s - Salle : %s<br/>" % (building, room)
|
||
|
pdf_title += "Controle : %s (coef. %g)<br/>" % (evaltitre, E["coefficient"])
|
||
|
pdf_title += "Date : %s - Horaire : %s à %s" % (
|
||
|
E["jour"],
|
||
|
E["heure_debut"],
|
||
|
E["heure_fin"],
|
||
|
)
|
||
|
|
||
|
filename = "placement_%s_%s.pdf" % (evalname, gr_title_filename)
|
||
|
titles = {
|
||
|
"nom": "Nom",
|
||
|
"prenom": "Prenom",
|
||
|
"colonne": "Colonne",
|
||
|
"ligne": "Ligne",
|
||
|
"place": "Place",
|
||
|
}
|
||
|
if numbering == "coordinate":
|
||
|
columns_ids = ["nom", "prenom", "colonne", "ligne"]
|
||
|
else:
|
||
|
columns_ids = ["nom", "prenom", "place"]
|
||
|
|
||
|
# etudiants
|
||
|
line = 1
|
||
|
col = 1
|
||
|
orderetud = []
|
||
|
for etudid in listetud:
|
||
|
if numbering == "coordinate":
|
||
|
orderetud.append((etudid[0], etudid[1], col, line))
|
||
|
else:
|
||
|
orderetud.append((etudid[0], etudid[1], col + (line - 1) * nbcolumns))
|
||
|
|
||
|
if col == nbcolumns:
|
||
|
col = 0
|
||
|
line += 1
|
||
|
col += 1
|
||
|
|
||
|
rows = []
|
||
|
orderetud.sort()
|
||
|
for etudid in orderetud:
|
||
|
if numbering == "coordinate":
|
||
|
rows.append(
|
||
|
{
|
||
|
"nom": etudid[0],
|
||
|
"prenom": etudid[1],
|
||
|
"colonne": etudid[2],
|
||
|
"ligne": etudid[3],
|
||
|
}
|
||
|
)
|
||
|
else:
|
||
|
rows.append({"nom": etudid[0], "prenom": etudid[1], "place": etudid[2]})
|
||
|
|
||
|
tab = GenTable(
|
||
|
titles=titles,
|
||
|
columns_ids=columns_ids,
|
||
|
rows=rows,
|
||
|
filename=filename,
|
||
|
origin="Généré par %s le " % VERSION.SCONAME + timedate_human_repr() + "",
|
||
|
pdf_title=pdf_title,
|
||
|
# pdf_shorttitle = '',
|
||
|
preferences=context.get_preferences(M["formsemestre_id"]),
|
||
|
# html_generate_cells=False # la derniere ligne (moyennes) est incomplete
|
||
|
)
|
||
|
t = tab.make_page(
|
||
|
context, format="pdf", with_html_headers=False, REQUEST=REQUEST
|
||
|
)
|
||
|
return t
|
||
|
|
||
|
|
||
|
def placement_eval_selectetuds(context, evaluation_id, REQUEST=None):
|
||
|
"""Dialogue placement etudiants: choix methode et localisation
|
||
|
"""
|
||
|
evals = context.do_evaluation_list({"evaluation_id": evaluation_id})
|
||
|
if not evals:
|
||
|
raise ScoValueError("invalid evaluation_id")
|
||
|
theeval = evals[0]
|
||
|
|
||
|
if theeval["description"]:
|
||
|
page_title = 'Placement "%s"' % theeval["description"]
|
||
|
else:
|
||
|
page_title = "Placement des étudiants"
|
||
|
H = [context.sco_header(REQUEST, page_title=page_title)]
|
||
|
|
||
|
formid = "placementfile"
|
||
|
if not REQUEST.form.get("%s-submitted" % formid, False):
|
||
|
# not submitted, choix groupe
|
||
|
r = do_placement_selectetuds(context, REQUEST)
|
||
|
if r:
|
||
|
H.append(r)
|
||
|
|
||
|
H.append(
|
||
|
"""<h3>Explications</h3>
|
||
|
<ul>
|
||
|
<li>Choisir le format du fichier résultat :</li>
|
||
|
<ul>
|
||
|
<li>le format pdf consiste en un tableau précisant pour chaque étudiant la localisation de sa table;</li>
|
||
|
<li>le format xls produit un classeur avec deux onglets</li>
|
||
|
<ul>
|
||
|
<li>le premier onglet donne une vue de la salle avec la localisation des étudiants et peut servir de feuille d'émargement;</li>
|
||
|
<li>le second onglet est un tableau similaire à celui du fichier pdf;</li>
|
||
|
</ul>
|
||
|
</ul>
|
||
|
<li>préciser les surveillants et la localisation (bâtiment et salle) et indiquer le nombre de colonnes;</li>
|
||
|
<li>deux types de placements sont possibles :</li>
|
||
|
<ul>
|
||
|
<li>continue suppose que les tables ont toutes un numéro unique;</li>
|
||
|
<li>coordonnées localise chaque table via un numéro de colonne et un numéro de ligne (ou rangée).</li>
|
||
|
</ul>
|
||
|
</ul>
|
||
|
"""
|
||
|
)
|
||
|
H.append(context.sco_footer(REQUEST))
|
||
|
return "\n".join(H)
|
||
|
|
||
|
|
||
|
def Excel_feuille_placement(
|
||
|
E, description, listetud, columns, space, maxlines, building, room, numbering
|
||
|
):
|
||
|
"""Genere feuille excel pour placement des etudiants.
|
||
|
E: evaluation (dict)
|
||
|
lines: liste de tuples
|
||
|
(etudid, nom, prenom, etat, groupe, val, explanation)
|
||
|
"""
|
||
|
nbcolumns = int(columns)
|
||
|
|
||
|
wb = Workbook()
|
||
|
|
||
|
SheetName0 = "Emargement"
|
||
|
ws0 = wb.add_sheet(SheetName0.decode(SCO_ENCODING))
|
||
|
# ajuste largeurs colonnes (unite inconnue, empirique)
|
||
|
width = 4500
|
||
|
if nbcolumns > 5:
|
||
|
width = 22500 / nbcolumns
|
||
|
|
||
|
for col in range(nbcolumns):
|
||
|
ws0.col(col + 1).width = width
|
||
|
ws0.col(0).width = 750
|
||
|
|
||
|
SheetName1 = "Positions"
|
||
|
ws1 = wb.add_sheet(SheetName1.decode(SCO_ENCODING))
|
||
|
if numbering == "coordinate":
|
||
|
ws1.col(0).width = 4000
|
||
|
ws1.col(1).width = 4500
|
||
|
ws1.col(2).width = 1500
|
||
|
ws1.col(3).width = 1500
|
||
|
|
||
|
ws1.col(4).width = 500
|
||
|
|
||
|
ws1.col(5).width = 4000
|
||
|
ws1.col(6).width = 4500
|
||
|
ws1.col(7).width = 1500
|
||
|
ws1.col(8).width = 1500
|
||
|
else:
|
||
|
ws1.col(0).width = 4000
|
||
|
ws1.col(1).width = 4500
|
||
|
ws1.col(2).width = 3000
|
||
|
|
||
|
ws1.col(3).width = 500
|
||
|
|
||
|
ws1.col(4).width = 4000
|
||
|
ws1.col(5).width = 4500
|
||
|
ws1.col(6).width = 3000
|
||
|
|
||
|
# styles
|
||
|
font0 = Font()
|
||
|
font0.name = "Arial"
|
||
|
font0.bold = True
|
||
|
font0.height = 12 * 0x14
|
||
|
|
||
|
font1b = Font()
|
||
|
font1b.name = "Arial"
|
||
|
font1b.bold = True
|
||
|
font1b.height = 9 * 0x14
|
||
|
|
||
|
font1i = Font()
|
||
|
font1i.name = "Arial"
|
||
|
font1i.height = 10 * 0x14
|
||
|
font1i.italic = True
|
||
|
|
||
|
font1o = Font()
|
||
|
font1o.name = "Arial"
|
||
|
font1o.height = 10 * 0x14
|
||
|
font1o.outline = True
|
||
|
|
||
|
font2bi = Font()
|
||
|
font2bi.name = "Arial"
|
||
|
font2bi.height = 8 * 0x14
|
||
|
font2bi.bold = True
|
||
|
font2bi.italic = True
|
||
|
|
||
|
font2 = Font()
|
||
|
font2.name = "Arial"
|
||
|
font2.height = 10 * 0x14
|
||
|
|
||
|
style_titres = XFStyle()
|
||
|
style_titres.font = font0
|
||
|
|
||
|
style1t = XFStyle()
|
||
|
style1t.font = font1b
|
||
|
alignment = Alignment()
|
||
|
alignment.horz = Alignment.HORZ_CENTER
|
||
|
alignment.vert = Alignment.VERT_CENTER
|
||
|
style1t.alignment = alignment
|
||
|
borders = Borders()
|
||
|
borders.left = Borders.DOUBLE
|
||
|
borders.top = Borders.DOUBLE
|
||
|
borders.bottom = Borders.NO_LINE
|
||
|
borders.right = Borders.DOUBLE
|
||
|
style1t.borders = borders
|
||
|
|
||
|
style1m = XFStyle()
|
||
|
style1m.font = font1b
|
||
|
alignment = Alignment()
|
||
|
alignment.horz = Alignment.HORZ_CENTER
|
||
|
alignment.vert = Alignment.VERT_CENTER
|
||
|
style1m.alignment = alignment
|
||
|
borders = Borders()
|
||
|
borders.left = Borders.DOUBLE
|
||
|
borders.top = Borders.NO_LINE
|
||
|
borders.bottom = Borders.THIN
|
||
|
borders.right = Borders.DOUBLE
|
||
|
style1m.borders = borders
|
||
|
|
||
|
style1bm = XFStyle()
|
||
|
borders = Borders()
|
||
|
borders.left = Borders.DOUBLE
|
||
|
borders.top = Borders.NO_LINE
|
||
|
borders.bottom = Borders.NO_LINE
|
||
|
borders.right = Borders.DOUBLE
|
||
|
style1bm.borders = borders
|
||
|
|
||
|
style1bb = XFStyle()
|
||
|
style1bb.font = font1o
|
||
|
alignment = Alignment()
|
||
|
alignment.horz = Alignment.HORZ_RIGHT
|
||
|
alignment.vert = Alignment.VERT_BOTTOM
|
||
|
style1bb.alignment = alignment
|
||
|
borders = Borders()
|
||
|
borders.left = Borders.DOUBLE
|
||
|
borders.top = Borders.NO_LINE
|
||
|
borders.bottom = Borders.DOUBLE
|
||
|
borders.right = Borders.DOUBLE
|
||
|
style1bb.borders = borders
|
||
|
|
||
|
style2b = XFStyle()
|
||
|
style2b.font = font1i
|
||
|
alignment = Alignment()
|
||
|
alignment.horz = Alignment.HORZ_CENTER
|
||
|
alignment.vert = Alignment.VERT_CENTER
|
||
|
style2b.alignment = alignment
|
||
|
borders = Borders()
|
||
|
borders.left = Borders.THIN
|
||
|
borders.top = Borders.THIN
|
||
|
borders.bottom = Borders.THIN
|
||
|
borders.right = Borders.THIN
|
||
|
style2b.borders = borders
|
||
|
|
||
|
style2bi = XFStyle()
|
||
|
style2bi.font = font2bi
|
||
|
alignment = Alignment()
|
||
|
alignment.horz = Alignment.HORZ_CENTER
|
||
|
alignment.vert = Alignment.VERT_CENTER
|
||
|
style2bi.alignment = alignment
|
||
|
borders = Borders()
|
||
|
borders.left = Borders.THIN
|
||
|
borders.top = Borders.THIN
|
||
|
borders.bottom = Borders.THIN
|
||
|
borders.right = Borders.THIN
|
||
|
style2bi.borders = borders
|
||
|
pattern = Pattern()
|
||
|
pattern.pattern = Pattern.SOLID_PATTERN
|
||
|
pattern._pattern_back_colour = "gray"
|
||
|
style2bi.pattern = pattern
|
||
|
|
||
|
style2l = XFStyle()
|
||
|
style2l.font = font2
|
||
|
alignment = Alignment()
|
||
|
alignment.horz = Alignment.HORZ_LEFT
|
||
|
alignment.vert = Alignment.VERT_CENTER
|
||
|
style2l.alignment = alignment
|
||
|
borders = Borders()
|
||
|
borders.left = Borders.THIN
|
||
|
borders.top = Borders.THIN
|
||
|
borders.bottom = Borders.THIN
|
||
|
borders.right = Borders.NO_LINE
|
||
|
style2l.borders = borders
|
||
|
|
||
|
style2m1 = XFStyle()
|
||
|
style2m1.font = font2
|
||
|
alignment = Alignment()
|
||
|
alignment.horz = Alignment.HORZ_LEFT
|
||
|
alignment.vert = Alignment.VERT_CENTER
|
||
|
style2m1.alignment = alignment
|
||
|
borders = Borders()
|
||
|
borders.left = Borders.NO_LINE
|
||
|
borders.top = Borders.THIN
|
||
|
borders.bottom = Borders.THIN
|
||
|
borders.right = Borders.NO_LINE
|
||
|
style2m1.borders = borders
|
||
|
|
||
|
style2m2 = XFStyle()
|
||
|
style2l.font = font2
|
||
|
alignment = Alignment()
|
||
|
alignment.horz = Alignment.HORZ_RIGHT
|
||
|
alignment.vert = Alignment.VERT_CENTER
|
||
|
style2m2.alignment = alignment
|
||
|
borders = Borders()
|
||
|
borders.left = Borders.NO_LINE
|
||
|
borders.top = Borders.THIN
|
||
|
borders.bottom = Borders.THIN
|
||
|
borders.right = Borders.NO_LINE
|
||
|
style2m2.borders = borders
|
||
|
|
||
|
style2r = XFStyle()
|
||
|
style2l.font = font2
|
||
|
alignment = Alignment()
|
||
|
alignment.horz = Alignment.HORZ_RIGHT
|
||
|
alignment.vert = Alignment.VERT_CENTER
|
||
|
style2r.alignment = alignment
|
||
|
borders = Borders()
|
||
|
borders.left = Borders.NO_LINE
|
||
|
borders.top = Borders.THIN
|
||
|
borders.bottom = Borders.THIN
|
||
|
borders.right = Borders.THIN
|
||
|
style2r.borders = borders
|
||
|
|
||
|
# ligne de titres
|
||
|
li = 0
|
||
|
line = 0
|
||
|
dt = time.strftime("%d/%m/%Y a %Hh%M")
|
||
|
ws0.write(li, 0, u"Feuille placement etudiants éditée le %s" % dt, style_titres)
|
||
|
ws1.write(li, 0, u"Feuille placement etudiants éditée le %s" % dt, style_titres)
|
||
|
for desceval in description:
|
||
|
if line % 2 == 0:
|
||
|
li += 2
|
||
|
else:
|
||
|
li += 1
|
||
|
line += 1
|
||
|
ws0.write(li, 0, desceval[0].decode(SCO_ENCODING), style_titres)
|
||
|
ws1.write(li, 0, desceval[0].decode(SCO_ENCODING), style_titres)
|
||
|
li += 1
|
||
|
ws0.write(
|
||
|
li,
|
||
|
0,
|
||
|
u"Date : %s - Horaire : %s à %s"
|
||
|
% (E["jour"], E["heure_debut"], E["heure_fin"]),
|
||
|
style_titres,
|
||
|
)
|
||
|
ws1.write(
|
||
|
li,
|
||
|
0,
|
||
|
u"Date : %s - Horaire : %s à %s"
|
||
|
% (E["jour"], E["heure_debut"], E["heure_fin"]),
|
||
|
style_titres,
|
||
|
)
|
||
|
li += 1
|
||
|
|
||
|
# entetes colonnes - feuille0
|
||
|
for col in range(nbcolumns):
|
||
|
ws0.write(li, col + 1, u"colonne %s" % (col + 1), style2b)
|
||
|
# entetes colonnes - feuille1
|
||
|
if numbering == "coordinate":
|
||
|
ws1.write(li, 0, u"Nom", style2bi)
|
||
|
ws1.write(li, 1, u"Prénom", style2bi)
|
||
|
ws1.write(li, 2, u"Colonne", style2bi)
|
||
|
ws1.write(li, 3, u"Ligne", style2bi)
|
||
|
|
||
|
ws1.write(li, 5, u"Nom", style2bi)
|
||
|
ws1.write(li, 6, u"Prénom", style2bi)
|
||
|
ws1.write(li, 7, u"Colonne", style2bi)
|
||
|
ws1.write(li, 8, u"Ligne", style2bi)
|
||
|
else:
|
||
|
ws1.write(li, 0, u"Nom", style2bi)
|
||
|
ws1.write(li, 1, u"Prénom", style2bi)
|
||
|
ws1.write(li, 2, u"Place", style2bi)
|
||
|
|
||
|
ws1.write(li, 4, u"Nom", style2bi)
|
||
|
ws1.write(li, 5, u"Prénom", style2bi)
|
||
|
ws1.write(li, 6, u"Place", style2bi)
|
||
|
|
||
|
# etudiants
|
||
|
line = 1
|
||
|
col = 1
|
||
|
linetud = []
|
||
|
orderetud = []
|
||
|
placementetud = []
|
||
|
for etudid in listetud:
|
||
|
linetud.append(etudid)
|
||
|
if numbering == "coordinate":
|
||
|
orderetud.append((etudid[0], etudid[1], col, line))
|
||
|
else:
|
||
|
orderetud.append((etudid[0], etudid[1], col + (line - 1) * nbcolumns))
|
||
|
|
||
|
if col == nbcolumns:
|
||
|
placementetud.append(linetud)
|
||
|
linetud = []
|
||
|
col = 0
|
||
|
line += 1
|
||
|
col += 1
|
||
|
if len(linetud) > 0:
|
||
|
placementetud.append(linetud)
|
||
|
|
||
|
# etudiants - feuille0
|
||
|
line = 0
|
||
|
li0 = li
|
||
|
for linetud in placementetud:
|
||
|
li0 += 1
|
||
|
line += 1
|
||
|
ws0.write(li0, 0, line, style2b)
|
||
|
col = 1
|
||
|
for etudid in linetud:
|
||
|
ws0.write(li0, col, (etudid[0]).decode(SCO_ENCODING), style1t)
|
||
|
ws0.write(li0 + 1, col, (etudid[1]).decode(SCO_ENCODING), style1m)
|
||
|
ws0.row(li0 + 2).height = space
|
||
|
if numbering == "coordinate":
|
||
|
ws0.write(li0 + 2, col, " ", style1bb)
|
||
|
else:
|
||
|
ws0.write(
|
||
|
li0 + 2, col, u"place %s" % (col + (line - 1) * nbcolumns), style1bb
|
||
|
)
|
||
|
# ws0.write(li+3,col, ' ', style1bm )
|
||
|
# ws0.write(li+4,col, ' ', style1bb )
|
||
|
|
||
|
if col == nbcolumns:
|
||
|
col = 0
|
||
|
li0 += 2
|
||
|
col += 1
|
||
|
|
||
|
# etudiants - feuille1
|
||
|
if numbering == "coordinate":
|
||
|
coloffset = 5
|
||
|
else:
|
||
|
coloffset = 4
|
||
|
line = 0
|
||
|
li1 = li
|
||
|
nbcol = 0
|
||
|
col = 0
|
||
|
orderetud.sort()
|
||
|
for etudid in orderetud:
|
||
|
li1 += 1
|
||
|
line += 1
|
||
|
ws1.write(li1, col, (etudid[0]).decode(SCO_ENCODING), style2l)
|
||
|
ws1.write(li1, col + 1, (etudid[1]).decode(SCO_ENCODING), style2m1)
|
||
|
if numbering == "coordinate":
|
||
|
ws1.write(li1, col + 2, etudid[2], style2m2)
|
||
|
ws1.write(li1, col + 3, etudid[3], style2r)
|
||
|
else:
|
||
|
ws1.write(li1, col + 2, etudid[2], style2r)
|
||
|
|
||
|
if line == maxlines:
|
||
|
line = 0
|
||
|
li1 = li
|
||
|
nbcol = nbcol + 1
|
||
|
col = col + coloffset
|
||
|
if nbcol == 2:
|
||
|
li = li + maxlines + 2
|
||
|
li1 = li
|
||
|
nbcol = 0
|
||
|
col = 0
|
||
|
if numbering == "coordinate":
|
||
|
ws1.write(li, 0, u"Nom", style2bi)
|
||
|
ws1.write(li, 1, u"Prénom", style2bi)
|
||
|
ws1.write(li, 2, u"Colonne", style2bi)
|
||
|
ws1.write(li, 3, u"Ligne", style2bi)
|
||
|
|
||
|
ws1.write(li, 5, u"Nom", style2bi)
|
||
|
ws1.write(li, 6, u"Prénom", style2bi)
|
||
|
ws1.write(li, 7, u"Colonne", style2bi)
|
||
|
ws1.write(li, 8, u"Ligne", style2bi)
|
||
|
else:
|
||
|
ws1.write(li, 0, u"Nom", style2bi)
|
||
|
ws1.write(li, 1, u"Prénom", style2bi)
|
||
|
ws1.write(li, 2, u"Place", style2bi)
|
||
|
|
||
|
ws1.write(li, 4, u"Nom", style2bi)
|
||
|
ws1.write(li, 5, u"Prénom", style2bi)
|
||
|
ws1.write(li, 6, u"Place", style2bi)
|
||
|
return wb.savetostr()
|