2020-09-26 16:19:37 +02:00
# -*- mode: python -*-
# -*- coding: utf-8 -*-
##############################################################################
#
# Gestion scolarite IUT
#
2022-01-01 14:49:42 +01:00
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
2020-09-26 16:19:37 +02:00
#
# 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 : formulaires gestion maquettes Apogee / export resultats
"""
2021-08-31 19:32:12 +02:00
import io
2020-09-26 16:19:37 +02:00
from zipfile import ZipFile
2021-08-01 10:16:16 +02:00
import flask
2021-09-18 10:10:02 +02:00
from flask import url_for , g , send_file , request
2021-08-31 19:32:12 +02:00
# from werkzeug.utils import send_file
2021-07-11 17:37:12 +02:00
2021-06-19 23:21:37 +02:00
import app . scodoc . sco_utils as scu
2021-08-29 19:57:32 +02:00
from app import log
2021-06-19 23:21:37 +02:00
from app . scodoc import html_sco_header
from app . scodoc import sco_apogee_csv
from app . scodoc import sco_etape_apogee
from app . scodoc import sco_formations
from app . scodoc import sco_formsemestre
from app . scodoc import sco_portal_apogee
from app . scodoc import sco_preferences
from app . scodoc import sco_semset
from app . scodoc import sco_etud
from app . scodoc . gen_tables import GenTable
2022-01-07 17:58:34 +01:00
from app . scodoc . sco_apogee_csv import APO_INPUT_ENCODING , APO_OUTPUT_ENCODING
2021-06-19 23:21:37 +02:00
from app . scodoc . sco_exceptions import ScoValueError
2020-09-26 16:19:37 +02:00
def apo_semset_maq_status (
2022-02-18 22:59:05 +01:00
semset_id : int ,
2020-09-26 16:19:37 +02:00
allow_missing_apo = False ,
allow_missing_decisions = False ,
2020-10-02 21:34:59 +02:00
allow_missing_csv = False ,
2020-09-26 16:19:37 +02:00
block_export_res_etape = False ,
block_export_res_sem = False ,
block_export_res_ues = False ,
block_export_res_modules = False ,
block_export_res_sdj = True ,
) :
2021-01-01 18:40:47 +01:00
""" Page statut / tableau de bord """
2020-09-26 16:19:37 +02:00
if not semset_id :
2022-02-18 22:59:05 +01:00
raise ScoValueError ( " invalid null semset_id " )
2021-08-21 00:24:51 +02:00
semset = sco_semset . SemSet ( semset_id = semset_id )
2021-07-29 16:31:15 +02:00
semset . fill_formsemestres ( )
2020-10-02 21:34:59 +02:00
# autorise export meme si etudiants Apo manquants:
allow_missing_apo = int ( allow_missing_apo )
# autorise export meme s'il manque des décisions de jury:
allow_missing_decisions = int ( allow_missing_decisions )
# autorise export même si maquette csv manquantes:
allow_missing_csv = int ( allow_missing_csv )
2020-09-26 16:19:37 +02:00
block_export_res_etape = int ( block_export_res_etape )
block_export_res_sem = int ( block_export_res_sem )
block_export_res_ues = int ( block_export_res_ues )
block_export_res_modules = int ( block_export_res_modules )
block_export_res_sdj = int ( block_export_res_sdj )
2021-07-28 17:03:54 +02:00
prefs = sco_preferences . SemPreferences ( )
2020-09-26 16:19:37 +02:00
2021-09-27 10:20:10 +02:00
tab_archives = table_apo_csv_list ( semset )
2020-09-26 16:19:37 +02:00
(
ok_for_export ,
etapes_missing_csv ,
etuds_without_nip ,
nips_ok ,
nips_no_apo ,
nips_no_sco ,
apo_dups ,
maq_elems ,
sem_elems ,
2021-01-01 18:40:47 +01:00
) = sco_etape_apogee . apo_csv_semset_check (
2021-08-21 00:24:51 +02:00
semset , allow_missing_apo , allow_missing_csv
2021-01-01 18:40:47 +01:00
)
2020-09-26 16:19:37 +02:00
if not allow_missing_decisions :
ok_for_export & = semset [ " jury_ok " ]
H = [
2021-06-13 19:12:20 +02:00
html_sco_header . sco_header (
2020-09-26 16:19:37 +02:00
page_title = " Export Apogée " ,
javascripts = [ " js/apo_semset_maq_status.js " ] ,
) ,
""" <h2>Export des résultats vers Apogée</h2> """
""" <div class= " semset_descr " > """ ,
semset . html_descr ( ) ,
semset . html_form_sems ( ) ,
""" </div> """ ,
]
# Bilans code apogée
H . append ( semset . html_diagnostic ( ) )
# Maquettes enregistrées
H . append (
""" <div class= " apo_csv_list " >
< span class = " box_title " > Maquettes Apogée < / span >
"""
)
if not tab_archives . is_empty ( ) :
H . append ( tab_archives . html ( ) )
else :
H . append ( """ <p><em>Aucune maquette chargée</em></p> """ )
# Upload fichier:
H . append (
""" <form id= " apo_csv_add " action= " view_apo_csv_store " method= " post " enctype= " multipart/form-data " >
Charger votre fichier maquette Apogée :
< input type = " file " size = " 30 " name = " csvfile " / >
< input type = " hidden " name = " semset_id " value = " %s " / >
< input type = " submit " value = " Ajouter ce fichier " / >
< input type = " checkbox " name = " autodetect " checked / > autodétecter encodage < / input >
< / form > """
% ( semset_id , )
)
# Récupération sur portail:
2021-08-20 10:51:42 +02:00
maquette_url = sco_portal_apogee . get_maquette_url ( )
2020-09-26 16:19:37 +02:00
if maquette_url : # portail configuré
menu_etapes = """ <option value= " " ></option> """
menu_etapes + = " " . join (
[ ' <option value= " %s " > %s </option> ' % ( et , et ) for et in semset . list_etapes ( ) ]
)
H . append (
""" <form id= " apo_csv_download " action= " view_apo_csv_download_and_store " method= " post " enctype= " multipart/form-data " >
Ou récupérer maquette Apogée pour une étape :
< script type = " text/javascript " >
function change_etape ( e ) {
$ ( ' #apo_csv_download_submit_btn ' ) . attr ( ' disabled ' , ( e . value == " " ) ) ;
}
< / script >
< select name = " etape_apo " onchange = " change_etape(this); " >
% s
< / select >
< input type = " hidden " name = " semset_id " value = " %s " / >
< input id = " apo_csv_download_submit_btn " type = " submit " value = " Télécharger " disabled = " disabled " / >
< / form > """
% ( menu_etapes , semset_id )
)
#
H . append ( " </div> " )
# Tableau de bord
if ok_for_export :
class_ok = " apo_csv_status_ok "
else :
class_ok = " apo_csv_status_nok "
H . append ( ' <div class= " apo_csv_status %s " > ' % class_ok )
if ok_for_export :
H . append ( """ <span class= " box_title " >Exportation</span> """ )
else :
H . append (
""" <span class= " box_title " >Problèmes à résoudre avant export des résultats:</span> """
)
H . append ( ' <div class= " apo_csv_problems " ><ul> ' )
if len ( semset . annees_scolaires ( ) ) > 1 :
H . append ( """ <li>Il y a plusieurs années scolaires !</li> """ )
if etapes_missing_csv :
H . append (
" <li>Etapes sans maquette: <tt> %s </tt></li> "
% sco_formsemestre . etapes_apo_str ( sorted ( etapes_missing_csv ) )
)
if etuds_without_nip :
H . append ( " <li> %d étudiants ScoDoc sans code NIP</li> " % len ( etuds_without_nip ) )
if nips_no_apo :
2021-08-31 19:32:12 +02:00
url_list = url_for (
" notes.view_scodoc_etuds " ,
scodoc_dept = g . scodoc_dept ,
semset_id = semset_id ,
title = " Etudiants ScoDoc non listés dans les maquettes Apogée chargées " ,
nip_list = " , " . join ( nips_no_apo ) ,
2020-09-26 16:19:37 +02:00
)
H . append (
' <li><a href= " %s " > %d étudiants</a> dans ce semestre non présents dans les maquettes Apogée chargées</li> '
% ( url_list , len ( nips_no_apo ) )
)
if nips_no_sco : # seulement un warning
2021-08-31 19:32:12 +02:00
url_list = url_for (
" notes.view_apo_etuds " ,
scodoc_dept = g . scodoc_dept ,
semset_id = semset_id ,
title = " Etudiants présents dans maquettes Apogée mais pas dans les semestres ScoDoc " ,
nip_list = " , " . join ( nips_no_sco ) ,
2020-09-26 16:19:37 +02:00
)
H . append (
' <li class= " apo_csv_warning " >Attention: il reste <a href= " %s " > %d étudiants</a> dans les maquettes Apogée chargées mais pas inscrits dans ce semestre ScoDoc</li> '
% ( url_list , len ( nips_no_sco ) )
)
if apo_dups :
2021-08-31 19:32:12 +02:00
url_list = url_for (
" notes.view_apo_etuds " ,
scodoc_dept = g . scodoc_dept ,
semset_id = semset_id ,
title = " Doublons %% 20Apogée " ,
nip_list = " , " . join ( apo_dups ) ,
2020-09-26 16:19:37 +02:00
)
H . append (
' <li><a href= " %s " > %d étudiants</a> présents dans les <em>plusieurs</em> maquettes Apogée chargées</li> '
% ( url_list , len ( apo_dups ) )
)
H . append ( " </ul></div> " )
# Decisions de jury
if semset [ " jury_ok " ] :
class_ok = " apo_csv_jury_ok "
else :
class_ok = " apo_csv_jury_nok "
H . append ( ' <div class= " apo_csv_jury %s " ><ul> ' % class_ok )
if semset [ " jury_ok " ] :
H . append ( """ <li>Décisions de jury saisies</li> """ )
else :
H . append ( """ <li>Il manque des décisions de jury !</li> """ )
if ok_for_export :
H . append ( """ <li> %d étudiants, prêt pour l ' export.</li> """ % len ( nips_ok ) )
H . append ( " </ul></div> " )
H . append (
""" <form name= " f " method= " get " action= " %s " >
< input type = " hidden " name = " semset_id " value = " %s " > < / input >
< div > < input type = " checkbox " name = " allow_missing_apo " value = " 1 " onchange = " document.f.submit() " """
2021-09-18 10:10:02 +02:00
% ( request . base_url , semset_id )
2020-09-26 16:19:37 +02:00
)
if allow_missing_apo :
H . append ( " checked " )
H . append (
""" >autoriser export même si étudiants manquants dans Apogée</input></div> """
)
H . append (
""" <div><input type= " checkbox " name= " allow_missing_decisions " value= " 1 " onchange= " document.f.submit() " """
)
if allow_missing_decisions :
H . append ( " checked " )
H . append (
""" >autoriser export même si des décisions de jury n ' ont pas été saisies</input></div> """
)
2020-10-02 21:34:59 +02:00
H . append (
""" <div><input type= " checkbox " name= " allow_missing_csv " value= " 1 " onchange= " document.f.submit() " """
)
if allow_missing_csv :
H . append ( " checked " )
2021-01-01 18:40:47 +01:00
H . append ( """ >autoriser export même si étapes sans maquettes</input></div> """ )
2020-09-26 16:19:37 +02:00
H . append ( """ </form> """ )
if semset and ok_for_export :
H . append (
""" <form class= " form_apo_export " action= " apo_csv_export_results " method= " get " >
< input type = " submit " value = " Export vers Apogée " >
< input type = " hidden " name = " semset_id " value = " %s " / >
"""
% ( semset_id , )
)
H . append ( ' <div id= " param_export_res " > ' )
def checked ( block , pname , msg ) :
if not prefs [ pname ] :
return (
" disabled " ,
" checked " ,
" <em>export de " + msg + " désactivé dans les paramètres</em> " ,
)
if block :
return " " , " checked " , " ne pas exporter " + msg
else :
return " " , " " , " ne pas exporter " + msg
H . append (
""" <div><label><input type= " checkbox " name= " block_export_res_etape " value= " 1 " %s %s > %s </input></label></div> """
% checked (
2021-01-01 18:40:47 +01:00
block_export_res_etape ,
" export_res_etape " ,
" résultat de l ' étape (VET), sauf si diplôme " ,
2020-09-26 16:19:37 +02:00
)
)
H . append (
""" <div><label><input type= " checkbox " name= " block_export_res_sem " value= " 1 " %s %s /> %s </label></div> """
% checked ( block_export_res_sem , " export_res_sem " , " résultat du semestre " )
)
H . append (
""" <div><label><input type= " checkbox " name= " block_export_res_ues " value= " 1 " %s %s /> %s </label></div> """
% checked ( block_export_res_ues , " export_res_ues " , " résultats d ' UE " )
)
H . append (
""" <div><label><input type= " checkbox " name= " block_export_res_modules " value= " 1 " %s %s /> %s </label></div> """
% checked (
block_export_res_modules , " export_res_modules " , " résultats de module "
)
)
H . append (
""" <div><label><input type= " checkbox " name= " block_export_res_sdj " value= " 1 " %s %s /> %s </label></div> """
% checked (
block_export_res_sdj ,
" export_res_sdj " ,
" résultats sans décision de jury " ,
)
)
H . append ( " </div> " )
H . append ( " </form> " )
# Elements:
missing = maq_elems - sem_elems
H . append ( ' <div id= " apo_elements " > ' )
H . append (
' <p>Elements Apogée: <span class= " apo_elems " > %s </span></p> '
% " , " . join (
[
e if not e in missing else ' <span class= " missing " > ' + e + " </span> "
for e in sorted ( maq_elems )
]
)
)
if missing :
formation_ids = { sem [ " formation_id " ] for sem in semset . sems }
2021-06-19 23:21:37 +02:00
formations = [
2021-08-19 10:28:35 +02:00
sco_formations . formation_list ( formation_id = i ) [ 0 ] for i in formation_ids
2021-06-19 23:21:37 +02:00
]
2020-09-26 16:19:37 +02:00
# log('formations=%s' % formations)
H . append (
' <div class= " apo_csv_status_missing_elems " ><span class= " fontred " >Elements Apogée absents dans ScoDoc: </span><span class= " apo_elems fontred " > %s </span> '
% " , " . join ( sorted ( missing ) )
)
H . append (
' <div class= " help " >Ces éléments de la maquette Apogée ne sont pas déclarés dans ScoDoc et ne seront donc pas remplis.</div><div> Vous pouvez les déclarer dans les programmes pédagogiques: '
)
H . append (
" , " . join (
[
2021-10-22 23:09:15 +02:00
' <a class= " stdlink " href= " ue_table?formation_id= %(formation_id)s " > %(acronyme)s v %(version)s </a> '
2020-09-26 16:19:37 +02:00
% f
for f in formations
]
)
)
H . append ( " </div></div> " )
H . append ( " </div> " )
H . append ( " </div> " )
# Aide:
H . append (
"""
< p > < a class = " stdlink " href = " semset_page " > Retour aux ensembles de semestres < / a > < / p >
< div class = " pas_help " >
< h3 > Explications < / h3 >
< p > Cette page permet de stocker les fichiers Apogée nécessaires pour
l ' export des résultats après les jurys, puis de remplir et exporter ces fichiers.
< / p >
< p >
Les fichiers ( " maquettes " ) Apogée sont de type CSV , du texte codé en % s .
< / p >
< p > On a un fichier par étape Apogée . Pour les obtenir , soit on peut les télécharger directement ( si votre ScoDoc est interfacé avec Apogée ) , soit se débrouiller pour exporter le fichier
texte depuis Apogée . Son contenu ressemble à cela : < / p >
< pre class = " small_pre_acc " >
XX - APO_TITRES - XX
apoC_annee 2007 / 2008
apoC_cod_dip VDTCJ
apoC_Cod_Exp 1
apoC_cod_vdi 111
apoC_Fichier_Exp VDTCJ_V1CJ . txt
apoC_lib_dip DUT CJ
apoC_Titre1 Export Apogée du 13 / 06 / 2008 à 14 : 29
apoC_Titre2
XX - APO_COLONNES - XX
apoL_a01_code Type Objet Code Version Année Session Admission / Admissibilité Type Rés . Etudiant Numéro
apoL_a02_nom 1 Nom
apoL_a03_prenom 1 Prénom
apoL_a04_naissance Session Admissibilité Naissance
APO_COL_VAL_DEB
apoL_c0001 VET V1CJ 111 2007 0 1 N V1CJ - DUT CJ an1 0 1 Note
apoL_c0002 VET V1CJ 111 2007 0 1 B 0 1 Barème
apoL_c0003 VET V1CJ 111 2007 0 1 R 0 1 Résultat
APO_COL_VAL_FIN
apoL_c0030 APO_COL_VAL_FIN
XX - APO_VALEURS - XX
apoL_a01_code apoL_a02_nom apoL_a03_prenom apoL_a04_naissance apoL_c0001 apoL_c0002 apoL_c0003 apoL_c0004 apoL_c0005 apoL_c0006 ( . . . )
11681234 DUPONT TOTO 23 / 09 / 1986 18 20 ADM 18 20 ADM ( . . . )
< / pre >
< p > Après avoir obtenu les fichier , stockez - les dans ScoDoc
( bouton " Ajouter fichier " en haut de cette page . Après vérification , il va
apparaitre dans une table . Vous pouvez supprimer ce fichier , ou en ajouter
d ' autres si votre semestre correspond à plusieurs étapes Apogée.
< / p >
< p > ScoDoc vérifie que tous les étudiants du semestre sont mentionnés dans
un fichier Apogée et que les étapes correspondent . < / p >
< p > Lorsque c ' est le cas, et que les décisions de jury sont saisies,
un bouton " Export vers Apogée " apparait et vous pouvez exporter les résultats .
< p >
< p > Vous obtiendrez alors un fichier ZIP comprenant tous les fichiers nécessaires .
Certains de ces fichiers devront être importés dans Apogée .
< / p >
< / div >
"""
% ( APO_INPUT_ENCODING , )
)
2021-07-29 10:19:00 +02:00
H . append ( html_sco_header . sco_footer ( ) )
2020-09-26 16:19:37 +02:00
return " \n " . join ( H )
2021-09-27 10:20:10 +02:00
def table_apo_csv_list ( semset ) :
2021-01-01 18:40:47 +01:00
""" Table des archives (triée par date d ' archivage) """
2020-09-26 16:19:37 +02:00
annee_scolaire = semset [ " annee_scolaire " ]
sem_id = semset [ " sem_id " ]
T = sco_etape_apogee . apo_csv_list_stored_archives (
2021-08-21 00:24:51 +02:00
annee_scolaire , sem_id , etapes = semset . list_etapes ( )
2020-09-26 16:19:37 +02:00
)
for t in T :
# Ajoute qq infos pour affichage:
2021-08-21 00:24:51 +02:00
csv_data = sco_etape_apogee . apo_csv_get ( t [ " etape_apo " ] , annee_scolaire , sem_id )
2020-09-26 16:19:37 +02:00
apo_data = sco_apogee_csv . ApoData ( csv_data , periode = semset [ " sem_id " ] )
t [ " filename " ] = apo_data . titles [ " apoC_Fichier_Exp " ]
t [ " nb_etuds " ] = len ( apo_data . etuds )
t [ " date_str " ] = t [ " date " ] . strftime ( " %d / % m/ % Y à % H: % M " )
view_link = " view_apo_csv?etape_apo= %s &semset_id= %s " % (
t [ " etape_apo " ] ,
semset [ " semset_id " ] ,
)
t [ " _filename_target " ] = view_link
t [ " _etape_apo_target " ] = view_link
2021-02-04 20:02:44 +01:00
t [ " suppress " ] = scu . icontag (
2020-09-26 16:19:37 +02:00
" delete_small_img " , border = " 0 " , alt = " supprimer " , title = " Supprimer "
)
t [ " _suppress_target " ] = " view_apo_csv_delete?etape_apo= %s &semset_id= %s " % (
t [ " etape_apo " ] ,
semset [ " semset_id " ] ,
)
columns_ids = [ " filename " , " etape_apo " , " date_str " , " nb_etuds " ]
# if can_edit:
columns_ids = [ " suppress " ] + columns_ids
tab = GenTable (
titles = {
" archive_id " : " " ,
" filename " : " Fichier " ,
" etape_apo " : " Etape " ,
" nb_etuds " : " Nb étudiants " ,
" date_str " : " Enregistré le " ,
} ,
columns_ids = columns_ids ,
rows = T ,
html_class = " table_leftalign apo_maq_list " ,
html_sortable = True ,
2021-09-18 10:10:02 +02:00
# base_url = '%s?formsemestre_id=%s' % (request.base_url, formsemestre_id),
2020-09-26 16:19:37 +02:00
# caption='Maquettes enregistrées',
2021-07-28 17:03:54 +02:00
preferences = sco_preferences . SemPreferences ( ) ,
2020-09-26 16:19:37 +02:00
)
return tab
2021-09-27 10:20:10 +02:00
def view_apo_etuds ( semset_id , title = " " , nip_list = " " , format = " html " ) :
2021-08-31 19:32:12 +02:00
""" Table des étudiants Apogée par nips
nip_list est une chaine , codes nip séparés par des ,
"""
2020-09-26 16:19:37 +02:00
if not semset_id :
raise ValueError ( " invalid null semset_id " )
2021-08-21 00:24:51 +02:00
semset = sco_semset . SemSet ( semset_id = semset_id )
2021-02-04 20:02:44 +01:00
# annee_scolaire = semset["annee_scolaire"]
# sem_id = semset["sem_id"]
2021-08-31 19:32:12 +02:00
if not isinstance ( nip_list , str ) :
nip_list = str ( nip_list )
nips = nip_list . split ( " , " )
2021-08-21 00:24:51 +02:00
etuds = sco_etape_apogee . apo_csv_retreive_etuds_by_nip ( semset , nips )
2020-09-26 16:19:37 +02:00
# Ils sont parfois dans ScoDoc même si pas dans le semestre: essaie de les retrouver
for etud in etuds . values ( ) :
2021-06-19 23:21:37 +02:00
etud_sco = sco_etud . get_etud_info ( code_nip = etud [ " nip " ] , filled = True )
2020-09-26 16:19:37 +02:00
if etud_sco :
e = etud_sco [ 0 ]
etud [ " inscriptions_scodoc " ] = " , " . join (
[
' <a href= " formsemestre_bulletinetud?formsemestre_id= {s[formsemestre_id]} &etudid= {e[etudid]} " > {s[etapes_apo_str]} (S {s[semestre_id]} )</a> ' . format (
s = sem , e = e
)
for sem in e [ " sems " ]
]
)
return _view_etuds_page (
semset_id ,
title = title ,
2021-07-09 17:47:06 +02:00
etuds = list ( etuds . values ( ) ) ,
2020-09-26 16:19:37 +02:00
keys = ( " nip " , " etape_apo " , " nom " , " prenom " , " inscriptions_scodoc " ) ,
format = format ,
)
2021-09-27 10:20:10 +02:00
def view_scodoc_etuds ( semset_id , title = " " , nip_list = " " , format = " html " ) :
2021-01-01 18:40:47 +01:00
""" Table des étudiants ScoDoc par nips ou etudids """
2021-08-31 19:32:12 +02:00
if not isinstance ( nip_list , str ) :
nip_list = str ( nip_list )
nips = nip_list . split ( " , " )
etuds = [ sco_etud . get_etud_info ( code_nip = nip , filled = True ) [ 0 ] for nip in nips ]
2020-09-26 16:19:37 +02:00
for e in etuds :
2021-07-11 17:37:12 +02:00
tgt = url_for ( " scolar.ficheEtud " , scodoc_dept = g . scodoc_dept , etudid = e [ " etudid " ] )
2020-09-26 16:19:37 +02:00
e [ " _nom_target " ] = tgt
e [ " _prenom_target " ] = tgt
e [ " _nom_td_attrs " ] = ' id= " %s " class= " etudinfo " ' % ( e [ " etudid " ] , )
e [ " _prenom_td_attrs " ] = ' id= " pre- %s " class= " etudinfo " ' % ( e [ " etudid " ] , )
return _view_etuds_page (
semset_id ,
title = title ,
etuds = etuds ,
keys = ( " code_nip " , " nom " , " prenom " ) ,
format = format ,
)
2021-09-27 10:20:10 +02:00
def _view_etuds_page ( semset_id , title = " " , etuds = [ ] , keys = ( ) , format = " html " ) :
2020-09-26 16:19:37 +02:00
# Tri les étudiants par nom:
if etuds :
etuds . sort ( key = lambda x : ( x [ " nom " ] , x [ " prenom " ] ) )
H = [
2021-06-13 19:12:20 +02:00
html_sco_header . sco_header (
page_title = title ,
init_qtip = True ,
javascripts = [ " js/etud_info.js " ] ,
2020-09-26 16:19:37 +02:00
) ,
" <h2> %s </h2> " % title ,
]
tab = GenTable (
titles = {
" nip " : " Code NIP " ,
" code_nip " : " Code NIP " ,
" etape_apo " : " Etape " ,
" nom " : " Nom " ,
" prenom " : " Prénom " ,
" inscriptions_scodoc " : " Inscriptions ScoDoc " ,
} ,
columns_ids = keys ,
rows = etuds ,
html_sortable = True ,
html_class = " table_leftalign " ,
filename = " students_apo " ,
2021-07-28 17:03:54 +02:00
preferences = sco_preferences . SemPreferences ( ) ,
2020-09-26 16:19:37 +02:00
)
if format != " html " :
2021-09-16 00:15:10 +02:00
return tab . make_page ( format = format )
2020-09-26 16:19:37 +02:00
H . append ( tab . html ( ) )
H . append (
""" <p><a href= " apo_semset_maq_status?semset_id= %s " >Retour à la page d ' export Apogée</a> """
% semset_id
)
2021-07-29 10:19:00 +02:00
return " \n " . join ( H ) + html_sco_header . sco_footer ( )
2020-09-26 16:19:37 +02:00
2022-01-07 17:58:34 +01:00
def view_apo_csv_store ( semset_id = " " , csvfile = None , data : bytes = " " , autodetect = False ) :
2020-09-26 16:19:37 +02:00
""" Store CSV data
Le semset identifie l ' annee scolaire et le semestre
Si csvfile , lit depuis FILE , sinon utilise data
"""
if not semset_id :
raise ValueError ( " invalid null semset_id " )
2021-08-21 00:24:51 +02:00
semset = sco_semset . SemSet ( semset_id = semset_id )
2020-09-26 16:19:37 +02:00
if csvfile :
2022-01-07 17:58:34 +01:00
data = csvfile . read ( ) # bytes
2020-09-26 16:19:37 +02:00
if autodetect :
# check encoding (although documentation states that users SHOULD upload LATIN1)
data , message = sco_apogee_csv . fix_data_encoding ( data )
if message :
log ( " view_apo_csv_store: %s " % message )
else :
log ( " view_apo_csv_store: autodetection of encoding disabled by user " )
if not data :
raise ScoValueError ( " view_apo_csv_store: no data " )
2022-01-07 17:58:34 +01:00
# data est du bytes, encodé en APO_INPUT_ENCODING
data_str = data . decode ( APO_INPUT_ENCODING )
2020-09-26 16:19:37 +02:00
# check si etape maquette appartient bien au semset
apo_data = sco_apogee_csv . ApoData (
2022-01-07 17:58:34 +01:00
data_str , periode = semset [ " sem_id " ]
2020-09-26 16:19:37 +02:00
) # parse le fichier -> exceptions
if apo_data . etape not in semset [ " etapes " ] :
raise ScoValueError (
" Le code étape de ce fichier ne correspond pas à ceux de cet ensemble "
)
2022-01-07 17:58:34 +01:00
sco_etape_apogee . apo_csv_store ( data_str , semset [ " annee_scolaire " ] , semset [ " sem_id " ] )
2020-09-26 16:19:37 +02:00
2022-01-07 17:58:34 +01:00
return flask . redirect (
url_for (
" notes.apo_semset_maq_status " ,
scodoc_dept = g . scodoc_dept ,
semset_id = semset_id ,
)
)
2020-09-26 16:19:37 +02:00
2021-09-27 10:20:10 +02:00
def view_apo_csv_download_and_store ( etape_apo = " " , semset_id = " " ) :
2021-01-01 18:40:47 +01:00
""" Download maquette and store it """
2020-09-26 16:19:37 +02:00
if not semset_id :
raise ValueError ( " invalid null semset_id " )
2021-08-21 00:24:51 +02:00
semset = sco_semset . SemSet ( semset_id = semset_id )
2020-09-26 16:19:37 +02:00
data = sco_portal_apogee . get_maquette_apogee (
2021-08-20 10:51:42 +02:00
etape = etape_apo , annee_scolaire = semset [ " annee_scolaire " ]
2020-09-26 16:19:37 +02:00
)
2022-01-07 17:58:34 +01:00
# here, data is str
2020-09-26 16:19:37 +02:00
# but we store and generate latin1 files, to ease further import in Apogée
2022-01-07 17:58:34 +01:00
data = data . encode ( APO_OUTPUT_ENCODING )
2021-09-27 10:20:10 +02:00
return view_apo_csv_store ( semset_id , data = data , autodetect = False )
2020-09-26 16:19:37 +02:00
2021-09-27 10:20:10 +02:00
def view_apo_csv_delete ( etape_apo = " " , semset_id = " " , dialog_confirmed = False ) :
2021-01-01 18:40:47 +01:00
""" Delete CSV file """
2020-09-26 16:19:37 +02:00
if not semset_id :
raise ValueError ( " invalid null semset_id " )
2021-08-21 00:24:51 +02:00
semset = sco_semset . SemSet ( semset_id = semset_id )
2021-10-05 23:43:32 +02:00
dest_url = f " apo_semset_maq_status?semset_id= { semset_id } "
2020-09-26 16:19:37 +02:00
if not dialog_confirmed :
2021-06-02 22:40:34 +02:00
return scu . confirm_dialog (
2020-09-26 16:19:37 +02:00
""" <h2>Confirmer la suppression du fichier étape <tt> %s </tt>?</h2>
< p > La suppression sera définitive . < / p > """
% ( etape_apo , ) ,
dest_url = " " ,
cancel_url = dest_url ,
parameters = { " semset_id " : semset_id , " etape_apo " : etape_apo } ,
)
info = sco_etape_apogee . apo_csv_get_archive (
2021-08-21 00:24:51 +02:00
etape_apo , semset [ " annee_scolaire " ] , semset [ " sem_id " ]
2020-09-26 16:19:37 +02:00
)
2021-08-21 00:24:51 +02:00
sco_etape_apogee . apo_csv_delete ( info [ " archive_id " ] )
2021-07-31 18:01:10 +02:00
return flask . redirect ( dest_url + " &head_message=Archive %20s upprimée " )
2020-09-26 16:19:37 +02:00
2021-09-27 10:20:10 +02:00
def view_apo_csv ( etape_apo = " " , semset_id = " " , format = " html " ) :
2020-09-26 16:19:37 +02:00
""" Visualise une maquette stockée
Si format = " raw " , renvoie le fichier maquette tel quel
"""
if not semset_id :
raise ValueError ( " invalid null semset_id " )
2021-08-21 00:24:51 +02:00
semset = sco_semset . SemSet ( semset_id = semset_id )
2020-09-26 16:19:37 +02:00
annee_scolaire = semset [ " annee_scolaire " ]
sem_id = semset [ " sem_id " ]
2021-08-21 00:24:51 +02:00
csv_data = sco_etape_apogee . apo_csv_get ( etape_apo , annee_scolaire , sem_id )
2020-09-26 16:19:37 +02:00
if format == " raw " :
2022-01-07 17:58:34 +01:00
return scu . send_file ( csv_data , etape_apo , suffix = " .txt " , mime = scu . CSV_MIMETYPE )
2021-09-16 00:15:10 +02:00
2020-09-26 16:19:37 +02:00
apo_data = sco_apogee_csv . ApoData ( csv_data , periode = semset [ " sem_id " ] )
(
ok_for_export ,
etapes_missing_csv ,
etuds_without_nip ,
nips_ok ,
nips_no_apo ,
nips_no_sco ,
apo_dups ,
maq_elems ,
sem_elems ,
2021-08-21 00:24:51 +02:00
) = sco_etape_apogee . apo_csv_semset_check ( semset )
2020-09-26 16:19:37 +02:00
H = [
2021-06-13 19:12:20 +02:00
html_sco_header . sco_header (
2020-09-26 16:19:37 +02:00
page_title = " Maquette Apogée enregistrée pour %s " % etape_apo ,
init_qtip = True ,
javascripts = [ " js/etud_info.js " ] ,
) ,
""" <h2>Etudiants dans la maquette Apogée %s </h2> """ % etape_apo ,
""" <p>Pour l ' ensemble <a class= " stdlink " href= " apo_semset_maq_status?semset_id= %(semset_id)s " > %(title)s </a> (indice semestre: %(sem_id)s )</p> """
% semset ,
]
# Infos générales
H . append (
"""
< div class = " apo_csv_infos " >
< div class = " apo_csv_etape " > < span > Code étape : < / span > < span > { 0. etape_apogee } VDI { 0. vdi_apogee } ( année { 0. annee_scolaire } ) < / span > < / div >
< / div >
""" .format(
apo_data
)
)
# Liste des étudiants (sans les résultats pour le moment): TODO
etuds = apo_data . etuds
if not etuds :
2021-07-29 10:19:00 +02:00
return " \n " . join ( H ) + " <p>Aucun étudiant</p> " + html_sco_header . sco_footer ( )
2020-09-26 16:19:37 +02:00
# Ajout infos sur ScoDoc vs Apogee
for e in etuds :
e [ " in_scodoc " ] = e [ " nip " ] not in nips_no_sco
e [ " in_scodoc_str " ] = { True : " oui " , False : " non " } [ e [ " in_scodoc " ] ]
if e [ " in_scodoc " ] :
2021-07-11 17:37:12 +02:00
e [ " _in_scodoc_str_target " ] = url_for (
" scolar.ficheEtud " , scodoc_dept = g . scodoc_dept , code_nip = e [ " nip " ]
)
2021-06-19 23:21:37 +02:00
e . update ( sco_etud . get_etud_info ( code_nip = e [ " nip " ] , filled = True ) [ 0 ] )
2020-09-26 16:19:37 +02:00
e [ " _nom_td_attrs " ] = ' id= " %s " class= " etudinfo " ' % ( e [ " etudid " ] , )
e [ " _prenom_td_attrs " ] = ' id= " pre- %s " class= " etudinfo " ' % ( e [ " etudid " ] , )
else :
e [ " _css_row_class " ] = " apo_not_scodoc "
# Construit la table:
tab = GenTable (
titles = {
" nip " : " Code NIP " ,
" nom " : " Nom " ,
" prenom " : " Prénom " ,
" naissance " : " Naissance " ,
" in_scodoc_str " : " Inscrit dans ces semestres ScoDoc " ,
} ,
columns_ids = ( " nip " , " nom " , " prenom " , " naissance " , " in_scodoc_str " ) ,
rows = etuds ,
html_sortable = True ,
html_class = " table_leftalign apo_maq_table " ,
2021-09-18 10:10:02 +02:00
base_url = " %s ?etape_apo= %s &semset_id= %s "
% ( request . base_url , etape_apo , semset_id ) ,
2020-09-26 16:19:37 +02:00
filename = " students_ " + etape_apo ,
caption = " Etudiants Apogée en " + etape_apo ,
2021-07-28 17:03:54 +02:00
preferences = sco_preferences . SemPreferences ( ) ,
2020-09-26 16:19:37 +02:00
)
if format != " html " :
2021-09-16 00:15:10 +02:00
return tab . make_page ( format = format )
2020-09-26 16:19:37 +02:00
H + = [
tab . html ( ) ,
""" <p><a class= " stdlink " href= " view_apo_csv?etape_apo= %s &semset_id= %s &format=raw " >fichier maquette CSV brut (non rempli par ScoDoc)</a></p> """
% ( etape_apo , semset_id ) ,
""" <div><a class= " stdlink " href= " apo_semset_maq_status?semset_id= %s " >Retour</a>
< / div > """
% semset_id ,
2021-07-29 10:19:00 +02:00
html_sco_header . sco_footer ( ) ,
2020-09-26 16:19:37 +02:00
]
return " \n " . join ( H )
2021-09-21 14:01:46 +02:00
# called from Web (GET)
2020-09-26 16:19:37 +02:00
def apo_csv_export_results (
semset_id ,
block_export_res_etape = False ,
block_export_res_sem = False ,
block_export_res_ues = False ,
block_export_res_modules = False ,
block_export_res_sdj = False ,
) :
""" Remplit les fichiers CSV archivés
et donne un ZIP avec tous les résultats .
"""
# nota: on peut éventuellement exporter même si tout n'est pas ok
# mais le lien via le tableau de bord n'est pas actif
# Les fichiers résultats ne sont pas stockés: pas besoin de permission particulière
2021-07-28 17:03:54 +02:00
prefs = sco_preferences . SemPreferences ( )
2020-09-26 16:19:37 +02:00
export_res_etape = prefs [ " export_res_etape " ] and not int ( block_export_res_etape )
export_res_sem = prefs [ " export_res_sem " ] and not int ( block_export_res_sem )
export_res_ues = prefs [ " export_res_ues " ] and not int ( block_export_res_ues )
export_res_modules = prefs [ " export_res_modules " ] and not int (
block_export_res_modules
)
export_res_sdj = prefs [ " export_res_sdj " ] and not int ( block_export_res_sdj )
export_res_rat = prefs [ " export_res_rat " ]
if not semset_id :
raise ValueError ( " invalid null semset_id " )
2021-08-21 00:24:51 +02:00
semset = sco_semset . SemSet ( semset_id = semset_id )
2020-09-26 16:19:37 +02:00
annee_scolaire = semset [ " annee_scolaire " ]
periode = semset [ " sem_id " ]
2021-08-31 19:32:12 +02:00
data = io . BytesIO ( )
2020-09-26 16:19:37 +02:00
dest_zip = ZipFile ( data , " w " )
etapes_apo = sco_etape_apogee . apo_csv_list_stored_etapes (
2021-08-21 00:24:51 +02:00
annee_scolaire , periode , etapes = semset . list_etapes ( )
2020-09-26 16:19:37 +02:00
)
for etape_apo in etapes_apo :
2021-08-21 00:24:51 +02:00
apo_csv = sco_etape_apogee . apo_csv_get ( etape_apo , annee_scolaire , periode )
2020-09-26 16:19:37 +02:00
sco_apogee_csv . export_csv_to_apogee (
apo_csv ,
periode = periode ,
export_res_etape = export_res_etape ,
export_res_sem = export_res_sem ,
export_res_ues = export_res_ues ,
export_res_modules = export_res_modules ,
export_res_sdj = export_res_sdj ,
export_res_rat = export_res_rat ,
dest_zip = dest_zip ,
)
2021-08-31 19:32:12 +02:00
dest_zip . close ( )
data . seek ( 0 )
2020-09-26 16:19:37 +02:00
basename = (
2021-07-28 17:03:54 +02:00
sco_preferences . get_preference ( " DeptName " )
2020-09-26 16:19:37 +02:00
+ str ( annee_scolaire )
+ " - %s - " % periode
+ " - " . join ( etapes_apo )
)
2021-08-31 20:18:50 +02:00
basename = scu . unescape_html ( basename )
2020-09-26 16:19:37 +02:00
2021-08-31 19:32:12 +02:00
return send_file (
data ,
mimetype = " application/zip " ,
2021-08-31 20:18:50 +02:00
download_name = scu . sanitize_filename ( basename + " .zip " ) ,
2021-08-31 19:32:12 +02:00
as_attachment = True ,
2020-09-26 16:19:37 +02:00
)