2021-05-31 00:14:15 +02:00
# -*- coding: utf-8 -*-
2021-06-02 22:40:34 +02:00
##############################################################################
#
# ScoDoc
#
2023-01-02 13:16:27 +01:00
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
2021-06-02 22:40:34 +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
#
##############################################################################
2021-05-31 00:14:15 +02:00
"""
2021-07-10 07:27:06 +02:00
Module scolar : vues de . . . / ScoDoc / < dept > / Scolarite
issu de ScoDoc7 / ZScolar . py
2021-05-31 00:14:15 +02:00
Emmanuel Viennet , 2021
"""
2022-09-03 09:29:40 +02:00
import datetime
2022-03-21 11:48:34 +01:00
import requests
2021-06-02 22:40:34 +02:00
import time
2021-08-01 10:16:16 +02:00
import flask
2021-11-03 16:15:39 +01:00
from flask import jsonify , url_for , flash , render_template , make_response
2022-02-12 14:59:18 +01:00
from flask import g , request
2021-08-10 17:12:10 +02:00
from flask_login import current_user
2021-09-08 23:00:01 +02:00
from flask_wtf import FlaskForm
from flask_wtf . file import FileField , FileAllowed
2021-11-16 18:48:56 +01:00
from wtforms import SubmitField
2021-05-31 00:14:15 +02:00
2022-04-12 17:12:51 +02:00
from app import db
2021-12-26 19:15:47 +01:00
from app import log
2021-05-31 00:14:15 +02:00
from app . decorators import (
2021-08-13 00:34:58 +02:00
scodoc ,
2021-05-31 00:14:15 +02:00
scodoc7func ,
permission_required ,
2021-09-09 16:11:05 +02:00
permission_required_compat_scodoc7 ,
2021-05-31 00:14:15 +02:00
admin_required ,
login_required ,
)
2021-12-20 22:53:09 +01:00
from app . models . etudiants import Identite
2021-12-26 19:15:47 +01:00
from app . models . etudiants import make_etud_args
2022-09-30 22:43:39 +02:00
from app . models . events import ScolarNews , Scolog
2022-05-22 05:01:25 +02:00
from app . models . formsemestre import FormSemestre
2022-09-30 22:43:39 +02:00
from app . models . validations import ScolarEvent
2021-05-31 00:14:15 +02:00
from app . views import scolar_bp as bp
2022-04-12 17:12:51 +02:00
from app . views import ScoData
2021-05-31 00:14:15 +02:00
2021-06-02 22:40:34 +02:00
import app . scodoc . sco_utils as scu
import app . scodoc . notesdb as ndb
from app . scodoc . scolog import logdb
2021-06-19 23:21:37 +02:00
from app . scodoc . sco_permissions import Permission
2021-06-02 22:40:34 +02:00
from app . scodoc . sco_exceptions import (
AccessDenied ,
ScoException ,
ScoValueError ,
)
2022-09-03 09:29:40 +02:00
from app . scodoc . TrivialFormulator import DMY_REGEXP , TrivialFormulator , tf_error_message
2021-06-02 22:40:34 +02:00
from app . scodoc . gen_tables import GenTable
2021-06-19 23:21:37 +02:00
from app . scodoc import html_sco_header
2021-06-21 10:17:16 +02:00
from app . scodoc import sco_import_etuds
2021-06-19 23:21:37 +02:00
from app . scodoc import sco_archives_etud
2023-02-12 13:36:47 +01:00
from app . scodoc import codes_cursus
2021-07-19 19:53:01 +02:00
from app . scodoc import sco_cache
2021-06-19 23:21:37 +02:00
from app . scodoc import sco_debouche
from app . scodoc import sco_dept
from app . scodoc import sco_dump_db
2022-03-19 22:00:31 +01:00
from app . scodoc import sco_etud
2021-06-12 22:43:22 +02:00
from app . scodoc import sco_find_etud
from app . scodoc import sco_formsemestre
2021-06-16 16:59:31 +02:00
from app . scodoc import sco_formsemestre_inscriptions
2021-06-19 23:21:37 +02:00
from app . scodoc import sco_groups
from app . scodoc import sco_groups_edit
2022-03-02 23:14:04 +01:00
from app . scodoc import sco_groups_exports
2021-06-19 23:21:37 +02:00
from app . scodoc import sco_groups_view
from app . scodoc import sco_page_etud
from app . scodoc import sco_permissions_check
from app . scodoc import sco_photos
2021-06-12 22:43:22 +02:00
from app . scodoc import sco_portal_apogee
2021-06-19 23:21:37 +02:00
from app . scodoc import sco_preferences
2021-06-12 22:43:22 +02:00
from app . scodoc import sco_synchro_etuds
from app . scodoc import sco_trombino
from app . scodoc import sco_trombino_tours
from app . scodoc import sco_up_to_date
2021-08-13 09:31:49 +02:00
def sco_publish ( route , function , permission , methods = [ " GET " ] ) :
2021-06-12 22:43:22 +02:00
""" Declare a route for a python function,
protected by permission and called following ScoDoc 7 Zope standards .
"""
2021-06-25 19:24:12 +02:00
return bp . route ( route , methods = methods ) (
2021-08-21 00:24:51 +02:00
scodoc ( permission_required ( permission ) ( scodoc7func ( function ) ) )
2021-06-16 18:18:32 +02:00
)
2021-06-02 22:40:34 +02:00
# --------------------------------------------------------------------
#
# SCOLARITE (/ScoDoc/<dept>/Scolarite/...)
#
# --------------------------------------------------------------------
2021-05-31 00:14:15 +02:00
2021-06-02 22:40:34 +02:00
# --------------------------------------------------------------------
#
# PREFERENCES
#
# --------------------------------------------------------------------
2021-06-21 14:40:58 +02:00
@bp.route ( " /edit_preferences " , methods = [ " GET " , " POST " ] )
2021-08-13 00:34:58 +02:00
@scodoc
2021-06-02 22:40:34 +02:00
@permission_required ( Permission . ScoChangePreferences )
2021-08-21 00:24:51 +02:00
@scodoc7func
2021-09-27 10:20:10 +02:00
def edit_preferences ( ) :
2021-06-16 18:18:32 +02:00
""" Edit global preferences (lien " Paramétrage " département) """
2021-09-27 10:20:10 +02:00
return sco_preferences . get_base_preferences ( ) . edit ( )
2021-06-02 22:40:34 +02:00
2021-06-25 19:24:12 +02:00
@bp.route ( " /formsemestre_edit_preferences " , methods = [ " GET " , " POST " ] )
2021-08-13 00:34:58 +02:00
@scodoc
2021-06-02 22:40:34 +02:00
@permission_required ( Permission . ScoView )
2021-08-21 00:24:51 +02:00
@scodoc7func
2021-09-27 10:20:10 +02:00
def formsemestre_edit_preferences ( formsemestre_id ) :
2021-06-02 22:40:34 +02:00
""" Edit preferences for a semestre """
2021-08-19 10:28:35 +02:00
sem = sco_formsemestre . get_formsemestre ( formsemestre_id )
2021-06-02 22:40:34 +02:00
ok = (
2021-08-22 13:24:36 +02:00
current_user . has_permission ( Permission . ScoImplement )
or ( ( current_user . id in sem [ " responsables " ] ) and sem [ " resp_can_edit " ] )
2021-08-10 12:57:38 +02:00
) and ( sem [ " etat " ] )
2021-06-02 22:40:34 +02:00
if ok :
2021-09-27 10:20:10 +02:00
return sco_preferences . SemPreferences ( formsemestre_id = formsemestre_id ) . edit ( )
2021-06-02 22:40:34 +02:00
else :
2021-08-22 13:24:36 +02:00
raise AccessDenied (
" Modification impossible pour %s " % current_user . get_nomplogin ( )
)
2021-06-02 22:40:34 +02:00
@bp.route ( " /doc_preferences " )
2021-08-13 00:34:58 +02:00
@scodoc
2021-06-02 22:40:34 +02:00
@permission_required ( Permission . ScoView )
2021-08-21 00:24:51 +02:00
@scodoc7func
2021-09-27 10:20:10 +02:00
def doc_preferences ( ) :
2021-06-02 22:40:34 +02:00
""" List preferences for wiki documentation """
2021-09-27 10:20:10 +02:00
response = make_response ( sco_preferences . doc_preferences ( ) )
response . headers [ " Content-Type " ] = " text/plain "
return response
2021-06-02 22:40:34 +02:00
2021-11-16 18:48:56 +01:00
class DeptLogosConfigurationForm ( FlaskForm ) :
" Panneau de configuration logos dept "
logo_header = FileField (
label = " Modifier l ' image: " ,
description = " logo placé en haut des documents PDF " ,
validators = [
FileAllowed (
scu . LOGOS_IMAGES_ALLOWED_TYPES ,
2021-11-19 11:51:05 +01:00
f " n ' accepte que les fichiers image <tt> { ' , ' . join ( scu . LOGOS_IMAGES_ALLOWED_TYPES ) } </tt> " ,
2021-11-16 18:48:56 +01:00
)
] ,
)
logo_footer = FileField (
label = " Modifier l ' image: " ,
description = " logo placé en pied des documents PDF " ,
validators = [
FileAllowed (
scu . LOGOS_IMAGES_ALLOWED_TYPES ,
2021-11-19 11:51:05 +01:00
f " n ' accepte que les fichiers image <tt> { ' , ' . join ( scu . LOGOS_IMAGES_ALLOWED_TYPES ) } </tt> " ,
2021-11-16 18:48:56 +01:00
)
] ,
)
submit = SubmitField ( " Enregistrer " )
2021-11-19 11:51:05 +01:00
# @bp.route("/config_logos", methods=["GET", "POST"])
# @permission_required(Permission.ScoChangePreferences)
# def config_logos(scodoc_dept):
# "Panneau de configuration général"
# form = DeptLogosConfigurationForm()
# if form.validate_on_submit():
# if form.logo_header.data:
# sco_logos.store_image(
# form.logo_header.data,
# os.path.join(
# scu.SCODOC_LOGOS_DIR, "logos_" + scodoc_dept, "logo_header"
# ),
# )
# if form.logo_footer.data:
# sco_logos.store_image(
# form.logo_footer.data,
# os.path.join(
# scu.SCODOC_LOGOS_DIR, "logos_" + scodoc_dept, "logo_footer"
# ),
# )
# app.clear_scodoc_cache()
# flash(f"Logos enregistrés")
# return flask.redirect(url_for("scolar.index_html", scodoc_dept=scodoc_dept))
#
# return render_template(
2023-01-30 22:25:17 +01:00
# "configuration.j2",
2021-11-19 11:51:05 +01:00
# title="Configuration Logos du département",
# form=form,
# scodoc_dept=scodoc_dept,
# )
#
#
# class DeptLogosConfigurationForm(FlaskForm):
# "Panneau de configuration logos dept"
#
# logo_header = FileField(
# label="Modifier l'image:",
# description="logo placé en haut des documents PDF",
# validators=[
# FileAllowed(
# scu.LOGOS_IMAGES_ALLOWED_TYPES,
# f"n'accepte que les fichiers image <tt>{','.join([e for e in scu.LOGOS_IMAGES_ALLOWED_TYPES])}</tt>",
# )
# ],
# )
#
# logo_footer = FileField(
# label="Modifier l'image:",
# description="logo placé en pied des documents PDF",
# validators=[
# FileAllowed(
# scu.LOGOS_IMAGES_ALLOWED_TYPES,
# f"n'accepte que les fichiers image <tt>{','.join([e for e in scu.LOGOS_IMAGES_ALLOWED_TYPES])}</tt>",
# )
# ],
# )
#
# submit = SubmitField("Enregistrer")
# @bp.route("/config_logos", methods=["GET", "POST"])
# @permission_required(Permission.ScoChangePreferences)
# def config_logos(scodoc_dept):
# "Panneau de configuration général"
# form = DeptLogosConfigurationForm()
# if form.validate_on_submit():
# if form.logo_header.data:
# sco_logos.store_image(
# form.logo_header.data,
# os.path.join(
# scu.SCODOC_LOGOS_DIR, "logos_" + scodoc_dept, "logo_header"
# ),
# )
# if form.logo_footer.data:
# sco_logos.store_image(
# form.logo_footer.data,
# os.path.join(
# scu.SCODOC_LOGOS_DIR, "logos_" + scodoc_dept, "logo_footer"
# ),
# )
# app.clear_scodoc_cache()
# flash(f"Logos enregistrés")
# return flask.redirect(url_for("scolar.index_html", scodoc_dept=scodoc_dept))
#
# return render_template(
2023-01-30 22:25:17 +01:00
# "configuration.j2",
2021-11-19 11:51:05 +01:00
# title="Configuration Logos du département",
# form=form,
# scodoc_dept=scodoc_dept,
# )
2021-11-16 18:48:56 +01:00
2021-06-02 22:40:34 +02:00
# --------------------------------------------------------------------
#
# ETUDIANTS
#
# --------------------------------------------------------------------
@bp.route ( " /showEtudLog " )
2021-08-13 00:34:58 +02:00
@scodoc
2021-06-02 22:40:34 +02:00
@permission_required ( Permission . ScoView )
2021-08-21 00:24:51 +02:00
@scodoc7func
2021-09-27 10:20:10 +02:00
def showEtudLog ( etudid , format = " html " ) :
2021-06-02 22:40:34 +02:00
""" Display log of operations on this student """
2021-08-22 13:24:36 +02:00
etud = sco_etud . get_etud_info ( filled = True ) [ 0 ]
2021-06-02 22:40:34 +02:00
2021-08-21 00:24:51 +02:00
ops = sco_etud . list_scolog ( etudid )
2021-06-02 22:40:34 +02:00
tab = GenTable (
titles = {
" date " : " Date " ,
" authenticated_user " : " Utilisateur " ,
" remote_addr " : " IP " ,
" method " : " Opération " ,
" msg " : " Message " ,
} ,
columns_ids = ( " date " , " authenticated_user " , " remote_addr " , " method " , " msg " ) ,
rows = ops ,
html_sortable = True ,
html_class = " table_leftalign " ,
2021-09-18 10:10:02 +02:00
base_url = " %s ?etudid= %s " % ( request . base_url , etudid ) ,
2021-06-02 22:40:34 +02:00
page_title = " Opérations sur %(nomprenom)s " % etud ,
html_title = " <h2>Opérations effectuées sur l ' étudiant %(nomprenom)s </h2> " % etud ,
filename = " log_ " + scu . make_filename ( etud [ " nomprenom " ] ) ,
2021-07-19 19:53:01 +02:00
html_next_section = f """
< ul > < li >
< a href = " { url_for( " scolar . ficheEtud " , scodoc_dept=g.scodoc_dept, etudid=etudid)} " >
fiche de { etud [ ' nomprenom ' ] } < / a > < / li >
< / ul > """ ,
2021-07-28 17:03:54 +02:00
preferences = sco_preferences . SemPreferences ( ) ,
2021-06-02 22:40:34 +02:00
)
2021-09-16 00:15:10 +02:00
return tab . make_page ( format = format )
2021-06-02 22:40:34 +02:00
# ---------- PAGE ACCUEIL (listes) --------------
2021-08-13 00:34:58 +02:00
2022-04-18 07:55:12 +02:00
@bp.route ( " / " , alias = True )
2021-08-13 09:31:49 +02:00
@bp.route ( " /index_html " )
2021-08-13 00:34:58 +02:00
@scodoc
2021-06-25 19:24:12 +02:00
@permission_required ( Permission . ScoView )
2021-08-21 00:24:51 +02:00
@scodoc7func
2021-09-27 10:20:10 +02:00
def index_html ( showcodes = 0 , showsemtable = 0 ) :
return sco_dept . index_html ( showcodes = showcodes , showsemtable = showsemtable )
2021-06-02 22:40:34 +02:00
2022-03-19 22:00:31 +01:00
@bp.route ( " /install_info " )
@scodoc
@permission_required ( Permission . ScoView )
def install_info ( ) :
""" Information on install status (html str) """
return sco_up_to_date . is_up_to_date ( )
2022-04-12 17:12:51 +02:00
@bp.route ( " /dept_news " )
@scodoc
@permission_required ( Permission . ScoView )
def dept_news ( ) :
" Affiche table des dernières opérations "
return render_template (
2023-01-30 22:25:17 +01:00
" dept_news.j2 " , title = f " Opérations { g . scodoc_dept } " , sco = ScoData ( )
2022-04-12 17:12:51 +02:00
)
@bp.route ( " /dept_news_json " )
@scodoc
@permission_required ( Permission . ScoView )
def dept_news_json ( ) :
" Table des news du département "
start = request . args . get ( " start " , type = int )
length = request . args . get ( " length " , type = int )
log ( f " dept_news_json( start= { start } , length= { length } ) " )
query = ScolarNews . query . filter_by ( dept_id = g . scodoc_dept_id )
# search
search = request . args . get ( " search[value] " )
if search :
query = query . filter (
db . or_ (
ScolarNews . authenticated_user . like ( f " % { search } % " ) ,
ScolarNews . text . like ( f " % { search } % " ) ,
)
)
total_filtered = query . count ( )
# sorting
order = [ ]
i = 0
while True :
col_index = request . args . get ( f " order[ { i } ][column] " )
if col_index is None :
break
col_name = request . args . get ( f " columns[ { col_index } ][data] " )
if col_name not in [ " date " , " type " , " authenticated_user " ] :
col_name = " date "
descending = request . args . get ( f " order[ { i } ][dir] " ) == " desc "
col = getattr ( ScolarNews , col_name )
if descending :
col = col . desc ( )
order . append ( col )
i + = 1
if order :
query = query . order_by ( * order )
# pagination
query = query . offset ( start ) . limit ( length )
data = [ news . to_dict ( ) for news in query ]
# response
return {
" data " : data ,
" recordsFiltered " : total_filtered ,
" recordsTotal " : ScolarNews . query . count ( ) ,
" draw " : request . args . get ( " draw " , type = int ) ,
}
2021-08-02 09:16:57 +02:00
sco_publish (
" /trombino " , sco_trombino . trombino , Permission . ScoView , methods = [ " GET " , " POST " ]
)
2021-06-02 22:40:34 +02:00
sco_publish (
" /pdf_trombino_tours " , sco_trombino_tours . pdf_trombino_tours , Permission . ScoView
)
sco_publish (
" /pdf_feuille_releve_absences " ,
sco_trombino_tours . pdf_feuille_releve_absences ,
Permission . ScoView ,
)
sco_publish (
2021-09-08 00:34:45 +02:00
" /trombino_copy_photos " ,
sco_trombino . trombino_copy_photos ,
Permission . ScoView ,
methods = [ " GET " , " POST " ] ,
2021-06-02 22:40:34 +02:00
)
2022-03-02 23:14:04 +01:00
sco_publish (
" /groups_export_annotations " ,
sco_groups_exports . groups_export_annotations ,
Permission . ScoView ,
)
2021-11-01 16:59:56 +01:00
@bp.route ( " /groups_view " )
@scodoc
@permission_required_compat_scodoc7 ( Permission . ScoView )
@scodoc7func
def groups_view (
group_ids = ( ) ,
format = " html " ,
# Options pour listes:
with_codes = 0 ,
etat = None ,
with_paiement = 0 , # si vrai, ajoute colonnes infos paiement droits et finalisation inscription (lent car interrogation portail)
with_archives = 0 , # ajoute colonne avec noms fichiers archivés
with_annotations = 0 ,
2022-12-07 15:52:50 +01:00
with_bourse = 0 ,
2021-11-01 16:59:56 +01:00
formsemestre_id = None ,
) :
return sco_groups_view . groups_view (
2021-11-03 00:27:50 +01:00
group_ids = group_ids ,
2021-11-01 16:59:56 +01:00
format = format ,
# Options pour listes:
with_codes = with_codes ,
etat = etat ,
2022-12-07 15:52:50 +01:00
with_paiement = with_paiement ,
with_archives = with_archives ,
2021-11-01 16:59:56 +01:00
with_annotations = with_annotations ,
2022-12-07 15:52:50 +01:00
with_bourse = with_bourse ,
2021-11-01 16:59:56 +01:00
formsemestre_id = formsemestre_id ,
)
2021-06-02 22:40:34 +02:00
sco_publish (
" /export_groups_as_moodle_csv " ,
sco_groups_view . export_groups_as_moodle_csv ,
Permission . ScoView ,
)
# -------------------------- INFOS SUR ETUDIANTS --------------------------
@bp.route ( " /getEtudInfo " )
2021-08-13 00:34:58 +02:00
@scodoc
2021-06-02 22:40:34 +02:00
@permission_required ( Permission . ScoView )
2021-08-21 00:24:51 +02:00
@scodoc7func
2021-09-27 10:20:10 +02:00
def getEtudInfo ( etudid = False , code_nip = False , filled = False , format = None ) :
2021-06-02 22:40:34 +02:00
""" infos sur un etudiant (API)
2021-06-14 00:23:22 +02:00
On peut specifier etudid ou code_nip
2021-09-27 10:20:10 +02:00
ou bien cherche dans les arguments de la requête : etudid , code_nip , code_ine
2021-06-02 22:40:34 +02:00
( dans cet ordre ) .
"""
2021-08-22 13:24:36 +02:00
etud = sco_etud . get_etud_info ( etudid = etudid , code_nip = code_nip , filled = filled )
2021-06-02 22:40:34 +02:00
if format is None :
return etud
else :
2021-09-21 15:53:33 +02:00
return scu . sendResult ( etud , name = " etud " , format = format )
2021-06-02 22:40:34 +02:00
sco_publish (
2021-07-13 14:53:14 +02:00
" /search_etud_in_dept " ,
sco_find_etud . search_etud_in_dept ,
Permission . ScoView ,
methods = [ " GET " , " POST " ] ,
2021-06-02 22:40:34 +02:00
)
2021-08-31 08:21:30 +02:00
@bp.route ( " /search_etud_by_name " )
@bp.route ( " /Notes/search_etud_by_name " ) # for JS apis
@scodoc
@permission_required ( Permission . ScoView )
def search_etud_by_name ( ) :
term = request . args [ " term " ]
data = sco_find_etud . search_etud_by_name ( term )
return jsonify ( data )
2021-06-02 22:40:34 +02:00
# XMLgetEtudInfos était le nom dans l'ancienne API ScoDoc 6
2021-09-10 22:03:52 +02:00
@bp.route ( " /etud_info " , methods = [ " GET " , " POST " ] ) # pour compat anciens clients PHP)
@bp.route (
" /XMLgetEtudInfos " , methods = [ " GET " , " POST " ]
) # pour compat anciens clients PHP)
@bp.route (
" /Absences/XMLgetEtudInfos " , methods = [ " GET " , " POST " ]
) # pour compat anciens clients PHP
@bp.route (
" /Notes/XMLgetEtudInfos " , methods = [ " GET " , " POST " ]
) # pour compat anciens clients PHP
2021-10-26 00:13:42 +02:00
@scodoc
2021-10-28 00:52:23 +02:00
@permission_required_compat_scodoc7 ( Permission . ScoView )
2021-08-21 00:24:51 +02:00
@scodoc7func
2021-09-27 10:20:10 +02:00
def etud_info ( etudid = None , format = " xml " ) :
2021-06-02 22:40:34 +02:00
" Donne les informations sur un etudiant "
2021-10-20 22:34:06 +02:00
if not format in ( " xml " , " json " ) :
raise ScoValueError ( " format demandé non supporté par cette fonction. " )
2021-06-02 22:40:34 +02:00
t0 = time . time ( )
2021-12-26 19:15:47 +01:00
args = make_etud_args ( etudid = etudid )
2021-06-15 13:59:56 +02:00
cnx = ndb . GetDBConnexion ( )
2021-06-19 23:21:37 +02:00
etuds = sco_etud . etudident_list ( cnx , args )
2021-06-02 22:40:34 +02:00
if not etuds :
# etudiant non trouvé: message d'erreur
d = {
" etudid " : etudid ,
" nom " : " ? " ,
" nom_usuel " : " " ,
" prenom " : " ? " ,
" civilite " : " ? " ,
" sexe " : " ? " , # for backward compat
" email " : " ? " ,
" emailperso " : " " ,
" error " : " code etudiant inconnu " ,
}
return scu . sendResult (
2021-09-21 15:53:33 +02:00
d , name = " etudiant " , format = format , force_outer_xml_tag = False
2021-06-02 22:40:34 +02:00
)
d = { }
etud = etuds [ 0 ]
2021-06-19 23:21:37 +02:00
sco_etud . fill_etuds_info ( [ etud ] )
2021-06-02 22:40:34 +02:00
etud [ " date_naissance_iso " ] = ndb . DateDMYtoISO ( etud [ " date_naissance " ] )
for a in (
" etudid " ,
" code_nip " ,
" code_ine " ,
" nom " ,
" nom_usuel " ,
" prenom " ,
" nomprenom " ,
" email " ,
" emailperso " ,
" domicile " ,
" codepostaldomicile " ,
" villedomicile " ,
" paysdomicile " ,
" telephone " ,
" telephonemobile " ,
" fax " ,
" bac " ,
" specialite " ,
" annee_bac " ,
" nomlycee " ,
" villelycee " ,
" codepostallycee " ,
" codelycee " ,
" date_naissance_iso " ,
) :
2021-10-20 23:18:00 +02:00
d [ a ] = etud [ a ] # ne pas quoter car ElementTree.tostring quote déjà
d [ " civilite " ] = etud [ " civilite_str " ] # exception: ne sort pas la civilite brute
2021-06-02 22:40:34 +02:00
d [ " sexe " ] = d [ " civilite " ] # backward compat pour anciens clients
2021-10-20 23:18:00 +02:00
d [ " photo_url " ] = sco_photos . etud_photo_url ( etud )
2021-06-02 22:40:34 +02:00
sem = etud [ " cursem " ]
if sem :
2022-03-05 12:47:08 +01:00
sco_groups . etud_add_group_infos ( etud , sem [ " formsemestre_id " ] if sem else None )
2021-06-02 22:40:34 +02:00
d [ " insemestre " ] = [
{
" current " : " 1 " ,
" formsemestre_id " : sem [ " formsemestre_id " ] ,
" date_debut " : ndb . DateDMYtoISO ( sem [ " date_debut " ] ) ,
" date_fin " : ndb . DateDMYtoISO ( sem [ " date_fin " ] ) ,
2021-10-20 23:18:00 +02:00
" etat " : sem [ " ins " ] [ " etat " ] ,
" groupes " : etud [ " groupes " ] , # slt pour semestre courant
2021-06-02 22:40:34 +02:00
}
]
else :
d [ " insemestre " ] = [ ]
for sem in etud [ " sems " ] :
if sem != etud [ " cursem " ] :
d [ " insemestre " ] . append (
{
" formsemestre_id " : sem [ " formsemestre_id " ] ,
" date_debut " : ndb . DateDMYtoISO ( sem [ " date_debut " ] ) ,
" date_fin " : ndb . DateDMYtoISO ( sem [ " date_fin " ] ) ,
2021-10-20 23:18:00 +02:00
" etat " : sem [ " ins " ] [ " etat " ] ,
2021-06-02 22:40:34 +02:00
}
)
log ( " etud_info ( %g s) " % ( time . time ( ) - t0 ) )
2021-10-20 22:34:06 +02:00
return scu . sendResult (
d , name = " etudiant " , format = format , force_outer_xml_tag = False , quote_xml = False
)
2021-06-02 22:40:34 +02:00
# -------------------------- FICHE ETUDIANT --------------------------
sco_publish ( " /ficheEtud " , sco_page_etud . ficheEtud , Permission . ScoView )
sco_publish (
" /etud_upload_file_form " ,
sco_archives_etud . etud_upload_file_form ,
Permission . ScoView ,
2021-06-25 19:24:12 +02:00
methods = [ " GET " , " POST " ] ,
2021-06-02 22:40:34 +02:00
)
sco_publish (
2021-07-13 14:53:14 +02:00
" /etud_delete_archive " ,
sco_archives_etud . etud_delete_archive ,
Permission . ScoView ,
methods = [ " GET " , " POST " ] ,
2021-06-02 22:40:34 +02:00
)
sco_publish (
" /etud_get_archived_file " ,
sco_archives_etud . etud_get_archived_file ,
Permission . ScoView ,
)
sco_publish (
" /etudarchive_import_files_form " ,
sco_archives_etud . etudarchive_import_files_form ,
Permission . ScoView ,
2021-06-25 19:24:12 +02:00
methods = [ " GET " , " POST " ] ,
2021-06-02 22:40:34 +02:00
)
sco_publish (
" /etudarchive_generate_excel_sample " ,
sco_archives_etud . etudarchive_generate_excel_sample ,
Permission . ScoView ,
)
# Debouche / devenir etudiant
sco_publish (
2021-08-10 17:12:10 +02:00
" /itemsuivi_suppress " ,
sco_debouche . itemsuivi_suppress ,
Permission . ScoEtudChangeAdr ,
methods = [ " GET " , " POST " ] ,
2021-06-02 22:40:34 +02:00
)
sco_publish (
2021-08-10 17:12:10 +02:00
" /itemsuivi_create " ,
sco_debouche . itemsuivi_create ,
Permission . ScoEtudChangeAdr ,
methods = [ " GET " , " POST " ] ,
2021-06-02 22:40:34 +02:00
)
sco_publish (
2021-08-10 17:12:10 +02:00
" /itemsuivi_set_date " ,
sco_debouche . itemsuivi_set_date ,
Permission . ScoEtudChangeAdr ,
methods = [ " GET " , " POST " ] ,
2021-06-02 22:40:34 +02:00
)
sco_publish (
" /itemsuivi_set_situation " ,
sco_debouche . itemsuivi_set_situation ,
Permission . ScoEtudChangeAdr ,
2021-08-10 17:12:10 +02:00
methods = [ " GET " , " POST " ] ,
2021-06-02 22:40:34 +02:00
)
sco_publish (
" /itemsuivi_list_etud " , sco_debouche . itemsuivi_list_etud , Permission . ScoView
)
sco_publish ( " /itemsuivi_tag_list " , sco_debouche . itemsuivi_tag_list , Permission . ScoView )
sco_publish (
" /itemsuivi_tag_search " , sco_debouche . itemsuivi_tag_search , Permission . ScoView
)
sco_publish (
2021-08-10 17:12:10 +02:00
" /itemsuivi_tag_set " ,
sco_debouche . itemsuivi_tag_set ,
Permission . ScoEtudChangeAdr ,
methods = [ " GET " , " POST " ] ,
2021-06-02 22:40:34 +02:00
)
2021-07-13 14:53:14 +02:00
@bp.route ( " /doAddAnnotation " , methods = [ " GET " , " POST " ] )
2021-08-13 00:34:58 +02:00
@scodoc
2021-06-02 22:40:34 +02:00
@permission_required ( Permission . ScoEtudAddAnnotations )
2021-08-21 00:24:51 +02:00
@scodoc7func
2021-08-10 17:12:10 +02:00
def doAddAnnotation ( etudid , comment ) :
2021-06-02 22:40:34 +02:00
" ajoute annotation sur etudiant "
2022-08-25 18:48:48 +02:00
etud = Identite . query . get_or_404 ( etudid ) # check existence
if comment :
cnx = ndb . GetDBConnexion ( )
sco_etud . etud_annotations_create (
cnx ,
args = {
" etudid " : etudid ,
" comment " : comment ,
" author " : current_user . user_name ,
} ,
)
logdb ( cnx , method = " addAnnotation " , etudid = etudid )
2021-07-31 18:01:10 +02:00
return flask . redirect (
2021-07-11 17:37:12 +02:00
url_for ( " scolar.ficheEtud " , scodoc_dept = g . scodoc_dept , etudid = etudid )
)
2021-06-02 22:40:34 +02:00
2021-07-13 14:53:14 +02:00
@bp.route ( " /doSuppressAnnotation " , methods = [ " GET " , " POST " ] )
2021-08-13 00:34:58 +02:00
@scodoc
2021-06-02 22:40:34 +02:00
@permission_required ( Permission . ScoView )
2021-08-21 00:24:51 +02:00
@scodoc7func
2021-09-27 10:20:10 +02:00
def doSuppressAnnotation ( etudid , annotation_id ) :
2021-06-02 22:40:34 +02:00
""" Suppression annotation. """
2021-07-29 16:31:15 +02:00
if not sco_permissions_check . can_suppress_annotation ( annotation_id ) :
2021-06-02 22:40:34 +02:00
raise AccessDenied ( " Vous n ' avez pas le droit d ' effectuer cette opération ! " )
2021-06-15 13:59:56 +02:00
cnx = ndb . GetDBConnexion ( )
2021-06-19 23:21:37 +02:00
annos = sco_etud . etud_annotations_list ( cnx , args = { " id " : annotation_id } )
2021-06-02 22:40:34 +02:00
if len ( annos ) != 1 :
raise ScoValueError ( " annotation inexistante ! " )
anno = annos [ 0 ]
log ( " suppress annotation: %s " % str ( anno ) )
2021-07-31 18:01:10 +02:00
logdb ( cnx , method = " SuppressAnnotation " , etudid = etudid )
2021-06-19 23:21:37 +02:00
sco_etud . etud_annotations_delete ( cnx , annotation_id )
2021-06-02 22:40:34 +02:00
2021-07-31 18:01:10 +02:00
return flask . redirect (
2021-07-11 17:37:12 +02:00
url_for (
" scolar.ficheEtud " ,
scodoc_dept = g . scodoc_dept ,
etudid = etudid ,
head_message = " Annotation %% 20supprimée " ,
)
2021-06-02 22:40:34 +02:00
)
2022-09-27 12:21:19 +02:00
@bp.route ( " /form_change_coordonnees " , methods = [ " GET " , " POST " ] )
2021-08-13 00:34:58 +02:00
@scodoc
2021-06-02 22:40:34 +02:00
@permission_required ( Permission . ScoEtudChangeAdr )
2021-08-21 00:24:51 +02:00
@scodoc7func
2022-09-27 12:21:19 +02:00
def form_change_coordonnees ( etudid ) :
2021-06-02 22:40:34 +02:00
" edit coordonnees etudiant "
2022-09-27 12:21:19 +02:00
etud = Identite . query . get_or_404 ( etudid )
2021-06-15 13:59:56 +02:00
cnx = ndb . GetDBConnexion ( )
2021-06-19 23:21:37 +02:00
adrs = sco_etud . adresse_list ( cnx , { " etudid " : etudid } )
2021-06-02 22:40:34 +02:00
if adrs :
adr = adrs [ 0 ]
else :
adr = { } # no data for this student
H = [
2022-09-27 12:21:19 +02:00
f """ { html_sco_header . sco_header (
page_title = f " Changement coordonnées de { etud . nomprenom } "
) }
< h2 > Changement des coordonnées de { etud . nomprenom } < / h2 >
< p > """
2021-06-02 22:40:34 +02:00
]
tf = TrivialFormulator (
2021-09-18 10:10:02 +02:00
request . base_url ,
2021-09-27 16:42:14 +02:00
scu . get_request_args ( ) ,
2021-06-02 22:40:34 +02:00
(
( " adresse_id " , { " input_type " : " hidden " } ) ,
( " etudid " , { " input_type " : " hidden " } ) ,
(
" email " ,
{
" size " : 40 ,
" title " : " e-mail " ,
" explanation " : " adresse institutionnelle " ,
} ,
) ,
(
" emailperso " ,
{
" size " : 40 ,
" title " : " e-mail " ,
" explanation " : " adresse personnelle " ,
} ,
) ,
(
" domicile " ,
{ " size " : 65 , " explanation " : " numéro, rue " , " title " : " Adresse " } ,
) ,
( " codepostaldomicile " , { " size " : 6 , " title " : " Code postal " } ) ,
( " villedomicile " , { " size " : 20 , " title " : " Ville " } ) ,
( " paysdomicile " , { " size " : 20 , " title " : " Pays " } ) ,
( " " , { " input_type " : " separator " , " default " : " " } ) ,
( " telephone " , { " size " : 13 , " title " : " Téléphone " } ) ,
( " telephonemobile " , { " size " : 13 , " title " : " Mobile " } ) ,
) ,
initvalues = adr ,
submitlabel = " Valider le formulaire " ,
)
2021-07-11 17:37:12 +02:00
dest_url = url_for ( " scolar.ficheEtud " , scodoc_dept = g . scodoc_dept , etudid = etudid )
2021-06-02 22:40:34 +02:00
if tf [ 0 ] == 0 :
2022-09-27 12:21:19 +02:00
return " \n " . join ( H ) + tf [ 1 ] + html_sco_header . sco_footer ( )
2021-06-02 22:40:34 +02:00
elif tf [ 0 ] == - 1 :
2021-07-31 18:01:10 +02:00
return flask . redirect ( dest_url )
2021-06-02 22:40:34 +02:00
else :
if adrs :
2021-08-21 00:24:51 +02:00
sco_etud . adresse_edit ( cnx , args = tf [ 2 ] )
2021-06-02 22:40:34 +02:00
else :
2021-06-19 23:21:37 +02:00
sco_etud . adresse_create ( cnx , args = tf [ 2 ] )
2021-07-31 18:01:10 +02:00
logdb ( cnx , method = " changeCoordonnees " , etudid = etudid )
return flask . redirect ( dest_url )
2021-06-02 22:40:34 +02:00
# --- Gestion des groupes:
2021-07-13 14:53:14 +02:00
sco_publish (
2021-10-04 22:05:05 +02:00
" /affect_groups " ,
sco_groups_edit . affect_groups ,
2021-07-13 14:53:14 +02:00
Permission . ScoView ,
methods = [ " GET " , " POST " ] ,
)
2021-06-02 22:40:34 +02:00
sco_publish (
" /XMLgetGroupsInPartition " , sco_groups . XMLgetGroupsInPartition , Permission . ScoView
)
sco_publish (
" /formsemestre_partition_list " ,
sco_groups . formsemestre_partition_list ,
Permission . ScoView ,
)
2022-09-02 15:07:59 +02:00
sco_publish ( " /setGroups " , sco_groups . setGroups , Permission . ScoView , methods = [ " POST " ] )
2021-06-02 22:40:34 +02:00
2021-07-13 14:53:14 +02:00
sco_publish (
" /group_rename " ,
sco_groups . group_rename ,
Permission . ScoView ,
methods = [ " GET " , " POST " ] ,
)
2021-06-02 22:40:34 +02:00
sco_publish (
2021-07-13 14:53:14 +02:00
" /groups_auto_repartition " ,
sco_groups . groups_auto_repartition ,
Permission . ScoView ,
methods = [ " GET " , " POST " ] ,
2021-06-02 22:40:34 +02:00
)
2021-07-13 14:53:14 +02:00
sco_publish (
2022-05-22 05:01:25 +02:00
" /edit_partition_form " ,
sco_groups . edit_partition_form ,
2021-07-13 14:53:14 +02:00
Permission . ScoView ,
methods = [ " GET " , " POST " ] ,
)
2021-06-02 22:40:34 +02:00
2021-07-13 14:53:14 +02:00
sco_publish (
" /partition_delete " ,
sco_groups . partition_delete ,
Permission . ScoView ,
methods = [ " GET " , " POST " ] ,
)
2021-06-02 22:40:34 +02:00
2021-07-13 14:53:14 +02:00
sco_publish (
" /partition_set_attr " ,
sco_groups . partition_set_attr ,
Permission . ScoView ,
methods = [ " GET " , " POST " ] ,
)
2021-06-02 22:40:34 +02:00
2021-07-13 14:53:14 +02:00
sco_publish (
" /partition_move " ,
sco_groups . partition_move ,
Permission . ScoView ,
methods = [ " GET " , " POST " ] ,
)
2021-06-02 22:40:34 +02:00
2021-07-13 14:53:14 +02:00
sco_publish (
" /partition_set_name " ,
sco_groups . partition_set_name ,
Permission . ScoView ,
methods = [ " GET " , " POST " ] ,
)
2021-06-02 22:40:34 +02:00
2021-07-13 14:53:14 +02:00
sco_publish (
" /partition_rename " ,
sco_groups . partition_rename ,
Permission . ScoView ,
methods = [ " GET " , " POST " ] ,
)
2021-06-02 22:40:34 +02:00
2021-07-13 14:53:14 +02:00
sco_publish (
" /partition_create " ,
sco_groups . partition_create ,
2022-05-22 05:01:25 +02:00
Permission . ScoView , # controle d'access ad-hoc
2021-07-13 14:53:14 +02:00
methods = [ " GET " , " POST " ] ,
)
2022-05-22 05:01:25 +02:00
2022-07-22 17:37:01 +02:00
# Nouvel éditeur de partitions et groupe, @SebL Jul 2022
@bp.route ( " /partition_editor " , methods = [ " GET " , " POST " ] )
@scodoc
@permission_required ( Permission . ScoView )
@scodoc7func
def partition_editor ( formsemestre_id : int ) :
formsemestre : FormSemestre = FormSemestre . query . get_or_404 ( formsemestre_id )
2022-12-17 13:43:47 +01:00
formsemestre . setup_parcours_groups ( )
2022-07-22 17:37:01 +02:00
H = [
html_sco_header . sco_header (
cssstyles = [ " css/partition_editor.css " ] ,
javascripts = [
" js/partition_editor.js " ,
] ,
page_title = f " Partitions de { formsemestre . titre_annee ( ) } " ,
2023-02-22 14:27:11 +01:00
init_datatables = True ,
2022-07-22 17:37:01 +02:00
) ,
f """ <h2>
< / h2 >
""" ,
render_template (
2023-01-30 22:25:17 +01:00
" scolar/partition_editor.j2 " ,
2022-07-22 17:37:01 +02:00
formsemestre = formsemestre ,
read_only = not sco_groups . sco_permissions_check . can_change_groups (
formsemestre_id
) ,
) ,
html_sco_header . sco_footer ( ) ,
]
return " \n " . join ( H )
2022-05-22 05:01:25 +02:00
2023-03-02 23:29:25 +01:00
# Future page pour répartition parcours
@bp.route ( " /students_groups_auto_assignment " , methods = [ " GET " , " POST " ] )
@scodoc
@permission_required ( Permission . ScoView )
@scodoc7func
def students_groups_auto_assignment ( formsemestre_id : int ) :
""" En cours de dev. """
formsemestre : FormSemestre = FormSemestre . query . get_or_404 ( formsemestre_id )
H = [
html_sco_header . sco_header (
page_title = f " DEV " ,
) ,
f """ <h2>
< / h2 >
""" ,
render_template (
" scolar/students_groups_auto_assignment.j2 " ,
formsemestre = formsemestre ,
) ,
html_sco_header . sco_footer ( ) ,
]
return " \n " . join ( H )
2022-05-22 05:01:25 +02:00
@bp.route ( " /create_partition_parcours " , methods = [ " GET " , " POST " ] )
@scodoc
@permission_required ( Permission . ScoView )
@scodoc7func
def create_partition_parcours ( formsemestre_id ) :
2022-05-26 03:55:03 +02:00
""" Création d ' une partitions nommée " Parcours " (PARTITION_PARCOURS)
avec un groupe par parcours . """
2023-01-24 00:35:15 +01:00
formsemestre : FormSemestre = FormSemestre . query . get_or_404 ( formsemestre_id )
2022-05-28 11:38:22 +02:00
formsemestre . setup_parcours_groups ( )
2022-05-22 05:01:25 +02:00
return flask . redirect (
url_for (
" scolar.edit_partition_form " ,
scodoc_dept = g . scodoc_dept ,
formsemestre_id = formsemestre_id ,
)
)
2021-08-11 00:36:07 +02:00
2021-06-02 22:40:34 +02:00
sco_publish ( " /etud_info_html " , sco_page_etud . etud_info_html , Permission . ScoView )
# --- Gestion des photos:
sco_publish ( " /get_photo_image " , sco_photos . get_photo_image , Permission . ScoView )
sco_publish ( " /etud_photo_html " , sco_photos . etud_photo_html , Permission . ScoView )
@bp.route ( " /etud_photo_orig_page " )
2021-08-13 00:34:58 +02:00
@scodoc
2021-06-02 22:40:34 +02:00
@permission_required ( Permission . ScoView )
2021-08-21 00:24:51 +02:00
@scodoc7func
2021-09-27 10:20:10 +02:00
def etud_photo_orig_page ( etudid = None ) :
2021-06-02 22:40:34 +02:00
" Page with photo in orig. size "
2021-08-22 13:24:36 +02:00
etud = sco_etud . get_etud_info ( filled = True , etudid = etudid ) [ 0 ]
2021-06-02 22:40:34 +02:00
H = [
2021-07-29 16:31:15 +02:00
html_sco_header . sco_header ( page_title = etud [ " nomprenom " ] ) ,
2021-06-02 22:40:34 +02:00
" <h2> %s </h2> " % etud [ " nomprenom " ] ,
2021-07-11 17:37:12 +02:00
' <div><a href= " %s " > '
% url_for ( " scolar.ficheEtud " , scodoc_dept = g . scodoc_dept , etudid = etudid ) ,
2021-08-21 00:24:51 +02:00
sco_photos . etud_photo_orig_html ( etud ) ,
2021-06-02 22:40:34 +02:00
" </a></div> " ,
2021-07-29 10:19:00 +02:00
html_sco_header . sco_footer ( ) ,
2021-06-02 22:40:34 +02:00
]
return " \n " . join ( H )
2022-09-30 22:43:39 +02:00
@bp.route ( " /form_change_photo " , methods = [ " GET " , " POST " ] )
2021-08-13 00:34:58 +02:00
@scodoc
2021-06-02 22:40:34 +02:00
@permission_required ( Permission . ScoEtudChangeAdr )
2021-08-21 00:24:51 +02:00
@scodoc7func
2022-09-30 22:43:39 +02:00
def form_change_photo ( etudid = None ) :
2021-06-02 22:40:34 +02:00
""" Formulaire changement photo étudiant """
2021-08-22 13:24:36 +02:00
etud = sco_etud . get_etud_info ( filled = True ) [ 0 ]
2021-08-21 00:24:51 +02:00
if sco_photos . etud_photo_is_local ( etud ) :
2021-06-02 22:40:34 +02:00
etud [ " photoloc " ] = " dans ScoDoc "
else :
etud [ " photoloc " ] = " externe "
H = [
2021-07-29 16:31:15 +02:00
html_sco_header . sco_header ( page_title = " Changement de photo " ) ,
2021-06-02 22:40:34 +02:00
""" <h2>Changement de la photo de %(nomprenom)s </h2>
< p > Photo actuelle ( % ( photoloc ) s ) :
"""
% etud ,
2021-09-24 12:10:53 +02:00
sco_photos . etud_photo_html ( etud , title = " photo actuelle " ) ,
2021-06-02 22:40:34 +02:00
""" </p><p>Le fichier ne doit pas dépasser 500Ko (recadrer l ' image, format " portrait " de préférence).</p>
< p > L ' image sera automagiquement réduite pour obtenir une hauteur de 90 pixels.</p>
""" ,
]
tf = TrivialFormulator (
2021-09-18 10:10:02 +02:00
request . base_url ,
2021-09-27 16:42:14 +02:00
scu . get_request_args ( ) ,
2021-06-02 22:40:34 +02:00
(
( " etudid " , { " default " : etudid , " input_type " : " hidden " } ) ,
(
" photofile " ,
{ " input_type " : " file " , " title " : " Fichier image " , " size " : 20 } ,
) ,
) ,
submitlabel = " Valider " ,
cancelbutton = " Annuler " ,
)
2021-07-11 17:37:12 +02:00
dest_url = url_for (
" scolar.ficheEtud " , scodoc_dept = g . scodoc_dept , etudid = etud [ " etudid " ]
)
2021-06-02 22:40:34 +02:00
if tf [ 0 ] == 0 :
return (
" \n " . join ( H )
+ tf [ 1 ]
2022-09-30 22:43:39 +02:00
+ ' <p><a class= " stdlink " href= " form_suppress_photo?etudid= %s " >Supprimer cette photo</a></p> '
2021-06-02 22:40:34 +02:00
% etudid
2021-07-29 10:19:00 +02:00
+ html_sco_header . sco_footer ( )
2021-06-02 22:40:34 +02:00
)
elif tf [ 0 ] == - 1 :
2021-07-31 18:01:10 +02:00
return flask . redirect ( dest_url )
2021-06-02 22:40:34 +02:00
else :
2021-07-26 15:23:07 +02:00
data = tf [ 2 ] [ " photofile " ] . read ( )
2022-09-02 20:56:55 +02:00
status , err_msg = sco_photos . store_photo (
etud , data , tf [ 2 ] [ " photofile " ] . filename
)
if status :
2021-07-31 18:01:10 +02:00
return flask . redirect ( dest_url )
2021-06-02 22:40:34 +02:00
else :
2022-09-02 20:56:55 +02:00
H . append ( f """ <p class= " warning " >Erreur: { err_msg } </p> """ )
2021-07-29 10:19:00 +02:00
return " \n " . join ( H ) + html_sco_header . sco_footer ( )
2021-06-02 22:40:34 +02:00
2022-09-30 22:43:39 +02:00
@bp.route ( " /form_suppress_photo " , methods = [ " POST " , " GET " ] )
2021-08-13 00:34:58 +02:00
@scodoc
2021-06-02 22:40:34 +02:00
@permission_required ( Permission . ScoEtudChangeAdr )
2021-08-21 00:24:51 +02:00
@scodoc7func
2022-09-30 22:43:39 +02:00
def form_suppress_photo ( etudid = None , dialog_confirmed = False ) :
2021-06-02 22:40:34 +02:00
""" Formulaire suppression photo étudiant """
2022-09-30 22:43:39 +02:00
etud : Identite = Identite . query . filter_by (
id = etudid , dept_id = g . scodoc_dept_id
) . first_or_404 ( )
2021-06-02 22:40:34 +02:00
if not dialog_confirmed :
return scu . confirm_dialog (
2021-12-20 22:53:09 +01:00
f " <p>Confirmer la suppression de la photo de { etud . nom_disp ( ) } ?</p> " ,
2021-06-02 22:40:34 +02:00
dest_url = " " ,
2021-07-11 17:37:12 +02:00
cancel_url = url_for (
2021-12-20 22:53:09 +01:00
" scolar.ficheEtud " , scodoc_dept = g . scodoc_dept , etudid = etud . id
2021-07-11 17:37:12 +02:00
) ,
2021-12-20 22:53:09 +01:00
parameters = { " etudid " : etud . id } ,
2021-06-02 22:40:34 +02:00
)
2021-09-27 10:20:10 +02:00
sco_photos . suppress_photo ( etud )
2021-06-02 22:40:34 +02:00
2021-07-31 18:01:10 +02:00
return flask . redirect (
2021-12-20 22:53:09 +01:00
url_for ( " scolar.ficheEtud " , scodoc_dept = g . scodoc_dept , etudid = etud . id )
2021-06-02 22:40:34 +02:00
)
#
2022-09-30 22:43:39 +02:00
@bp.route ( " /form_dem " )
2021-08-13 00:34:58 +02:00
@scodoc
2021-06-02 22:40:34 +02:00
@permission_required ( Permission . ScoEtudInscrit )
2021-08-21 00:24:51 +02:00
@scodoc7func
2022-09-30 22:43:39 +02:00
def form_dem ( etudid , formsemestre_id ) :
2021-06-02 22:40:34 +02:00
" Formulaire Démission Etudiant "
2022-09-30 22:43:39 +02:00
return _form_dem_of_def (
2021-06-02 22:40:34 +02:00
etudid ,
formsemestre_id ,
operation_name = " Démission " ,
2022-09-30 22:43:39 +02:00
operation_method = " do_dem_etudiant " ,
2021-06-02 22:40:34 +02:00
)
2022-09-30 22:43:39 +02:00
@bp.route ( " /form_def " )
2021-08-13 00:34:58 +02:00
@scodoc
2021-06-02 22:40:34 +02:00
@permission_required ( Permission . ScoEtudInscrit )
2021-08-21 00:24:51 +02:00
@scodoc7func
2022-09-30 22:43:39 +02:00
def form_def ( etudid , formsemestre_id ) :
2021-06-02 22:40:34 +02:00
" Formulaire Défaillance Etudiant "
2022-09-30 22:43:39 +02:00
return _form_dem_of_def (
2021-06-02 22:40:34 +02:00
etudid ,
formsemestre_id ,
operation_name = " Défaillance " ,
2022-09-30 22:43:39 +02:00
operation_method = " do_def_etudiant " ,
2021-06-02 22:40:34 +02:00
)
2022-09-30 22:43:39 +02:00
def _form_dem_of_def (
etudid : int ,
formsemestre_id : int ,
operation_name : str = " " ,
operation_method : str = " " ,
2021-06-02 22:40:34 +02:00
) :
" Formulaire démission ou défaillance Etudiant "
2022-09-30 22:43:39 +02:00
etud : Identite = Identite . query . filter_by (
id = etudid , dept_id = g . scodoc_dept_id
) . first_or_404 ( )
formsemestre : FormSemestre = FormSemestre . query . filter_by (
id = formsemestre_id , dept_id = g . scodoc_dept_id
) . first_or_404 ( )
if not formsemestre . etat :
2021-06-02 22:40:34 +02:00
raise ScoValueError ( " Modification impossible: semestre verrouille " )
2022-09-30 22:43:39 +02:00
nowdmy = time . strftime ( " %d / % m/ % Y " )
2021-06-02 22:40:34 +02:00
#
2021-06-13 18:29:53 +02:00
header = html_sco_header . sco_header (
2022-09-30 22:43:39 +02:00
page_title = f """ { operation_name } de { etud . nomprenom } (du semestre { formsemestre . titre_mois ( ) } ) """
2021-06-02 22:40:34 +02:00
)
2022-10-01 10:39:46 +02:00
validations_descr = formsemestre . etud_validations_description_html ( etudid )
2022-09-30 22:43:39 +02:00
return f """
{ header }
< h2 > < font color = " #FF0000 " > { operation_name } de < / font > { etud . nomprenom } ( { formsemestre . titre_mois ( ) } ) < / h2 >
< form action = " {operation_method} " method = " get " >
< div > < b > Date de la { operation_name . lower ( ) } ( J / M / AAAA ) : & nbsp ; < / b >
< input type = " text " name = " event_date " width = 20 value = " {nowdmy} " >
< / div >
< input type = " hidden " name = " etudid " value = " {etudid} " >
< input type = " hidden " name = " formsemestre_id " value = " {formsemestre_id} " >
< div class = " vertical_spacing_but " > < input type = " submit " value = " Confirmer " > < / div >
< / form >
2022-10-01 10:39:46 +02:00
< div class = " rappel_decisions " >
{ ' <p class= " warning " >Attention: il y a des décisions de jury déjà prises !</p> ' if validations_descr else " " }
{ validations_descr }
{ ( ' <p><a class= " stdlink " href= " '
+ url_for ( " notes.formsemestre_validation_but " , scodoc_dept = g . scodoc_dept ,
2022-10-05 10:31:25 +02:00
formsemestre_id = formsemestre_id , etudid = etudid )
2022-10-01 10:39:46 +02:00
+ ' " >modifier ces décisions</a></p> ' ) if validations_descr else " " }
< / div >
2022-09-30 22:43:39 +02:00
{ html_sco_header . sco_footer ( ) }
2021-06-02 22:40:34 +02:00
"""
2022-09-30 22:43:39 +02:00
@bp.route ( " /do_dem_etudiant " )
2021-08-13 00:34:58 +02:00
@scodoc
2021-06-02 22:40:34 +02:00
@permission_required ( Permission . ScoEtudInscrit )
2021-08-21 00:24:51 +02:00
@scodoc7func
2022-09-30 22:43:39 +02:00
def do_dem_etudiant ( etudid , formsemestre_id , event_date = None ) :
2021-06-02 22:40:34 +02:00
" Déclare la démission d ' un etudiant dans le semestre "
2021-06-21 12:13:25 +02:00
return _do_dem_or_def_etud (
2021-06-02 22:40:34 +02:00
etudid ,
formsemestre_id ,
event_date = event_date ,
2022-09-30 22:43:39 +02:00
etat_new = scu . DEMISSION ,
operation_method = " dem_etudiant " ,
2021-06-02 22:40:34 +02:00
event_type = " DEMISSION " ,
)
2022-09-30 22:43:39 +02:00
@bp.route ( " /do_def_etudiant " )
2021-08-13 00:34:58 +02:00
@scodoc
2021-06-02 22:40:34 +02:00
@permission_required ( Permission . ScoEtudInscrit )
2021-08-21 00:24:51 +02:00
@scodoc7func
2022-09-30 22:43:39 +02:00
def do_def_etudiant ( etudid , formsemestre_id , event_date = None ) :
2021-06-02 22:40:34 +02:00
" Déclare la défaillance d ' un etudiant dans le semestre "
2021-06-21 12:13:25 +02:00
return _do_dem_or_def_etud (
2021-06-02 22:40:34 +02:00
etudid ,
formsemestre_id ,
event_date = event_date ,
2023-02-12 13:36:47 +01:00
etat_new = codes_cursus . DEF ,
2021-06-02 22:40:34 +02:00
operation_method = " defailleEtudiant " ,
event_type = " DEFAILLANCE " ,
)
2021-06-21 12:13:25 +02:00
def _do_dem_or_def_etud (
2021-06-02 22:40:34 +02:00
etudid ,
formsemestre_id ,
event_date = None ,
2022-09-30 22:43:39 +02:00
etat_new = scu . DEMISSION , # DEMISSION or DEF
2021-06-02 22:40:34 +02:00
operation_method = " demEtudiant " ,
event_type = " DEMISSION " ,
2021-09-27 10:20:10 +02:00
redirect = True ,
2021-06-02 22:40:34 +02:00
) :
" Démission ou défaillance d ' un étudiant "
2021-11-03 16:15:39 +01:00
sco_formsemestre_inscriptions . do_formsemestre_demission (
etudid ,
formsemestre_id ,
event_date = event_date ,
2022-09-30 22:43:39 +02:00
etat_new = etat_new , # DEMISSION or DEF
2021-11-03 16:15:39 +01:00
operation_method = operation_method ,
event_type = event_type ,
2021-06-02 22:40:34 +02:00
)
2021-09-27 10:20:10 +02:00
if redirect :
2021-07-31 18:01:10 +02:00
return flask . redirect (
2021-07-11 17:37:12 +02:00
url_for ( " scolar.ficheEtud " , scodoc_dept = g . scodoc_dept , etudid = etudid )
)
2021-06-02 22:40:34 +02:00
2022-09-30 22:43:39 +02:00
@bp.route ( " /do_cancel_dem " , methods = [ " GET " , " POST " ] )
2021-08-13 00:34:58 +02:00
@scodoc
2021-06-02 22:40:34 +02:00
@permission_required ( Permission . ScoEtudInscrit )
2021-08-21 00:24:51 +02:00
@scodoc7func
2022-09-30 22:43:39 +02:00
def do_cancel_dem ( etudid , formsemestre_id , dialog_confirmed = False , args = None ) :
2021-06-02 22:40:34 +02:00
" Annule une démission "
2021-06-21 12:13:25 +02:00
return _do_cancel_dem_or_def (
2021-06-02 22:40:34 +02:00
etudid ,
formsemestre_id ,
dialog_confirmed = dialog_confirmed ,
args = args ,
operation_name = " démission " ,
2022-09-30 22:43:39 +02:00
etat_current = scu . DEMISSION ,
etat_new = scu . INSCRIT ,
2021-06-02 22:40:34 +02:00
operation_method = " cancelDem " ,
event_type = " DEMISSION " ,
)
2022-09-30 22:43:39 +02:00
@bp.route ( " /do_cancel_def " , methods = [ " GET " , " POST " ] )
2021-08-13 00:34:58 +02:00
@scodoc
2021-06-02 22:40:34 +02:00
@permission_required ( Permission . ScoEtudInscrit )
2021-08-21 00:24:51 +02:00
@scodoc7func
2022-09-30 22:43:39 +02:00
def do_cancel_def ( etudid , formsemestre_id , dialog_confirmed = False , args = None ) :
2021-06-02 22:40:34 +02:00
" Annule la défaillance de l ' étudiant "
2021-06-21 12:13:25 +02:00
return _do_cancel_dem_or_def (
2021-06-02 22:40:34 +02:00
etudid ,
formsemestre_id ,
dialog_confirmed = dialog_confirmed ,
args = args ,
operation_name = " défaillance " ,
2023-02-12 13:36:47 +01:00
etat_current = codes_cursus . DEF ,
2022-09-30 22:43:39 +02:00
etat_new = scu . INSCRIT ,
operation_method = " cancel_def " ,
2021-06-02 22:40:34 +02:00
event_type = " DEFAILLANCE " ,
)
2021-06-21 12:13:25 +02:00
def _do_cancel_dem_or_def (
2021-06-02 22:40:34 +02:00
etudid ,
formsemestre_id ,
dialog_confirmed = False ,
args = None ,
operation_name = " " , # "démission" ou "défaillance"
2022-09-30 22:43:39 +02:00
etat_current = scu . DEMISSION ,
etat_new = scu . INSCRIT ,
operation_method = " cancel_dem " ,
2021-06-02 22:40:34 +02:00
event_type = " DEMISSION " ,
) :
2022-09-30 22:43:39 +02:00
" Annule une démission ou une défaillance "
etud : Identite = Identite . query . filter_by (
id = etudid , dept_id = g . scodoc_dept_id
) . first_or_404 ( )
formsemestre : FormSemestre = FormSemestre . query . filter_by (
id = formsemestre_id , dept_id = g . scodoc_dept_id
) . first_or_404 ( )
2021-06-02 22:40:34 +02:00
# check lock
2022-09-30 22:43:39 +02:00
if not formsemestre . etat :
2021-06-02 22:40:34 +02:00
raise ScoValueError ( " Modification impossible: semestre verrouille " )
# verif
2022-09-30 22:43:39 +02:00
if formsemestre_id not in ( inscr . formsemestre_id for inscr in etud . inscriptions ( ) ) :
raise ScoValueError ( " étudiant non inscrit dans ce semestre ! " )
if etud . inscription_etat ( formsemestre_id ) != etat_current :
raise ScoValueError ( f " etudiant non { operation_name } ! " )
2021-06-02 22:40:34 +02:00
if not dialog_confirmed :
return scu . confirm_dialog (
2022-09-30 22:43:39 +02:00
f " <p>Confirmer l ' annulation de la { operation_name } ?</p> " ,
2021-06-02 22:40:34 +02:00
dest_url = " " ,
2021-07-11 17:37:12 +02:00
cancel_url = url_for (
" scolar.ficheEtud " , scodoc_dept = g . scodoc_dept , etudid = etudid
) ,
2021-06-02 22:40:34 +02:00
parameters = { " etudid " : etudid , " formsemestre_id " : formsemestre_id } ,
)
#
2022-09-30 22:43:39 +02:00
inscr = next (
inscr
for inscr in etud . inscriptions ( )
if inscr . formsemestre_id == formsemestre_id
2021-06-02 22:40:34 +02:00
)
2022-09-30 22:43:39 +02:00
inscr . etat = etat_new
db . session . add ( inscr )
Scolog . logdb ( method = operation_method , etudid = etudid )
# Efface les évènements
for event in ScolarEvent . query . filter_by (
etudid = etudid , formsemestre_id = formsemestre_id , event_type = event_type
) :
db . session . delete ( event )
db . session . commit ( )
flash ( f " { operation_name } annulée. " )
2021-07-31 18:01:10 +02:00
return flask . redirect (
2021-07-11 17:37:12 +02:00
url_for ( " scolar.ficheEtud " , scodoc_dept = g . scodoc_dept , etudid = etudid )
)
2021-06-02 22:40:34 +02:00
2021-06-25 18:25:46 +02:00
@bp.route ( " /etudident_create_form " , methods = [ " GET " , " POST " ] )
2021-08-13 00:34:58 +02:00
@scodoc
2021-06-02 22:40:34 +02:00
@permission_required ( Permission . ScoEtudInscrit )
2021-08-21 00:24:51 +02:00
@scodoc7func
2021-09-27 10:20:10 +02:00
def etudident_create_form ( ) :
2021-06-02 22:40:34 +02:00
" formulaire creation individuelle etudiant "
2021-09-27 10:20:10 +02:00
return _etudident_create_or_edit_form ( edit = False )
2021-06-02 22:40:34 +02:00
2021-06-25 18:25:46 +02:00
@bp.route ( " /etudident_edit_form " , methods = [ " GET " , " POST " ] )
2021-08-13 00:34:58 +02:00
@scodoc
2021-06-02 22:40:34 +02:00
@permission_required ( Permission . ScoEtudInscrit )
2021-08-21 00:24:51 +02:00
@scodoc7func
2021-09-27 10:20:10 +02:00
def etudident_edit_form ( ) :
2021-06-02 22:40:34 +02:00
" formulaire edition individuelle etudiant "
2021-09-27 10:20:10 +02:00
return _etudident_create_or_edit_form ( edit = True )
2021-06-02 22:40:34 +02:00
2021-09-27 10:20:10 +02:00
def _etudident_create_or_edit_form ( edit ) :
2021-06-02 22:40:34 +02:00
" Le formulaire HTML "
2021-12-04 21:06:32 +01:00
H = [ html_sco_header . sco_header ( ) ]
2021-07-29 10:19:00 +02:00
F = html_sco_header . sco_footer ( )
2021-09-28 09:14:04 +02:00
vals = scu . get_request_args ( )
2021-09-27 10:20:10 +02:00
etudid = vals . get ( " etudid " , None )
2021-06-15 13:59:56 +02:00
cnx = ndb . GetDBConnexion ( )
2021-06-02 22:40:34 +02:00
descr = [ ]
if not edit :
# creation nouvel etudiant
initvalues = { }
submitlabel = " Ajouter cet étudiant "
H . append (
""" <h2>Création d ' un étudiant</h2>
2022-09-05 14:58:57 +02:00
< p class = " warning " > En général , il est < b > recommandé < / b > d ' importer les
étudiants depuis Apogée ou via un fichier Excel ( menu < b > Inscriptions < / b >
2022-09-03 09:29:40 +02:00
dans le semestre ) .
< / p >
< p >
N ' utilisez ce formulaire au cas par cas que <b>pour les cas particuliers</b>
ou si votre établissement n ' utilise pas d ' autre logiciel de gestion des
inscriptions .
< / p >
< p class " warning " > < em > L ' étudiant créé ne sera pas inscrit.
2021-06-02 22:40:34 +02:00
Pensez à l ' inscrire dans un semestre !</em></p>
"""
)
else :
# edition donnees d'un etudiant existant
# setup form init values
if not etudid :
raise ValueError ( " missing etudid parameter " )
descr . append ( ( " etudid " , { " default " : etudid , " input_type " : " hidden " } ) )
H . append (
2021-07-11 17:37:12 +02:00
' <h2>Modification d \' un étudiant (<a href= " %s " >fiche</a>)</h2> '
% url_for ( " scolar.ficheEtud " , scodoc_dept = g . scodoc_dept , etudid = etudid )
2021-06-02 22:40:34 +02:00
)
2021-06-19 23:21:37 +02:00
initvalues = sco_etud . etudident_list ( cnx , { " etudid " : etudid } )
2021-06-02 22:40:34 +02:00
assert len ( initvalues ) == 1
initvalues = initvalues [ 0 ]
submitlabel = " Modifier les données "
2021-09-28 09:14:04 +02:00
vals = scu . get_request_args ( )
2021-09-27 10:20:10 +02:00
nom = vals . get ( " nom " , None )
2021-06-02 22:40:34 +02:00
if nom is None :
nom = initvalues . get ( " nom " , None )
if nom is None :
infos = [ ]
else :
2021-09-27 10:20:10 +02:00
prenom = vals . get ( " prenom " , " " )
if vals . get ( " tf_submitted " , False ) and not prenom :
2021-06-02 22:40:34 +02:00
prenom = initvalues . get ( " prenom " , " " )
2021-08-20 10:51:42 +02:00
infos = sco_portal_apogee . get_infos_apogee ( nom , prenom )
2021-06-02 22:40:34 +02:00
if infos :
formatted_infos = [
"""
< script type = " text/javascript " >
function copy_nip ( nip ) {
document . tf . code_nip . value = nip ;
}
< / script >
< ol > """
]
nanswers = len ( infos )
2022-09-03 09:29:40 +02:00
nmax = 10 # nb max de reponse montrées
2021-06-02 22:40:34 +02:00
infos = infos [ : nmax ]
for i in infos :
formatted_infos . append ( " <li><ul> " )
for k in i . keys ( ) :
if k != " nip " :
item = " <li> %s : %s </li> " % ( k , i [ k ] )
else :
item = (
' <li><form> %s : %s <input type= " button " value= " copier ce code " onmousedown= " copy_nip( %s ); " /></form></li> '
% ( k , i [ k ] , i [ k ] )
)
formatted_infos . append ( item )
formatted_infos . append ( " </ul></li> " )
formatted_infos . append ( " </ol> " )
m = " %d étudiants trouvés " % nanswers
if len ( infos ) != nanswers :
m + = " ( %d montrés) " % len ( infos )
A = """ <div class= " infoapogee " >
< h5 > Informations Apogée < / h5 >
< p > % s < / p >
% s
< / div > """ % (
m ,
" \n " . join ( formatted_infos ) ,
)
else :
A = """ <div class= " infoapogee " ><p>Pas d ' informations d ' Apogée</p></div> """
2021-07-28 17:03:54 +02:00
require_ine = sco_preferences . get_preference ( " always_require_ine " )
2021-06-02 22:40:34 +02:00
descr + = [
( " adm_id " , { " input_type " : " hidden " } ) ,
( " nom " , { " size " : 25 , " title " : " Nom " , " allow_null " : False } ) ,
( " nom_usuel " , { " size " : 25 , " title " : " Nom usuel " , " allow_null " : True } ) ,
(
" prenom " ,
{
" size " : 25 ,
" title " : " Prénom " ,
" allow_null " : scu . CONFIG . ALLOW_NULL_PRENOM ,
} ,
) ,
(
" civilite " ,
{
" input_type " : " menu " ,
" labels " : [ " Homme " , " Femme " , " Autre/neutre " ] ,
" allowed_values " : [ " M " , " F " , " X " ] ,
" title " : " Civilité " ,
} ,
) ,
(
" date_naissance " ,
{
" title " : " Date de naissance " ,
" input_type " : " date " ,
" explanation " : " j/m/a " ,
2022-09-03 09:29:40 +02:00
" validator " : lambda val , _ : DMY_REGEXP . match ( val )
and ( ndb . DateDMYtoISO ( val ) < datetime . date . today ( ) . isoformat ( ) ) ,
2021-06-02 22:40:34 +02:00
} ,
) ,
( " lieu_naissance " , { " title " : " Lieu de naissance " , " size " : 32 } ) ,
( " dept_naissance " , { " title " : " Département de naissance " , " size " : 5 } ) ,
( " nationalite " , { " size " : 25 , " title " : " Nationalité " } ) ,
(
" statut " ,
{
" size " : 25 ,
" title " : " Statut " ,
" explanation " : ' ( " salarie " , ...) inutilisé par ScoDoc ' ,
} ,
) ,
2022-12-07 13:52:16 +01:00
(
" boursier " ,
{
" input_type " : " boolcheckbox " ,
" labels " : [ " non " , " oui " ] ,
" title " : " Boursier ? " ,
" explanation " : " actuellement " ,
} ,
) ,
2021-06-02 22:40:34 +02:00
(
" annee " ,
{
" size " : 5 ,
" title " : " Année admission IUT " ,
" type " : " int " ,
" allow_null " : False ,
" explanation " : " année 1ere inscription (obligatoire) " ,
} ,
) ,
#
( " sep " , { " input_type " : " separator " , " title " : " Scolarité antérieure: " } ) ,
2022-12-07 13:52:16 +01:00
( " bac " , { " size " : 32 , " explanation " : " série du bac (S, STI, STT, ...) " } ) ,
2021-06-02 22:40:34 +02:00
(
" specialite " ,
{
" size " : 25 ,
" title " : " Spécialité " ,
" explanation " : " spécialité bac: SVT M, GENIE ELECTRONIQUE, ... " ,
} ,
) ,
(
" annee_bac " ,
{
" size " : 5 ,
" title " : " Année bac " ,
" type " : " int " ,
2022-08-29 15:23:44 +02:00
" min_value " : 1945 ,
2022-09-03 09:29:40 +02:00
" max_value " : datetime . date . today ( ) . year + 1 ,
2021-06-02 22:40:34 +02:00
" explanation " : " année obtention du bac " ,
} ,
) ,
(
" math " ,
{
" size " : 3 ,
" type " : " float " ,
" title " : " Note de mathématiques " ,
" explanation " : " note sur 20 en terminale " ,
} ,
) ,
(
" physique " ,
{
" size " : 3 ,
" type " : " float " ,
" title " : " Note de physique " ,
" explanation " : " note sur 20 en terminale " ,
} ,
) ,
(
" anglais " ,
{
" size " : 3 ,
" type " : " float " ,
" title " : " Note d ' anglais " ,
" explanation " : " note sur 20 en terminale " ,
} ,
) ,
(
" francais " ,
{
" size " : 3 ,
" type " : " float " ,
" title " : " Note de français " ,
" explanation " : " note sur 20 obtenue au bac " ,
} ,
) ,
(
" type_admission " ,
{
" input_type " : " menu " ,
" title " : " Voie d ' admission " ,
" allowed_values " : scu . TYPES_ADMISSION ,
} ,
) ,
(
" boursier_prec " ,
{
" input_type " : " boolcheckbox " ,
" labels " : [ " non " , " oui " ] ,
" title " : " Boursier ? " ,
" explanation " : " dans le cycle précédent (lycée) " ,
} ,
) ,
(
" rang " ,
{
" size " : 1 ,
" type " : " int " ,
" title " : " Position établissement " ,
" explanation " : " rang de notre établissement dans les voeux du candidat (si connu) " ,
} ,
) ,
(
" qualite " ,
{
" size " : 3 ,
" type " : " float " ,
" title " : " Qualité " ,
" explanation " : " Note de qualité attribuée au dossier (par le jury d ' adm.) " ,
} ,
) ,
(
" decision " ,
{
" input_type " : " menu " ,
" title " : " Décision " ,
" allowed_values " : [
" ADMIS " ,
" ATTENTE 1 " ,
" ATTENTE 2 " ,
" ATTENTE 3 " ,
" REFUS " ,
" ? " ,
] ,
} ,
) ,
(
" score " ,
{
" size " : 3 ,
" type " : " float " ,
" title " : " Score " ,
" explanation " : " score calculé lors de l ' admission " ,
} ,
) ,
(
" classement " ,
{
" size " : 3 ,
" type " : " int " ,
" title " : " Classement " ,
" explanation " : " Classement par le jury d ' admission (de 1 à N) " ,
} ,
) ,
( " apb_groupe " , { " size " : 15 , " title " : " Groupe APB ou PS " } ) ,
(
" apb_classement_gr " ,
{
" size " : 3 ,
" type " : " int " ,
" title " : " Classement " ,
" explanation " : " Classement par le jury dans le groupe ABP ou PS (de 1 à Ng) " ,
} ,
) ,
( " rapporteur " , { " size " : 50 , " title " : " Enseignant rapporteur " } ) ,
(
" commentaire " ,
{
" input_type " : " textarea " ,
" rows " : 4 ,
" cols " : 50 ,
" title " : " Note du rapporteur " ,
} ,
) ,
( " nomlycee " , { " size " : 20 , " title " : " Lycée d ' origine " } ) ,
( " villelycee " , { " size " : 15 , " title " : " Commune du lycée " } ) ,
( " codepostallycee " , { " size " : 15 , " title " : " Code Postal lycée " } ) ,
(
" codelycee " ,
{
" size " : 15 ,
" title " : " Code Lycée " ,
" explanation " : " Code national établissement du lycée ou établissement d ' origine " ,
} ,
) ,
( " sep " , { " input_type " : " separator " , " title " : " Codes Apogée: (optionnels) " } ) ,
(
" code_nip " ,
{
" size " : 25 ,
" title " : " Numéro NIP " ,
" allow_null " : True ,
" explanation " : " numéro identité étudiant (Apogée) " ,
} ,
) ,
(
" code_ine " ,
{
" size " : 25 ,
" title " : " Numéro INE " ,
" allow_null " : not require_ine ,
" explanation " : " numéro INE " ,
} ,
) ,
(
" dont_check_homonyms " ,
{
" title " : " Autoriser les homonymes " ,
" input_type " : " boolcheckbox " ,
" explanation " : " ne vérifie pas les noms et prénoms proches " ,
} ,
) ,
]
initvalues [ " dont_check_homonyms " ] = False
tf = TrivialFormulator (
2021-09-18 10:10:02 +02:00
request . base_url ,
2021-09-27 16:42:14 +02:00
scu . get_request_args ( ) ,
2021-06-02 22:40:34 +02:00
descr ,
submitlabel = submitlabel ,
cancelbutton = " Re-interroger Apogee " ,
initvalues = initvalues ,
)
if tf [ 0 ] == 0 :
return " \n " . join ( H ) + tf [ 1 ] + " <p> " + A + F
elif tf [ 0 ] == - 1 :
return " \n " . join ( H ) + tf [ 1 ] + " <p> " + A + F
# return '\n'.join(H) + '<h4>annulation</h4>' + F
else :
# form submission
if edit :
etudid = tf [ 2 ] [ " etudid " ]
else :
etudid = None
2021-06-19 23:21:37 +02:00
ok , NbHomonyms = sco_etud . check_nom_prenom (
2021-06-02 22:40:34 +02:00
cnx , nom = tf [ 2 ] [ " nom " ] , prenom = tf [ 2 ] [ " prenom " ] , etudid = etudid
)
if not ok :
return (
" \n " . join ( H )
+ tf_error_message ( " Nom ou prénom invalide " )
+ tf [ 1 ]
+ " <p> "
+ A
+ F
)
# log('NbHomonyms=%s' % NbHomonyms)
if not tf [ 2 ] [ " dont_check_homonyms " ] and NbHomonyms > 0 :
return (
" \n " . join ( H )
+ tf_error_message (
""" Attention: il y a déjà un étudiant portant des noms et prénoms proches. Vous pouvez forcer la présence d ' un homonyme en cochant " autoriser les homonymes " en bas du formulaire. """
)
+ tf [ 1 ]
+ " <p> "
+ A
+ F
)
if not edit :
2021-09-27 10:20:10 +02:00
etud = sco_etud . create_etud ( cnx , args = tf [ 2 ] )
2021-06-02 22:40:34 +02:00
etudid = etud [ " etudid " ]
else :
# modif d'un etudiant
2021-09-27 10:20:10 +02:00
sco_etud . etudident_edit ( cnx , tf [ 2 ] )
2021-06-19 23:21:37 +02:00
etud = sco_etud . etudident_list ( cnx , { " etudid " : etudid } ) [ 0 ]
sco_etud . fill_etuds_info ( [ etud ] )
2021-06-02 22:40:34 +02:00
# Inval semesters with this student:
to_inval = [ s [ " formsemestre_id " ] for s in etud [ " sems " ] ]
2021-07-19 19:53:01 +02:00
for formsemestre_id in to_inval :
sco_cache . invalidate_formsemestre (
formsemestre_id = formsemestre_id
2021-06-02 22:40:34 +02:00
) # > etudident_create_or_edit
#
2023-03-12 21:22:19 +01:00
return flask . redirect (
url_for ( " scolar.ficheEtud " , scodoc_dept = g . scodoc_dept , etudid = etudid )
)
2021-06-02 22:40:34 +02:00
2021-07-26 16:52:38 +02:00
@bp.route ( " /etudident_delete " , methods = [ " GET " , " POST " ] )
2021-08-13 00:34:58 +02:00
@scodoc
2021-06-02 22:40:34 +02:00
@permission_required ( Permission . ScoEtudInscrit )
2021-08-21 00:24:51 +02:00
@scodoc7func
2021-09-27 10:20:10 +02:00
def etudident_delete ( etudid , dialog_confirmed = False ) :
2021-06-02 22:40:34 +02:00
" Delete a student "
2021-06-15 13:59:56 +02:00
cnx = ndb . GetDBConnexion ( )
2021-06-19 23:21:37 +02:00
etuds = sco_etud . etudident_list ( cnx , { " etudid " : etudid } )
2021-06-02 22:40:34 +02:00
if not etuds :
2022-09-03 11:41:56 +02:00
raise ScoValueError ( " Étudiant inexistant ! " )
2021-06-02 22:40:34 +02:00
else :
etud = etuds [ 0 ]
2021-06-19 23:21:37 +02:00
sco_etud . fill_etuds_info ( [ etud ] )
2021-06-02 22:40:34 +02:00
if not dialog_confirmed :
return scu . confirm_dialog (
2021-07-11 17:37:12 +02:00
""" <h2>Confirmer la suppression de l ' étudiant <b> {e[nomprenom]} </b> ?</h2>
2021-06-02 22:40:34 +02:00
< / p >
2021-07-11 17:37:12 +02:00
< p style = " top-margin: 2ex; bottom-margin: 2ex; " > Prenez le temps de vérifier
que vous devez vraiment supprimer cet étudiant !
< / p >
< p > Cette opération < font color = " red " > < b > irréversible < / b > < / font >
efface toute trace de l ' étudiant: inscriptions, <b>notes</b>, absences...
dans < b > tous les semestres < / b > qu ' il a fréquenté.
< / p >
< p > Dans la plupart des cas , vous avez seulement besoin de le < ul > désinscrire < / ul >
d ' un semestre ? (dans ce cas passez par sa fiche, menu associé au semestre)</p>
< p > < a href = " {fiche_url} " > Vérifier la fiche de { e [ nomprenom ] } < / a >
< / p > """ .format(
e = etud ,
fiche_url = url_for (
" scolar.ficheEtud " , scodoc_dept = g . scodoc_dept , etudid = etudid
) ,
) ,
2021-06-02 22:40:34 +02:00
dest_url = " " ,
2021-07-11 17:37:12 +02:00
cancel_url = url_for (
" scolar.ficheEtud " , scodoc_dept = g . scodoc_dept , etudid = etudid
) ,
2021-06-02 22:40:34 +02:00
OK = " Supprimer définitivement cet étudiant " ,
parameters = { " etudid " : etudid } ,
)
log ( " etudident_delete: etudid= %(etudid)s nomprenom= %(nomprenom)s " % etud )
# delete in all tables !
tables = [
" notes_appreciations " ,
" scolar_autorisation_inscription " ,
" scolar_formsemestre_validation " ,
" scolar_events " ,
" notes_notes_log " ,
" notes_notes " ,
" notes_moduleimpl_inscription " ,
" notes_formsemestre_inscription " ,
" group_membership " ,
" etud_annotations " ,
" scolog " ,
" admissions " ,
" adresse " ,
" absences " ,
2021-09-29 14:15:12 +02:00
" absences_notifications " ,
2021-06-02 22:40:34 +02:00
" billet_absence " ,
]
cursor = cnx . cursor ( cursor_factory = ndb . ScoDocCursor )
for table in tables :
cursor . execute ( " delete from %s where etudid= %% (etudid)s " % table , etud )
2021-08-15 21:33:47 +02:00
cursor . execute ( " delete from identite where id= %(etudid)s " , etud )
2021-06-02 22:40:34 +02:00
cnx . commit ( )
# Inval semestres où il était inscrit:
to_inval = [ s [ " formsemestre_id " ] for s in etud [ " sems " ] ]
2021-07-19 19:53:01 +02:00
for formsemestre_id in to_inval :
sco_cache . invalidate_formsemestre ( formsemestre_id = formsemestre_id ) # >
2021-07-31 18:01:10 +02:00
return flask . redirect ( scu . ScoURL ( ) + r " ?head_message=Etudiant %20s upprimé " )
2021-06-02 22:40:34 +02:00
@bp.route ( " /check_group_apogee " )
2021-08-13 00:34:58 +02:00
@scodoc
2021-06-02 22:40:34 +02:00
@permission_required ( Permission . ScoEtudInscrit )
2021-08-21 00:24:51 +02:00
@scodoc7func
2021-09-27 10:20:10 +02:00
def check_group_apogee ( group_id , etat = None , fix = False , fixmail = False ) :
2021-06-02 22:40:34 +02:00
""" Verification des codes Apogee et mail de tout un groupe.
Si fix == True , change les codes avec Apogée .
XXX A re - écrire pour API 2 : prendre liste dans l ' étape et vérifier à partir de cela.
"""
etat = etat or None
2021-08-19 10:28:35 +02:00
members , group , _ , sem , _ = sco_groups . get_group_infos ( group_id , etat = etat )
2021-06-02 22:40:34 +02:00
formsemestre_id = group [ " formsemestre_id " ]
2021-06-15 13:59:56 +02:00
cnx = ndb . GetDBConnexion ( )
2021-06-02 22:40:34 +02:00
H = [
2021-06-21 11:22:55 +02:00
html_sco_header . html_sem_header (
2022-09-03 11:41:56 +02:00
" Étudiants du %s " % ( group [ " group_name " ] or " semestre " )
2021-06-02 22:40:34 +02:00
) ,
' <table class= " sortable " id= " listegroupe " > ' ,
" <tr><th>Nom</th><th>Nom usuel</th><th>Prénom</th><th>Mail</th><th>NIP (ScoDoc)</th><th>Apogée</th></tr> " ,
]
nerrs = 0 # nombre d'anomalies détectées
nfix = 0 # nb codes changes
nmailmissing = 0 # nb etuds sans mail
for t in members :
nom , nom_usuel , prenom , etudid , email , code_nip = (
t [ " nom " ] ,
t [ " nom_usuel " ] ,
t [ " prenom " ] ,
t [ " etudid " ] ,
t [ " email " ] ,
t [ " code_nip " ] ,
)
2021-08-20 10:51:42 +02:00
infos = sco_portal_apogee . get_infos_apogee ( nom , prenom )
2021-06-02 22:40:34 +02:00
if not infos :
info_apogee = (
' <b>Pas d \' information</b> (<a href= " etudident_edit_form?etudid= %s " >Modifier identité</a>) '
% etudid
)
nerrs + = 1
else :
if len ( infos ) == 1 :
nip_apogee = infos [ 0 ] [ " nip " ]
if code_nip != nip_apogee :
if fix :
# Update database
2021-06-19 23:21:37 +02:00
sco_etud . identite_edit (
2021-06-02 22:40:34 +02:00
cnx ,
args = { " etudid " : etudid , " code_nip " : nip_apogee } ,
)
info_apogee = (
' <span style= " color:green " >copié %s </span> ' % nip_apogee
)
nfix + = 1
else :
info_apogee = ' <span style= " color:red " > %s </span> ' % nip_apogee
nerrs + = 1
else :
info_apogee = " ok "
else :
info_apogee = (
' <b> %d correspondances</b> (<a href= " etudident_edit_form?etudid= %s " >Choisir</a>) '
% ( len ( infos ) , etudid )
)
nerrs + = 1
# check mail
if email :
mailstat = " ok "
else :
if fixmail and len ( infos ) == 1 and " mail " in infos [ 0 ] :
mail_apogee = infos [ 0 ] [ " mail " ]
2021-06-19 23:21:37 +02:00
adrs = sco_etud . adresse_list ( cnx , { " etudid " : etudid } )
2021-06-02 22:40:34 +02:00
if adrs :
adr = adrs [ 0 ] # modif adr existante
args = { " adresse_id " : adr [ " adresse_id " ] , " email " : mail_apogee }
2021-08-21 00:24:51 +02:00
sco_etud . adresse_edit ( cnx , args = args , disable_notify = True )
2021-06-02 22:40:34 +02:00
else :
# creation adresse
args = { " etudid " : etudid , " email " : mail_apogee }
2021-06-19 23:21:37 +02:00
sco_etud . adresse_create ( cnx , args = args )
2021-06-02 22:40:34 +02:00
mailstat = ' <span style= " color:green " >copié</span> '
else :
mailstat = " inconnu "
nmailmissing + = 1
H . append (
2021-07-11 17:37:12 +02:00
' <tr><td><a href= " %s " > %s </a></td><td> %s </td><td> %s </td><td> %s </td><td> %s </td><td> %s </td></tr> '
% (
url_for ( " scolar.ficheEtud " , scodoc_dept = g . scodoc_dept , etudid = etudid ) ,
nom ,
nom_usuel ,
prenom ,
mailstat ,
code_nip ,
info_apogee ,
)
2021-06-02 22:40:34 +02:00
)
H . append ( " </table> " )
H . append ( " <ul> " )
if nfix :
H . append ( " <li><b> %d </b> codes modifiés</li> " % nfix )
H . append ( " <li>Codes NIP: <b> %d </b> anomalies détectées</li> " % nerrs )
H . append ( " <li>Adresse mail: <b> %d </b> étudiants sans adresse</li> " % nmailmissing )
H . append ( " </ul> " )
H . append (
"""
< form method = " get " action = " %s " >
< input type = " hidden " name = " formsemestre_id " value = " %s " / >
< input type = " hidden " name = " group_id " value = " %s " / >
< input type = " hidden " name = " etat " value = " %s " / >
< input type = " hidden " name = " fix " value = " 1 " / >
< input type = " submit " value = " Mettre à jour les codes NIP depuis Apogée " / >
< / form >
< p > < a href = " Notes/formsemestre_status?formsemestre_id= %s " > Retour au semestre < / a >
"""
% (
2021-09-18 10:10:02 +02:00
request . base_url ,
2021-06-02 22:40:34 +02:00
formsemestre_id ,
scu . strnone ( group_id ) ,
scu . strnone ( etat ) ,
formsemestre_id ,
)
)
H . append (
"""
< form method = " get " action = " %s " >
< input type = " hidden " name = " formsemestre_id " value = " %s " / >
< input type = " hidden " name = " group_id " value = " %s " / >
< input type = " hidden " name = " etat " value = " %s " / >
< input type = " hidden " name = " fixmail " value = " 1 " / >
< input type = " submit " value = " Renseigner les e-mail manquants (adresse institutionnelle) " / >
< / form >
< p > < a href = " Notes/formsemestre_status?formsemestre_id= %s " > Retour au semestre < / a >
"""
% (
2021-09-18 10:10:02 +02:00
request . base_url ,
2021-06-02 22:40:34 +02:00
formsemestre_id ,
scu . strnone ( group_id ) ,
scu . strnone ( etat ) ,
formsemestre_id ,
)
)
2021-07-29 10:19:00 +02:00
return " \n " . join ( H ) + html_sco_header . sco_footer ( )
2021-06-02 22:40:34 +02:00
2021-08-14 10:12:40 +02:00
@bp.route ( " /form_students_import_excel " , methods = [ " GET " , " POST " ] )
2021-08-15 21:33:47 +02:00
@scodoc
2021-06-02 22:40:34 +02:00
@permission_required ( Permission . ScoEtudInscrit )
2021-08-21 00:24:51 +02:00
@scodoc7func
2021-09-27 10:20:10 +02:00
def form_students_import_excel ( formsemestre_id = None ) :
2021-06-02 22:40:34 +02:00
" formulaire import xls "
2021-09-29 20:08:18 +02:00
formsemestre_id = int ( formsemestre_id ) if formsemestre_id else None
2021-06-02 22:40:34 +02:00
if formsemestre_id :
2021-08-19 10:28:35 +02:00
sem = sco_formsemestre . get_formsemestre ( formsemestre_id )
2023-03-02 22:55:25 +01:00
dest_url = url_for (
" notes.formsemestre_status " ,
scodoc_dept = g . scodoc_dept ,
formsemestre_id = formsemestre_id ,
2021-06-02 22:40:34 +02:00
)
else :
sem = None
2021-06-15 12:34:33 +02:00
dest_url = scu . ScoURL ( )
2021-08-10 12:57:38 +02:00
if sem and not sem [ " etat " ] :
2021-06-02 22:40:34 +02:00
raise ScoValueError ( " Modification impossible: semestre verrouille " )
H = [
2021-07-29 16:31:15 +02:00
html_sco_header . sco_header ( page_title = " Import etudiants " ) ,
2021-06-02 22:40:34 +02:00
""" <h2 class= " formsemestre " >Téléchargement d \' une nouvelle liste d \' etudiants</h2>
< div style = " color: red " >
< p > A utiliser pour importer de < b > nouveaux < / b > étudiants ( typiquement au
< b > premier semestre < / b > ) . < / p >
< p > Si les étudiants à inscrire sont déjà dans un autre
semestre , utiliser le menu " <em>Inscriptions (passage des étudiants)
depuis d ' autres semestres</em> à partir du semestre destination.
< / p >
< p > Si vous avez un portail Apogée , il est en général préférable d ' importer les
étudiants depuis Apogée , via le menu " <em>Synchroniser avec étape Apogée</em> " .
< / p >
< / div >
< p >
L ' opération se déroule en deux étapes. Dans un premier temps,
vous téléchargez une feuille Excel type . Vous devez remplir
cette feuille , une ligne décrivant chaque étudiant . Ensuite ,
vous indiquez le nom de votre fichier dans la case " Fichier Excel "
ci - dessous , et cliquez sur " Télécharger " pour envoyer au serveur
votre liste .
< / p >
""" ,
] # '
if sem :
H . append (
""" <p style= " color: red " >Les étudiants importés seront inscrits dans
le semestre < b > % s < / b > < / p > """
% sem [ " titremois " ]
)
else :
H . append (
"""
< p > Pour inscrire directement les étudiants dans un semestre de
formation , il suffit d ' indiquer le code de ce semestre
( qui doit avoir été créé au préalable ) . < a class = " stdlink " href = " %s ?showcodes=1 " > Cliquez ici pour afficher les codes < / a >
< / p >
"""
2021-06-15 12:34:33 +02:00
% ( scu . ScoURL ( ) )
2021-06-02 22:40:34 +02:00
)
H . append ( """ <ol><li> """ )
if formsemestre_id :
H . append (
"""
< a class = " stdlink " href = " import_generate_excel_sample?with_codesemestre=0 " >
"""
)
else :
H . append ( """ <a class= " stdlink " href= " import_generate_excel_sample " > """ )
H . append (
""" Obtenir la feuille excel à remplir</a></li>
< li > """
)
2021-07-29 10:19:00 +02:00
F = html_sco_header . sco_footer ( )
2021-06-02 22:40:34 +02:00
tf = TrivialFormulator (
2021-09-18 10:10:02 +02:00
request . base_url ,
2021-09-27 16:42:14 +02:00
scu . get_request_args ( ) ,
2021-06-02 22:40:34 +02:00
(
(
" csvfile " ,
{ " title " : " Fichier Excel: " , " input_type " : " file " , " size " : 40 } ,
) ,
(
" check_homonyms " ,
{
" title " : " Vérifier les homonymes " ,
" input_type " : " boolcheckbox " ,
" explanation " : " arrète l ' importation si plus de 10 % d ' homonymes " ,
} ,
) ,
(
" require_ine " ,
{
" title " : " Importer INE " ,
" input_type " : " boolcheckbox " ,
" explanation " : " n ' importe QUE les étudiants avec nouveau code INE " ,
} ,
) ,
( " formsemestre_id " , { " input_type " : " hidden " } ) ,
) ,
initvalues = { " check_homonyms " : True , " require_ine " : False } ,
submitlabel = " Télécharger " ,
)
S = [
""" <hr/><p>Le fichier Excel décrivant les étudiants doit comporter les colonnes suivantes.
< p > Les colonnes peuvent être placées dans n ' importe quel ordre, mais
le < b > titre < / b > exact ( tel que ci - dessous ) doit être sur la première ligne .
< / p >
< p >
Les champs avec un astérisque ( * ) doivent être présents ( nulls non autorisés ) .
< / p >
< p >
< table >
< tr > < td > < b > Attribut < / b > < / td > < td > < b > Type < / b > < / td > < td > < b > Description < / b > < / td > < / tr > """
]
2021-06-21 10:17:16 +02:00
for t in sco_import_etuds . sco_import_format (
2021-06-02 22:40:34 +02:00
with_codesemestre = ( formsemestre_id == None )
) :
if int ( t [ 3 ] ) :
ast = " "
else :
ast = " * "
S . append (
" <tr><td> %s </td><td> %s </td><td> %s </td><td> %s </td></tr> "
% ( t [ 0 ] , t [ 1 ] , t [ 4 ] , ast )
)
if tf [ 0 ] == 0 :
return " \n " . join ( H ) + tf [ 1 ] + " </li></ol> " + " \n " . join ( S ) + F
elif tf [ 0 ] == - 1 :
2021-07-31 18:01:10 +02:00
return flask . redirect ( dest_url )
2021-06-02 22:40:34 +02:00
else :
2021-06-21 10:17:16 +02:00
return sco_import_etuds . students_import_excel (
2021-06-02 22:40:34 +02:00
tf [ 2 ] [ " csvfile " ] ,
2021-09-29 20:08:18 +02:00
formsemestre_id = int ( formsemestre_id ) if formsemestre_id else None ,
2021-06-02 22:40:34 +02:00
check_homonyms = tf [ 2 ] [ " check_homonyms " ] ,
require_ine = tf [ 2 ] [ " require_ine " ] ,
)
@bp.route ( " /import_generate_excel_sample " )
2021-08-13 00:34:58 +02:00
@scodoc
2021-06-02 22:40:34 +02:00
@permission_required ( Permission . ScoEtudInscrit )
2021-08-21 00:24:51 +02:00
@scodoc7func
2021-09-27 10:20:10 +02:00
def import_generate_excel_sample ( with_codesemestre = " 1 " ) :
2021-06-02 22:40:34 +02:00
" une feuille excel pour importation etudiants "
if with_codesemestre :
with_codesemestre = int ( with_codesemestre )
else :
with_codesemestre = 0
2021-06-21 10:17:16 +02:00
format = sco_import_etuds . sco_import_format ( )
data = sco_import_etuds . sco_import_generate_excel_sample (
2021-08-21 00:24:51 +02:00
format , with_codesemestre , exclude_cols = [ " photo_filename " ]
2021-06-02 22:40:34 +02:00
)
2021-09-18 10:51:19 +02:00
return scu . send_file (
2021-09-21 22:19:08 +02:00
data , " ImportEtudiants " , scu . XLSX_SUFFIX , mime = scu . XLSX_MIMETYPE
2021-09-18 10:51:19 +02:00
)
2021-06-02 22:40:34 +02:00
# --- Données admission
@bp.route ( " /import_generate_admission_sample " )
2021-08-13 00:34:58 +02:00
@scodoc
2021-06-02 22:40:34 +02:00
@permission_required ( Permission . ScoView )
2021-08-21 00:24:51 +02:00
@scodoc7func
2021-09-27 10:20:10 +02:00
def import_generate_admission_sample ( formsemestre_id ) :
2021-06-02 22:40:34 +02:00
" une feuille excel pour importation données admissions "
2021-08-19 10:28:35 +02:00
group = sco_groups . get_group ( sco_groups . get_default_group ( formsemestre_id ) )
2021-06-21 10:17:16 +02:00
fmt = sco_import_etuds . sco_import_format ( )
data = sco_import_etuds . sco_import_generate_excel_sample (
2021-06-02 22:40:34 +02:00
fmt ,
only_tables = [ " identite " , " admissions " , " adresse " ] ,
exclude_cols = [ " nationalite " , " foto " , " photo_filename " ] ,
group_ids = [ group [ " group_id " ] ] ,
)
2021-09-18 10:51:19 +02:00
return scu . send_file (
2021-09-21 22:19:08 +02:00
data , " AdmissionEtudiants " , scu . XLSX_SUFFIX , mime = scu . XLSX_MIMETYPE
2021-08-12 14:49:53 +02:00
)
2021-09-27 10:20:10 +02:00
# return sco_excel.send_excel_file(data, "AdmissionEtudiants" + scu.XLSX_SUFFIX)
2021-06-02 22:40:34 +02:00
# --- Données admission depuis fichier excel (version nov 2016)
2021-06-25 19:24:12 +02:00
@bp.route ( " /form_students_import_infos_admissions " , methods = [ " GET " , " POST " ] )
2021-08-13 00:34:58 +02:00
@scodoc
2021-06-02 22:40:34 +02:00
@permission_required ( Permission . ScoView )
2021-08-21 00:24:51 +02:00
@scodoc7func
2021-09-27 10:20:10 +02:00
def form_students_import_infos_admissions ( formsemestre_id = None ) :
2021-06-02 22:40:34 +02:00
" formulaire import xls "
2021-09-18 13:42:19 +02:00
authuser = current_user
2021-07-29 10:19:00 +02:00
F = html_sco_header . sco_footer ( )
2021-06-19 23:21:37 +02:00
if not authuser . has_permission ( Permission . ScoEtudInscrit ) :
2021-06-02 22:40:34 +02:00
# autorise juste l'export
H = [
2021-06-13 18:29:53 +02:00
html_sco_header . sco_header (
2021-06-02 22:40:34 +02:00
page_title = " Export données admissions (Parcoursup ou autre) " ,
) ,
""" <h2 class= " formsemestre " >Téléchargement des informations sur l ' admission des étudiants</h2>
< p >
< a href = " import_generate_admission_sample?formsemestre_id= %(formsemestre_id)s " > Exporter les informations de ScoDoc ( classeur Excel ) < / a > ( ce fichier peut être ré - importé après d ' éventuelles modifications)
< / p >
< p class = " warning " > Vous n ' avez pas le droit d ' importer les données < / p >
"""
% { " formsemestre_id " : formsemestre_id } ,
]
return " \n " . join ( H ) + F
# On a le droit d'importer:
H = [
2021-07-29 16:31:15 +02:00
html_sco_header . sco_header ( page_title = " Import données admissions Parcoursup " ) ,
2021-06-02 22:40:34 +02:00
""" <h2 class= " formsemestre " >Téléchargement des informations sur l ' admission des étudiants depuis feuilles import Parcoursup</h2>
< div style = " color: red " >
< p > A utiliser pour renseigner les informations sur l ' origine des étudiants (lycées, bac, etc). Ces informations sont facultatives mais souvent utiles pour mieux connaitre les étudiants et aussi pour effectuer des statistiques (résultats suivant le type de bac...). Les données sont affichées sur les fiches individuelles des étudiants.</p>
< / div >
< p >
Importer ici la feuille excel utilisée pour envoyer le classement Parcoursup .
Seuls les étudiants actuellement inscrits dans ce semestre ScoDoc seront affectés ,
les autres lignes de la feuille seront ignorées . Et seules les colonnes intéressant ScoDoc
seront importées : il est inutile d ' éliminer les autres.
2022-10-02 23:43:29 +02:00
< br >
2021-06-02 22:40:34 +02:00
< em > Seules les données " admission " seront modifiées ( et pas l ' identité de l ' étudiant ) . < / em >
2022-10-02 23:43:29 +02:00
< br >
2021-06-02 22:40:34 +02:00
< em > Les colonnes " nom " et " prenom " sont requises , ou bien une colonne " etudid " . < / em >
< / p >
< p >
Avant d ' importer vos données, il est recommandé d ' enregistrer les informations actuelles :
< a href = " import_generate_admission_sample?formsemestre_id= %(formsemestre_id)s " > exporter les données actuelles de ScoDoc < / a > ( ce fichier peut être ré - importé après d ' éventuelles modifications)
< / p >
"""
% { " formsemestre_id " : formsemestre_id } ,
] # '
type_admission_list = (
" Autre " ,
" Parcoursup " ,
" Parcoursup PC " ,
" APB " ,
" APB PC " ,
" CEF " ,
" Direct " ,
)
tf = TrivialFormulator (
2021-09-18 10:10:02 +02:00
request . base_url ,
2021-09-27 16:42:14 +02:00
scu . get_request_args ( ) ,
2021-06-02 22:40:34 +02:00
(
(
" csvfile " ,
{ " title " : " Fichier Excel: " , " input_type " : " file " , " size " : 40 } ,
) ,
(
" type_admission " ,
{
" title " : " Type d ' admission " ,
" explanation " : " sera attribué aux étudiants modifiés par cet import n ' ayant pas déjà un type " ,
" input_type " : " menu " ,
" allowed_values " : type_admission_list ,
} ,
) ,
( " formsemestre_id " , { " input_type " : " hidden " } ) ,
) ,
submitlabel = " Télécharger " ,
)
help_text = (
""" <p>Les colonnes importables par cette fonction sont indiquées dans la table ci-dessous.
Seule la première feuille du classeur sera utilisée .
< div id = " adm_table_description_format " >
"""
2021-08-21 00:24:51 +02:00
+ sco_import_etuds . adm_table_description_format ( ) . html ( )
2021-06-02 22:40:34 +02:00
+ """ </div> """
)
if tf [ 0 ] == 0 :
return " \n " . join ( H ) + tf [ 1 ] + help_text + F
elif tf [ 0 ] == - 1 :
2021-07-31 18:01:10 +02:00
return flask . redirect (
2021-08-10 17:12:10 +02:00
scu . ScoURL ( )
+ " /formsemestre_status?formsemestre_id= "
+ str ( formsemestre_id )
2021-06-02 22:40:34 +02:00
)
else :
2021-06-21 12:13:25 +02:00
return sco_import_etuds . students_import_admission (
2021-06-02 22:40:34 +02:00
tf [ 2 ] [ " csvfile " ] ,
type_admission = tf [ 2 ] [ " type_admission " ] ,
formsemestre_id = formsemestre_id ,
)
@bp.route ( " /formsemestre_import_etud_admission " )
2021-08-13 00:34:58 +02:00
@scodoc
2021-06-02 22:40:34 +02:00
@permission_required ( Permission . ScoEtudChangeAdr )
2021-08-21 00:24:51 +02:00
@scodoc7func
2021-09-27 10:20:10 +02:00
def formsemestre_import_etud_admission ( formsemestre_id , import_email = True ) :
2021-06-02 22:40:34 +02:00
""" Reimporte donnees admissions par synchro Portail Apogée """
(
no_nip ,
unknowns ,
changed_mails ,
) = sco_synchro_etuds . formsemestre_import_etud_admission (
2021-08-21 00:24:51 +02:00
formsemestre_id , import_identite = True , import_email = import_email
2021-06-02 22:40:34 +02:00
)
H = [
2021-09-24 12:10:53 +02:00
html_sco_header . html_sem_header ( " Reimport données admission " ) ,
2021-06-02 22:40:34 +02:00
" <h3>Opération effectuée</h3> " ,
]
if no_nip :
H . append ( " <p>Attention: étudiants sans NIP: " + str ( no_nip ) + " </p> " )
if unknowns :
H . append (
" <p>Attention: étudiants inconnus du portail: codes NIP= "
+ str ( unknowns )
+ " </p> "
)
if changed_mails :
H . append ( " <h3>Adresses mails modifiées:</h3> " )
for ( info , new_mail ) in changed_mails :
H . append (
2022-10-02 23:43:29 +02:00
" %s : <tt> %s </tt> devient <tt> %s </tt><br> "
2021-06-02 22:40:34 +02:00
% ( info [ " nom " ] , info [ " email " ] , new_mail )
)
2021-07-29 10:19:00 +02:00
return " \n " . join ( H ) + html_sco_header . sco_footer ( )
2021-06-02 22:40:34 +02:00
sco_publish (
" /photos_import_files_form " ,
sco_trombino . photos_import_files_form ,
Permission . ScoEtudChangeAdr ,
2021-08-20 09:17:44 +02:00
methods = [ " GET " , " POST " ] ,
2021-06-02 22:40:34 +02:00
)
sco_publish (
" /photos_generate_excel_sample " ,
sco_trombino . photos_generate_excel_sample ,
Permission . ScoEtudChangeAdr ,
)
# --- Statistiques
@bp.route ( " /stat_bac " )
2021-08-13 00:34:58 +02:00
@scodoc
2021-06-02 22:40:34 +02:00
@permission_required ( Permission . ScoView )
2021-08-21 00:24:51 +02:00
@scodoc7func
def stat_bac ( formsemestre_id ) :
2021-06-02 22:40:34 +02:00
" Renvoie statistisques sur nb d ' etudiants par bac "
2021-06-15 13:59:56 +02:00
cnx = ndb . GetDBConnexion ( )
2021-06-16 16:59:31 +02:00
ins = sco_formsemestre_inscriptions . do_formsemestre_inscription_list (
2021-08-19 10:28:35 +02:00
args = { " formsemestre_id " : formsemestre_id }
2021-06-02 22:40:34 +02:00
)
Bacs = { } # type bac : nb etud
for i in ins :
2021-06-19 23:21:37 +02:00
etud = sco_etud . etudident_list ( cnx , { " etudid " : i [ " etudid " ] } ) [ 0 ]
2021-06-02 22:40:34 +02:00
typebac = " %(bac)s %(specialite)s " % etud
Bacs [ typebac ] = Bacs . get ( typebac , 0 ) + 1
return Bacs
2022-03-14 14:09:59 +01:00
# --- Dump (assistance)
@bp.route ( " /sco_dump_and_send_db " , methods = [ " GET " , " POST " ] )
@scodoc
@permission_required ( Permission . ScoView )
@scodoc7func
2022-09-10 15:23:54 +02:00
def sco_dump_and_send_db ( message = " " , request_url = " " , traceback_str_base64 = " " ) :
2022-03-14 14:09:59 +01:00
" Send anonymized data to supervision "
2022-03-21 11:48:34 +01:00
2022-09-10 15:23:54 +02:00
status_code = sco_dump_db . sco_dump_and_send_db (
message , request_url , traceback_str_base64 = traceback_str_base64
)
2022-03-21 11:48:34 +01:00
H = [ html_sco_header . sco_header ( page_title = " Assistance technique " ) ]
if status_code == requests . codes . INSUFFICIENT_STORAGE : # pylint: disable=no-member
H . append (
""" <p class= " warning " >
Erreur : espace serveur trop plein .
Merci de contacter < a href = " mailto: {0} " > { 0 } < / a > < / p > """ .format(
scu . SCO_DEV_MAIL
)
)
elif status_code == requests . codes . OK : # pylint: disable=no-member
H . append ( """ <p>Opération effectuée.</p> """ )
else :
H . append (
f """ <p class= " warning " >
Erreur : code < tt > { status_code } < / tt >
Merci de contacter < a href = " mailto: {scu.SCO_DEV_MAIL} " > { scu . SCO_DEV_MAIL } < / a > < / p > """
)
flash ( " Données envoyées au serveur d ' assistance " )
return " \n " . join ( H ) + html_sco_header . sco_footer ( )