forked from ScoDoc/ScoDoc
Merge branch 'master' of https://scodoc.org/git/viennet/ScoDoc into dev93
This commit is contained in:
commit
7b12552121
@ -23,4 +23,13 @@ def requested_format(default_format="json", allowed_formats=None):
|
|||||||
|
|
||||||
from app.api import tokens
|
from app.api import tokens
|
||||||
from app.api import sco_api
|
from app.api import sco_api
|
||||||
|
from app.api import test_api
|
||||||
|
from app.api import departements
|
||||||
|
from app.api import etudiants
|
||||||
|
from app.api import formations
|
||||||
|
from app.api import formsemestres
|
||||||
|
from app.api import partitions
|
||||||
|
from app.api import evaluations
|
||||||
|
from app.api import jury
|
||||||
|
from app.api import absences
|
||||||
from app.api import logos
|
from app.api import logos
|
||||||
|
150
app/api/absences.py
Normal file
150
app/api/absences.py
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
#################################################### Absences #########################################################
|
||||||
|
|
||||||
|
from flask import jsonify
|
||||||
|
|
||||||
|
from app.api import bp
|
||||||
|
from app.api.errors import error_response
|
||||||
|
from app.api.auth import token_permission_required
|
||||||
|
from app.api.tools import get_etu_from_etudid_or_nip_or_ine
|
||||||
|
from app.scodoc import notesdb as ndb
|
||||||
|
|
||||||
|
from app.scodoc import sco_abs
|
||||||
|
from app.scodoc.sco_groups import get_group_members
|
||||||
|
from app.scodoc.sco_permissions import Permission
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route("/absences/etudid/<int:etudid>", methods=["GET"])
|
||||||
|
@bp.route("/absences/nip/<int:nip>", methods=["GET"])
|
||||||
|
@bp.route("/absences/ine/<int:ine>", methods=["GET"])
|
||||||
|
@token_permission_required(Permission.APIView)
|
||||||
|
def absences(etudid: int = None, nip: int = None, ine: int = None):
|
||||||
|
"""
|
||||||
|
Retourne la liste des absences d'un étudiant donné
|
||||||
|
|
||||||
|
etudid : l'etudid d'un étudiant
|
||||||
|
nip: le code nip d'un étudiant
|
||||||
|
ine : le code ine d'un étudiant
|
||||||
|
|
||||||
|
Exemple de résultat:
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"jour": "2022-04-15",
|
||||||
|
"matin": true,
|
||||||
|
"estabs": true,
|
||||||
|
"estjust": true,
|
||||||
|
"description": "",
|
||||||
|
"begin": "2022-04-15 08:00:00",
|
||||||
|
"end": "2022-04-15 11:59:59"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"jour": "2022-04-15",
|
||||||
|
"matin": false,
|
||||||
|
"estabs": true,
|
||||||
|
"estjust": false,
|
||||||
|
"description": "",
|
||||||
|
"begin": "2022-04-15 12:00:00",
|
||||||
|
"end": "2022-04-15 17:59:59"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
"""
|
||||||
|
if etudid is None:
|
||||||
|
# Récupération de l'étudiant
|
||||||
|
etud = get_etu_from_etudid_or_nip_or_ine(etudid, nip, ine)
|
||||||
|
if etud is None:
|
||||||
|
return error_response(
|
||||||
|
409,
|
||||||
|
message="La requête ne peut être traitée en l’état actuel.\n "
|
||||||
|
"Veuillez vérifier que l'id de l'étudiant (etudid, nip, ine) est valide",
|
||||||
|
)
|
||||||
|
etudid = etud.etudid
|
||||||
|
|
||||||
|
# Récupération des absences de l'étudiant
|
||||||
|
ndb.open_db_connection()
|
||||||
|
absences = sco_abs.list_abs_date(etudid)
|
||||||
|
for absence in absences:
|
||||||
|
absence["jour"] = absence["jour"].isoformat()
|
||||||
|
return jsonify(absences)
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route("/absences/etudid/<int:etudid>/just", methods=["GET"])
|
||||||
|
@bp.route("/absences/nip/<int:nip>/just", methods=["GET"])
|
||||||
|
@bp.route("/absences/ine/<int:ine>/just", methods=["GET"])
|
||||||
|
@token_permission_required(Permission.APIView)
|
||||||
|
def absences_just(etudid: int = None, nip: int = None, ine: int = None):
|
||||||
|
"""
|
||||||
|
Retourne la liste des absences justifiées d'un étudiant donné
|
||||||
|
|
||||||
|
etudid : l'etudid d'un étudiant
|
||||||
|
nip: le code nip d'un étudiant
|
||||||
|
ine : le code ine d'un étudiant
|
||||||
|
|
||||||
|
Exemple de résultat :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"jour": "2022-04-15",
|
||||||
|
"matin": true,
|
||||||
|
"estabs": true,
|
||||||
|
"estjust": true,
|
||||||
|
"description": "",
|
||||||
|
"begin": "2022-04-15 08:00:00",
|
||||||
|
"end": "2022-04-15 11:59:59"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"jour": "Fri, 15 Apr 2022 00:00:00 GMT",
|
||||||
|
"matin": false,
|
||||||
|
"estabs": true,
|
||||||
|
"estjust": false,
|
||||||
|
"description": "",
|
||||||
|
"begin": "2022-04-15 12:00:00",
|
||||||
|
"end": "2022-04-15 17:59:59"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
"""
|
||||||
|
if etudid is None:
|
||||||
|
# Récupération de l'étudiant
|
||||||
|
try:
|
||||||
|
etu = get_etu_from_etudid_or_nip_or_ine(etudid, nip, ine)
|
||||||
|
etudid = etu.etudid
|
||||||
|
except AttributeError:
|
||||||
|
return error_response(
|
||||||
|
409,
|
||||||
|
message="La requête ne peut être traitée en l’état actuel.\n "
|
||||||
|
"Veuillez vérifier que l'id de l'étudiant (etudid, nip, ine) est valide",
|
||||||
|
)
|
||||||
|
|
||||||
|
# Récupération des absences justifiées de l'étudiant
|
||||||
|
absences = sco_abs.list_abs_date(etudid)
|
||||||
|
for absence in [absence for absence in absences if absence["estjust"]]:
|
||||||
|
absence["jour"] = absence["jour"].isoformat()
|
||||||
|
return jsonify(absences)
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route(
|
||||||
|
"/absences/abs_group_etat/?group_id=<int:group_id>&date_debut=date_debut&date_fin=date_fin",
|
||||||
|
methods=["GET"],
|
||||||
|
)
|
||||||
|
@token_permission_required(Permission.APIView)
|
||||||
|
def abs_groupe_etat( # XXX A REVOIR XXX
|
||||||
|
group_id: int, date_debut, date_fin, with_boursier=True, format="html"
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Retoune la liste des absences d'un ou plusieurs groupes entre deux dates
|
||||||
|
"""
|
||||||
|
# Fonction utilisée : app.scodoc.sco_groups.get_group_members() et app.scodoc.sco_abs.list_abs_date()
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Utilisation de la fonction get_group_members
|
||||||
|
members = get_group_members(group_id)
|
||||||
|
except ValueError:
|
||||||
|
return error_response(
|
||||||
|
409, message="La requête ne peut être traitée en l’état actuel"
|
||||||
|
)
|
||||||
|
|
||||||
|
data = []
|
||||||
|
# Filtre entre les deux dates renseignées
|
||||||
|
for member in members:
|
||||||
|
abs = sco_abs.list_abs_date(member.id, date_debut, date_fin)
|
||||||
|
data.append(abs)
|
||||||
|
|
||||||
|
# return jsonify(data) # XXX TODO faire en sorte de pouvoir renvoyer sa (ex to_dict() dans absences)
|
||||||
|
return error_response(501, message="Not implemented")
|
@ -24,6 +24,10 @@
|
|||||||
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
from functools import wraps
|
||||||
|
|
||||||
|
|
||||||
|
from flask import abort
|
||||||
from flask import g
|
from flask import g
|
||||||
from flask_httpauth import HTTPBasicAuth, HTTPTokenAuth
|
from flask_httpauth import HTTPBasicAuth, HTTPTokenAuth
|
||||||
from app.auth.models import User
|
from app.auth.models import User
|
||||||
@ -63,15 +67,17 @@ def get_user_roles(user):
|
|||||||
return user.roles
|
return user.roles
|
||||||
|
|
||||||
|
|
||||||
# def token_permission_required(permission):
|
def token_permission_required(permission):
|
||||||
# def decorator(f):
|
def decorator(f):
|
||||||
# @wraps(f)
|
@wraps(f)
|
||||||
# def decorated_function(*args, **kwargs):
|
def decorated_function(*args, **kwargs):
|
||||||
# scodoc_dept = getattr(g, "scodoc_dept", None)
|
scodoc_dept = getattr(g, "scodoc_dept", None)
|
||||||
# if not current_user.has_permission(permission, scodoc_dept):
|
if hasattr(g, "current_user") and not g.current_user.has_permission(
|
||||||
# abort(403)
|
permission, scodoc_dept
|
||||||
# return f(*args, **kwargs)
|
):
|
||||||
|
abort(403)
|
||||||
|
return f(*args, **kwargs)
|
||||||
|
|
||||||
# return login_required(decorated_function)
|
return decorated_function # login_required(decorated_function)
|
||||||
|
|
||||||
# return decorator
|
return decorator
|
||||||
|
303
app/api/departements.py
Normal file
303
app/api/departements.py
Normal file
@ -0,0 +1,303 @@
|
|||||||
|
############################################### Departements ##########################################################
|
||||||
|
import app
|
||||||
|
|
||||||
|
from app import models
|
||||||
|
from app.api import bp
|
||||||
|
from app.api.auth import token_permission_required
|
||||||
|
from app.api.errors import error_response
|
||||||
|
from app.scodoc.sco_permissions import Permission
|
||||||
|
|
||||||
|
from flask import jsonify
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route("/departements", methods=["GET"])
|
||||||
|
@token_permission_required(Permission.APIView)
|
||||||
|
def departements():
|
||||||
|
"""
|
||||||
|
Retourne la liste des ids de départements visibles
|
||||||
|
|
||||||
|
Exemple de résultat :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"acronym": "TAPI",
|
||||||
|
"description": null,
|
||||||
|
"visible": true,
|
||||||
|
"date_creation": "Fri, 15 Apr 2022 12:19:28 GMT"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"acronym": "MMI",
|
||||||
|
"description": null,
|
||||||
|
"visible": false,
|
||||||
|
"date_creation": "Fri, 18 Apr 2022 11:20:8 GMT"
|
||||||
|
},
|
||||||
|
...
|
||||||
|
]
|
||||||
|
"""
|
||||||
|
# Récupération de tous les départements
|
||||||
|
depts = models.Departement.query.all()
|
||||||
|
|
||||||
|
# Mise en place de la liste avec tous les départements
|
||||||
|
data = [d.to_dict() for d in depts]
|
||||||
|
|
||||||
|
return jsonify(data)
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route("/departements/<string:dept>/etudiants/liste", methods=["GET"])
|
||||||
|
@bp.route(
|
||||||
|
"/departements/<string:dept>/etudiants/liste/<int:formsemestre_id>", methods=["GET"]
|
||||||
|
)
|
||||||
|
@token_permission_required(Permission.APIView)
|
||||||
|
def liste_etudiants(dept: str, formsemestre_id=None):
|
||||||
|
"""
|
||||||
|
Retourne la liste des étudiants d'un département
|
||||||
|
|
||||||
|
dept: l'acronym d'un département
|
||||||
|
formsemestre_id: l'id d'un formesemestre
|
||||||
|
|
||||||
|
Exemple de résultat :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"civilite": "X",
|
||||||
|
"code_ine": null,
|
||||||
|
"code_nip": null,
|
||||||
|
"date_naissance": null,
|
||||||
|
"email": null,
|
||||||
|
"emailperso": null,
|
||||||
|
"etudid": 18,
|
||||||
|
"nom": "MOREL",
|
||||||
|
"prenom": "JACQUES"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"civilite": "X",
|
||||||
|
"code_ine": null,
|
||||||
|
"code_nip": null,
|
||||||
|
"date_naissance": null,
|
||||||
|
"email": null,
|
||||||
|
"emailperso": null,
|
||||||
|
"etudid": 19,
|
||||||
|
"nom": "FOURNIER",
|
||||||
|
"prenom": "ANNE"
|
||||||
|
},
|
||||||
|
...
|
||||||
|
]
|
||||||
|
"""
|
||||||
|
# Si le formsemestre_id a été renseigné
|
||||||
|
if formsemestre_id is not None:
|
||||||
|
# Récupération du formsemestre
|
||||||
|
formsemestre = models.FormSemestre.query.filter_by(
|
||||||
|
id=formsemestre_id
|
||||||
|
).first_or_404()
|
||||||
|
# Récupération du département
|
||||||
|
departement = formsemestre.departement
|
||||||
|
|
||||||
|
# Si le formsemestre_id n'a pas été renseigné
|
||||||
|
else:
|
||||||
|
# Récupération du formsemestre
|
||||||
|
departement = models.Departement.query.filter_by(acronym=dept).first_or_404()
|
||||||
|
|
||||||
|
# Récupération des étudiants
|
||||||
|
etudiants = departement.etudiants.all()
|
||||||
|
|
||||||
|
# Mise en forme des données
|
||||||
|
list_etu = [etu.to_dict_bul(include_urls=False) for etu in etudiants]
|
||||||
|
|
||||||
|
return jsonify(list_etu)
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route("/departements/<string:dept>/semestres_courants", methods=["GET"])
|
||||||
|
@token_permission_required(Permission.APIView)
|
||||||
|
def liste_semestres_courant(dept: str):
|
||||||
|
"""
|
||||||
|
Liste des semestres actifs d'un départements donné
|
||||||
|
|
||||||
|
dept: l'acronym d'un département
|
||||||
|
|
||||||
|
Exemple de résultat :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"titre": "master machine info",
|
||||||
|
"gestion_semestrielle": false,
|
||||||
|
"scodoc7_id": null,
|
||||||
|
"date_debut": "01/09/2021",
|
||||||
|
"bul_bgcolor": null,
|
||||||
|
"date_fin": "15/12/2022",
|
||||||
|
"resp_can_edit": false,
|
||||||
|
"dept_id": 1,
|
||||||
|
"etat": true,
|
||||||
|
"resp_can_change_ens": false,
|
||||||
|
"id": 1,
|
||||||
|
"modalite": "FI",
|
||||||
|
"ens_can_edit_eval": false,
|
||||||
|
"formation_id": 1,
|
||||||
|
"gestion_compensation": false,
|
||||||
|
"elt_sem_apo": null,
|
||||||
|
"semestre_id": 1,
|
||||||
|
"bul_hide_xml": false,
|
||||||
|
"elt_annee_apo": null,
|
||||||
|
"block_moyennes": false,
|
||||||
|
"formsemestre_id": 1,
|
||||||
|
"titre_num": "master machine info semestre 1",
|
||||||
|
"date_debut_iso": "2021-09-01",
|
||||||
|
"date_fin_iso": "2022-12-15",
|
||||||
|
"responsables": [
|
||||||
|
3,
|
||||||
|
2
|
||||||
|
]
|
||||||
|
},
|
||||||
|
...
|
||||||
|
]
|
||||||
|
"""
|
||||||
|
# Récupération des départements comportant l'acronym mit en paramètre
|
||||||
|
dept = models.Departement.query.filter_by(acronym=dept).first_or_404()
|
||||||
|
|
||||||
|
# Récupération des semestres suivant id_dept
|
||||||
|
semestres = models.FormSemestre.query.filter_by(dept_id=dept.id, etat=True)
|
||||||
|
|
||||||
|
# Mise en forme des données
|
||||||
|
data = [d.to_dict() for d in semestres]
|
||||||
|
|
||||||
|
return jsonify(data)
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route(
|
||||||
|
"/departements/<string:dept>/formations/<int:formation_id>/referentiel_competences",
|
||||||
|
methods=["GET"],
|
||||||
|
)
|
||||||
|
@token_permission_required(Permission.APIView)
|
||||||
|
def referenciel_competences(dept: str, formation_id: int):
|
||||||
|
"""
|
||||||
|
Retourne le référentiel de compétences
|
||||||
|
|
||||||
|
dept : l'acronym d'un département
|
||||||
|
formation_id : l'id d'une formation
|
||||||
|
"""
|
||||||
|
dept = models.Departement.query.filter_by(acronym=dept).first_or_404()
|
||||||
|
|
||||||
|
formation = models.Formation.query.filter_by(
|
||||||
|
id=formation_id, dept_id=dept.id
|
||||||
|
).first_or_404()
|
||||||
|
|
||||||
|
ref_comp = formation.referentiel_competence_id
|
||||||
|
|
||||||
|
if ref_comp is None:
|
||||||
|
return error_response(
|
||||||
|
204, message="Pas de référenciel de compétences pour cette formation"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
return jsonify(ref_comp)
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route(
|
||||||
|
"/departements/<string:dept>/formsemestre/<string:formsemestre_id>/programme",
|
||||||
|
methods=["GET"],
|
||||||
|
)
|
||||||
|
@token_permission_required(Permission.APIView)
|
||||||
|
def semestre_index(dept: str, formsemestre_id: int):
|
||||||
|
"""
|
||||||
|
Retourne la liste des Ues, ressources et SAE d'un semestre
|
||||||
|
|
||||||
|
dept : l'acronym d'un département
|
||||||
|
formsemestre_id : l'id d'un formesemestre
|
||||||
|
|
||||||
|
Exemple de résultat :
|
||||||
|
{
|
||||||
|
"ues": [
|
||||||
|
{
|
||||||
|
"type": 0,
|
||||||
|
"formation_id": 1,
|
||||||
|
"ue_code": "UCOD11",
|
||||||
|
"id": 1,
|
||||||
|
"ects": 12.0,
|
||||||
|
"acronyme": "RT1.1",
|
||||||
|
"is_external": false,
|
||||||
|
"numero": 1,
|
||||||
|
"code_apogee": "",
|
||||||
|
"titre": "Administrer les r\u00e9seaux et l\u2019Internet",
|
||||||
|
"coefficient": 0.0,
|
||||||
|
"semestre_idx": 1,
|
||||||
|
"color": "#B80004",
|
||||||
|
"ue_id": 1
|
||||||
|
},
|
||||||
|
...
|
||||||
|
],
|
||||||
|
"ressources": [
|
||||||
|
{
|
||||||
|
"titre": "Fondamentaux de la programmation",
|
||||||
|
"coefficient": 1.0,
|
||||||
|
"module_type": 2,
|
||||||
|
"id": 17,
|
||||||
|
"ects": null,
|
||||||
|
"abbrev": null,
|
||||||
|
"ue_id": 3,
|
||||||
|
"code": "R107",
|
||||||
|
"formation_id": 1,
|
||||||
|
"heures_cours": 0.0,
|
||||||
|
"matiere_id": 3,
|
||||||
|
"heures_td": 0.0,
|
||||||
|
"semestre_id": 1,
|
||||||
|
"heures_tp": 0.0,
|
||||||
|
"numero": 70,
|
||||||
|
"code_apogee": "",
|
||||||
|
"module_id": 17
|
||||||
|
},
|
||||||
|
...
|
||||||
|
],
|
||||||
|
"saes": [
|
||||||
|
{
|
||||||
|
"titre": "Se pr\u00e9senter sur Internet",
|
||||||
|
"coefficient": 1.0,
|
||||||
|
"module_type": 3,
|
||||||
|
"id": 14,
|
||||||
|
"ects": null,
|
||||||
|
"abbrev": null,
|
||||||
|
"ue_id": 3,
|
||||||
|
"code": "SAE14",
|
||||||
|
"formation_id": 1,
|
||||||
|
"heures_cours": 0.0,
|
||||||
|
"matiere_id": 3,
|
||||||
|
"heures_td": 0.0,
|
||||||
|
"semestre_id": 1,
|
||||||
|
"heures_tp": 0.0,
|
||||||
|
"numero": 40,
|
||||||
|
"code_apogee": "",
|
||||||
|
"module_id": 14
|
||||||
|
},
|
||||||
|
...
|
||||||
|
]
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
app.set_sco_dept(dept)
|
||||||
|
|
||||||
|
formsemestre = models.FormSemestre.query.filter_by(
|
||||||
|
id=formsemestre_id
|
||||||
|
).first_or_404()
|
||||||
|
|
||||||
|
ues = formsemestre.query_ues()
|
||||||
|
|
||||||
|
ues_dict = []
|
||||||
|
ressources = []
|
||||||
|
saes = []
|
||||||
|
|
||||||
|
for ue in ues:
|
||||||
|
ues_dict.append(ue.to_dict())
|
||||||
|
ressources = ue.get_ressources()
|
||||||
|
saes = ue.get_saes()
|
||||||
|
|
||||||
|
data_ressources = []
|
||||||
|
for ressource in ressources:
|
||||||
|
data_ressources.append(ressource.to_dict())
|
||||||
|
|
||||||
|
data_saes = []
|
||||||
|
for sae in saes:
|
||||||
|
data_saes.append(sae.to_dict())
|
||||||
|
|
||||||
|
data = {
|
||||||
|
"ues": ues_dict,
|
||||||
|
"ressources": data_ressources,
|
||||||
|
"saes": data_saes,
|
||||||
|
}
|
||||||
|
|
||||||
|
return data
|
432
app/api/etudiants.py
Normal file
432
app/api/etudiants.py
Normal file
@ -0,0 +1,432 @@
|
|||||||
|
#################################################### Etudiants ########################################################
|
||||||
|
|
||||||
|
from flask import jsonify
|
||||||
|
|
||||||
|
import app
|
||||||
|
from app import models
|
||||||
|
from app.api import bp
|
||||||
|
from app.api.errors import error_response
|
||||||
|
from app.api.auth import token_permission_required
|
||||||
|
from app.api.tools import get_etu_from_etudid_or_nip_or_ine
|
||||||
|
from app.models import FormSemestreInscription, FormSemestre, Identite
|
||||||
|
from app.scodoc import sco_bulletins
|
||||||
|
from app.scodoc import sco_groups
|
||||||
|
from app.scodoc.sco_permissions import Permission
|
||||||
|
from app.scodoc import notesdb as ndb
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route("/etudiants/courant", methods=["GET"])
|
||||||
|
@token_permission_required(Permission.APIView)
|
||||||
|
def etudiants_courant():
|
||||||
|
"""
|
||||||
|
Retourne la liste des étudiants courant
|
||||||
|
|
||||||
|
Exemple de résultat :
|
||||||
|
{
|
||||||
|
{
|
||||||
|
"civilite": "X",
|
||||||
|
"code_ine": null,
|
||||||
|
"code_nip": null,
|
||||||
|
"date_naissance": null,
|
||||||
|
"email": null,
|
||||||
|
"emailperso": null,
|
||||||
|
"etudid": 18,
|
||||||
|
"nom": "MOREL",
|
||||||
|
"prenom": "JACQUES"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"civilite": "X",
|
||||||
|
"code_ine": null,
|
||||||
|
"code_nip": null,
|
||||||
|
"date_naissance": null,
|
||||||
|
"email": null,
|
||||||
|
"emailperso": null,
|
||||||
|
"etudid": 19,
|
||||||
|
"nom": "FOURNIER",
|
||||||
|
"prenom": "ANNE"
|
||||||
|
},
|
||||||
|
...
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
# Récupération de tous les étudiants
|
||||||
|
etuds = Identite.query.filter(
|
||||||
|
Identite.id == FormSemestreInscription.etudid,
|
||||||
|
FormSemestreInscription.formsemestre_id == FormSemestre.id,
|
||||||
|
FormSemestre.date_debut <= app.db.func.now(),
|
||||||
|
FormSemestre.date_fin >= app.db.func.now(),
|
||||||
|
)
|
||||||
|
|
||||||
|
data = [etu.to_dict_bul(include_urls=False) for etu in etuds]
|
||||||
|
|
||||||
|
return jsonify(data)
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route("/etudiant/etudid/<int:etudid>", methods=["GET"])
|
||||||
|
@bp.route("/etudiant/nip/<int:nip>", methods=["GET"])
|
||||||
|
@bp.route("/etudiant/ine/<int:ine>", methods=["GET"])
|
||||||
|
@token_permission_required(Permission.APIView)
|
||||||
|
def etudiant(etudid: int = None, nip: int = None, ine: int = None):
|
||||||
|
"""
|
||||||
|
Retourne les informations de l'étudiant correspondant à l'id passé en paramètres.
|
||||||
|
|
||||||
|
etudid : l'etudid d'un étudiant
|
||||||
|
nip : le code nip d'un étudiant
|
||||||
|
ine : le code ine d'un étudiant
|
||||||
|
|
||||||
|
Exemple de résultat :
|
||||||
|
{
|
||||||
|
"civilite": "X",
|
||||||
|
"code_ine": null,
|
||||||
|
"code_nip": null,
|
||||||
|
"date_naissance": null,
|
||||||
|
"email": null,
|
||||||
|
"emailperso": null,
|
||||||
|
"etudid": 18,
|
||||||
|
"nom": "MOREL",
|
||||||
|
"prenom": "JACQUES"
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
# Récupération de l'étudiant
|
||||||
|
etud = get_etu_from_etudid_or_nip_or_ine(etudid, nip, ine)
|
||||||
|
|
||||||
|
# Mise en forme des données
|
||||||
|
data = etud.to_dict_bul(include_urls=False)
|
||||||
|
|
||||||
|
return jsonify(data)
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route("/etudiant/etudid/<int:etudid>/formsemestres")
|
||||||
|
@bp.route("/etudiant/nip/<int:nip>/formsemestres")
|
||||||
|
@bp.route("/etudiant/ine/<int:ine>/formsemestres")
|
||||||
|
@token_permission_required(Permission.APIView)
|
||||||
|
def etudiant_formsemestres(etudid: int = None, nip: int = None, ine: int = None):
|
||||||
|
"""
|
||||||
|
Retourne la liste des semestres qu'un étudiant a suivis, triés par ordre chronologique.
|
||||||
|
|
||||||
|
etudid : l'etudid d'un étudiant
|
||||||
|
nip : le code nip d'un étudiant
|
||||||
|
ine : le code ine d'un étudiant
|
||||||
|
|
||||||
|
Exemple de résultat :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"titre": "master machine info",
|
||||||
|
"gestion_semestrielle": false,
|
||||||
|
"date_debut": "01/09/2021",
|
||||||
|
"bul_bgcolor": null,
|
||||||
|
"date_fin": "15/12/2022",
|
||||||
|
"resp_can_edit": false,
|
||||||
|
"dept_id": 1,
|
||||||
|
"etat": true,
|
||||||
|
"resp_can_change_ens": false,
|
||||||
|
"id": 1,
|
||||||
|
"modalite": "FI",
|
||||||
|
"ens_can_edit_eval": false,
|
||||||
|
"formation_id": 1,
|
||||||
|
"gestion_compensation": false,
|
||||||
|
"elt_sem_apo": null,
|
||||||
|
"semestre_id": 1,
|
||||||
|
"bul_hide_xml": false,
|
||||||
|
"elt_annee_apo": null,
|
||||||
|
"block_moyennes": false,
|
||||||
|
"formsemestre_id": 1,
|
||||||
|
"titre_num": "master machine info semestre 1",
|
||||||
|
"date_debut_iso": "2021-09-01",
|
||||||
|
"date_fin_iso": "2022-12-15",
|
||||||
|
"responsables": [
|
||||||
|
3,
|
||||||
|
2
|
||||||
|
]
|
||||||
|
},
|
||||||
|
...
|
||||||
|
]
|
||||||
|
"""
|
||||||
|
# Récupération de l'étudiant
|
||||||
|
etud = get_etu_from_etudid_or_nip_or_ine(etudid, nip, ine)
|
||||||
|
|
||||||
|
formsemestres = models.FormSemestre.query.filter(
|
||||||
|
models.FormSemestreInscription.etudid == etud.id,
|
||||||
|
models.FormSemestreInscription.formsemestre_id == models.FormSemestre.id,
|
||||||
|
).order_by(models.FormSemestre.date_debut)
|
||||||
|
|
||||||
|
return jsonify([formsemestre.to_dict() for formsemestre in formsemestres])
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route(
|
||||||
|
"/etudiant/etudid/<int:etudid>/formsemestre/<int:formsemestre_id>/bulletin",
|
||||||
|
methods=["GET"],
|
||||||
|
)
|
||||||
|
@bp.route(
|
||||||
|
"/etudiant/nip/<int:nip>/formsemestre/<int:formsemestre_id>/bulletin",
|
||||||
|
methods=["GET"],
|
||||||
|
)
|
||||||
|
@bp.route(
|
||||||
|
"/etudiant/ine/<int:ine>/formsemestre/<int:formsemestre_id>/bulletin",
|
||||||
|
methods=["GET"],
|
||||||
|
)
|
||||||
|
@token_permission_required(Permission.APIView)
|
||||||
|
def etudiant_bulletin_semestre(
|
||||||
|
formsemestre_id, etudid: int = None, nip: int = None, ine: int = None
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Retourne le bulletin d'un étudiant en fonction de son id et d'un semestre donné
|
||||||
|
|
||||||
|
formsemestre_id : l'id d'un formsemestre
|
||||||
|
etudid : l'etudid d'un étudiant
|
||||||
|
nip : le code nip d'un étudiant
|
||||||
|
ine : le code ine d'un étudiant
|
||||||
|
Exemple de résultat :
|
||||||
|
{
|
||||||
|
"version": "0",
|
||||||
|
"type": "BUT",
|
||||||
|
"date": "2022-04-27T07:18:16.450634Z",
|
||||||
|
"publie": true,
|
||||||
|
"etudiant": {
|
||||||
|
"civilite": "X",
|
||||||
|
"code_ine": "1",
|
||||||
|
"code_nip": "1",
|
||||||
|
"date_naissance": "",
|
||||||
|
"email": "SACHA.COSTA@example.com",
|
||||||
|
"emailperso": "",
|
||||||
|
"etudid": 1,
|
||||||
|
"nom": "COSTA",
|
||||||
|
"prenom": "SACHA",
|
||||||
|
"nomprenom": "Sacha COSTA",
|
||||||
|
"lieu_naissance": "",
|
||||||
|
"dept_naissance": "",
|
||||||
|
"nationalite": "",
|
||||||
|
"boursier": "",
|
||||||
|
"fiche_url": "/ScoDoc/TAPI/Scolarite/ficheEtud?etudid=1",
|
||||||
|
"photo_url": "/ScoDoc/TAPI/Scolarite/get_photo_image?etudid=1&size=small",
|
||||||
|
"id": 1,
|
||||||
|
"codepostaldomicile": "",
|
||||||
|
"paysdomicile": "",
|
||||||
|
"telephonemobile": "",
|
||||||
|
"typeadresse": "domicile",
|
||||||
|
"domicile": "",
|
||||||
|
"villedomicile": "",
|
||||||
|
"telephone": "",
|
||||||
|
"fax": "",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"formation": {
|
||||||
|
"id": 1,
|
||||||
|
"acronyme": "BUT R&T",
|
||||||
|
"titre_officiel": "Bachelor technologique r\u00e9seaux et t\u00e9l\u00e9communications",
|
||||||
|
"titre": "BUT R&T"
|
||||||
|
},
|
||||||
|
"formsemestre_id": 1,
|
||||||
|
"etat_inscription": "I",
|
||||||
|
"options": {
|
||||||
|
"show_abs": true,
|
||||||
|
"show_abs_modules": false,
|
||||||
|
"show_ects": true,
|
||||||
|
"show_codemodules": false,
|
||||||
|
"show_matieres": false,
|
||||||
|
"show_rangs": true,
|
||||||
|
"show_ue_rangs": true,
|
||||||
|
"show_mod_rangs": true,
|
||||||
|
"show_moypromo": false,
|
||||||
|
"show_minmax": false,
|
||||||
|
"show_minmax_mod": false,
|
||||||
|
"show_minmax_eval": false,
|
||||||
|
"show_coef": true,
|
||||||
|
"show_ue_cap_details": false,
|
||||||
|
"show_ue_cap_current": true,
|
||||||
|
"show_temporary": true,
|
||||||
|
"temporary_txt": "Provisoire",
|
||||||
|
"show_uevalid": true,
|
||||||
|
"show_date_inscr": true
|
||||||
|
},
|
||||||
|
"ressources": {
|
||||||
|
"R101": {
|
||||||
|
"id": 1,
|
||||||
|
"titre": "Initiation aux r\u00e9seaux informatiques",
|
||||||
|
"code_apogee": null,
|
||||||
|
"url": "/ScoDoc/TAPI/Scolarite/Notes/moduleimpl_status?moduleimpl_id=1",
|
||||||
|
"moyenne": {},
|
||||||
|
"evaluations": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"description": "eval1",
|
||||||
|
"date": "2022-04-20",
|
||||||
|
"heure_debut": "08:00",
|
||||||
|
"heure_fin": "09:00",
|
||||||
|
"coef": "01.00",
|
||||||
|
"poids": {
|
||||||
|
"RT1.1": 1.0,
|
||||||
|
},
|
||||||
|
"note": {
|
||||||
|
"value": "12.00",
|
||||||
|
"min": "00.00",
|
||||||
|
"max": "18.00",
|
||||||
|
"moy": "10.88"
|
||||||
|
},
|
||||||
|
"url": "/ScoDoc/TAPI/Scolarite/Notes/evaluation_listenotes?evaluation_id=1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"saes": {
|
||||||
|
"SAE11": {
|
||||||
|
"id": 2,
|
||||||
|
"titre": "Se sensibiliser \u00e0 l'hygi\u00e8ne informatique et \u00e0 la cybers\u00e9curit\u00e9",
|
||||||
|
"code_apogee": null,
|
||||||
|
"url": "/ScoDoc/TAPI/Scolarite/Notes/moduleimpl_status?moduleimpl_id=2",
|
||||||
|
"moyenne": {},
|
||||||
|
"evaluations": []
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"ues": {
|
||||||
|
"RT1.1": {
|
||||||
|
"id": 1,
|
||||||
|
"titre": "Administrer les r\u00e9seaux et l\u2019Internet",
|
||||||
|
"numero": 1,
|
||||||
|
"type": 0,
|
||||||
|
"color": "#B80004",
|
||||||
|
"competence": null,
|
||||||
|
"moyenne": {
|
||||||
|
"value": "08.50",
|
||||||
|
"min": "06.00",
|
||||||
|
"max": "16.50",
|
||||||
|
"moy": "11.31",
|
||||||
|
"rang": "12",
|
||||||
|
"total": 16
|
||||||
|
},
|
||||||
|
"bonus": "00.00",
|
||||||
|
"malus": "00.00",
|
||||||
|
"capitalise": null,
|
||||||
|
"ressources": {
|
||||||
|
"R101": {
|
||||||
|
"id": 1,
|
||||||
|
"coef": 12.0,
|
||||||
|
"moyenne": "12.00"
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"saes": {
|
||||||
|
"SAE11": {
|
||||||
|
"id": 2,
|
||||||
|
"coef": 16.0,
|
||||||
|
"moyenne": "~"
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"ECTS": {
|
||||||
|
"acquis": 0.0,
|
||||||
|
"total": 12.0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"semestre": {
|
||||||
|
"etapes": [],
|
||||||
|
"date_debut": "2021-09-01",
|
||||||
|
"date_fin": "2022-08-31",
|
||||||
|
"annee_universitaire": "2021 - 2022",
|
||||||
|
"numero": 1,
|
||||||
|
"inscription": "",
|
||||||
|
"groupes": [],
|
||||||
|
"absences": {
|
||||||
|
"injustifie": 1,
|
||||||
|
"total": 2
|
||||||
|
},
|
||||||
|
"ECTS": {
|
||||||
|
"acquis": 0,
|
||||||
|
"total": 30.0
|
||||||
|
},
|
||||||
|
"notes": {
|
||||||
|
"value": "10.60",
|
||||||
|
"min": "02.40",
|
||||||
|
"moy": "11.05",
|
||||||
|
"max": "17.40"
|
||||||
|
},
|
||||||
|
"rang": {
|
||||||
|
"value": "10",
|
||||||
|
"total": 16
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
formsemestre = models.FormSemestre.query.filter_by(
|
||||||
|
id=formsemestre_id
|
||||||
|
).first_or_404()
|
||||||
|
|
||||||
|
dept = models.Departement.query.filter_by(id=formsemestre.dept_id).first_or_404()
|
||||||
|
|
||||||
|
app.set_sco_dept(dept.acronym)
|
||||||
|
|
||||||
|
# Récupération de l'étudiant
|
||||||
|
try:
|
||||||
|
etu = get_etu_from_etudid_or_nip_or_ine(etudid, nip, ine)
|
||||||
|
except AttributeError:
|
||||||
|
return error_response(
|
||||||
|
409,
|
||||||
|
message="La requête ne peut être traitée en l’état actuel.\n "
|
||||||
|
"Veuillez vérifier que l'id de l'étudiant (etudid, nip, ine) est valide",
|
||||||
|
)
|
||||||
|
|
||||||
|
return sco_bulletins.get_formsemestre_bulletin_etud_json(formsemestre, etu)
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route(
|
||||||
|
"/etudiant/etudid/<int:etudid>/semestre/<int:formsemestre_id>/groups",
|
||||||
|
methods=["GET"],
|
||||||
|
)
|
||||||
|
@bp.route(
|
||||||
|
"/etudiant/nip/<int:nip>/semestre/<int:formsemestre_id>/groups", methods=["GET"]
|
||||||
|
)
|
||||||
|
@bp.route(
|
||||||
|
"/etudiant/ine/<int:ine>/semestre/<int:formsemestre_id>/groups", methods=["GET"]
|
||||||
|
)
|
||||||
|
@token_permission_required(Permission.APIView)
|
||||||
|
def etudiant_groups(
|
||||||
|
formsemestre_id: int, etudid: int = None, nip: int = None, ine: int = None
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Retourne la liste des groupes auxquels appartient l'étudiant dans le semestre indiqué
|
||||||
|
|
||||||
|
formsemestre_id : l'id d'un formsemestre
|
||||||
|
etudid : l'etudid d'un étudiant
|
||||||
|
nip : le code nip d'un étudiant
|
||||||
|
ine : le code ine d'un étudiant
|
||||||
|
|
||||||
|
Exemple de résultat :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"partition_id": 1,
|
||||||
|
"id": 1,
|
||||||
|
"formsemestre_id": 1,
|
||||||
|
"partition_name": null,
|
||||||
|
"numero": 0,
|
||||||
|
"bul_show_rank": false,
|
||||||
|
"show_in_lists": true,
|
||||||
|
"group_id": 1,
|
||||||
|
"group_name": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"partition_id": 2,
|
||||||
|
"id": 2,
|
||||||
|
"formsemestre_id": 1,
|
||||||
|
"partition_name": "TD",
|
||||||
|
"numero": 1,
|
||||||
|
"bul_show_rank": false,
|
||||||
|
"show_in_lists": true,
|
||||||
|
"group_id": 2,
|
||||||
|
"group_name": "A"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
"""
|
||||||
|
if etudid is None:
|
||||||
|
etud = get_etu_from_etudid_or_nip_or_ine(etudid, nip, ine)
|
||||||
|
if etud is None:
|
||||||
|
return error_response(
|
||||||
|
409,
|
||||||
|
message="La requête ne peut être traitée en l’état actuel.\n "
|
||||||
|
"Veuillez vérifier que l'id de l'étudiant (etudid, nip, ine) est valide",
|
||||||
|
)
|
||||||
|
etudid = etud.etudid
|
||||||
|
|
||||||
|
# Récupération du formsemestre
|
||||||
|
sem = models.FormSemestre.query.filter_by(id=formsemestre_id).first_or_404()
|
||||||
|
dept = models.Departement.query.get(sem.dept_id)
|
||||||
|
app.set_sco_dept(dept.acronym)
|
||||||
|
data = sco_groups.get_etud_groups(etudid, sem.id)
|
||||||
|
|
||||||
|
return jsonify(data)
|
111
app/api/evaluations.py
Normal file
111
app/api/evaluations.py
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
############################################### Evaluations ###########################################################
|
||||||
|
from flask import jsonify
|
||||||
|
|
||||||
|
import app
|
||||||
|
|
||||||
|
from app import models
|
||||||
|
from app.api import bp
|
||||||
|
from app.api.auth import token_permission_required
|
||||||
|
from app.api.errors import error_response
|
||||||
|
from app.scodoc.sco_evaluation_db import do_evaluation_get_all_notes
|
||||||
|
from app.scodoc.sco_permissions import Permission
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route("/evaluations/<int:moduleimpl_id>", methods=["GET"])
|
||||||
|
@token_permission_required(Permission.APIView)
|
||||||
|
def evaluations(moduleimpl_id: int):
|
||||||
|
"""
|
||||||
|
Retourne la liste des évaluations à partir de l'id d'un moduleimpl
|
||||||
|
|
||||||
|
moduleimpl_id : l'id d'un moduleimpl
|
||||||
|
|
||||||
|
Exemple de résultat :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"moduleimpl_id": 1,
|
||||||
|
"jour": "20/04/2022",
|
||||||
|
"heure_debut": "08h00",
|
||||||
|
"description": "eval1",
|
||||||
|
"coefficient": 1.0,
|
||||||
|
"publish_incomplete": false,
|
||||||
|
"numero": 0,
|
||||||
|
"id": 1,
|
||||||
|
"heure_fin": "09h00",
|
||||||
|
"note_max": 20.0,
|
||||||
|
"visibulletin": true,
|
||||||
|
"evaluation_type": 0,
|
||||||
|
"evaluation_id": 1,
|
||||||
|
"jouriso": "2022-04-20",
|
||||||
|
"duree": "1h",
|
||||||
|
"descrheure": " de 08h00 \u00e0 09h00",
|
||||||
|
"matin": 1,
|
||||||
|
"apresmidi": 0
|
||||||
|
},
|
||||||
|
...
|
||||||
|
]
|
||||||
|
"""
|
||||||
|
# Récupération de toutes les évaluations
|
||||||
|
evals = models.Evaluation.query.filter_by(id=moduleimpl_id)
|
||||||
|
|
||||||
|
# Mise en forme des données
|
||||||
|
data = [d.to_dict() for d in evals]
|
||||||
|
|
||||||
|
return jsonify(data)
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route("/evaluations/eval_notes/<int:evaluation_id>", methods=["GET"])
|
||||||
|
@token_permission_required(Permission.APIView)
|
||||||
|
def evaluation_notes(evaluation_id: int):
|
||||||
|
"""
|
||||||
|
Retourne la liste des notes à partir de l'id d'une évaluation donnée
|
||||||
|
|
||||||
|
evaluation_id : l'id d'une évaluation
|
||||||
|
|
||||||
|
Exemple de résultat :
|
||||||
|
{
|
||||||
|
"1": {
|
||||||
|
"id": 1,
|
||||||
|
"etudid": 10,
|
||||||
|
"evaluation_id": 1,
|
||||||
|
"value": 15.0,
|
||||||
|
"comment": "",
|
||||||
|
"date": "Wed, 20 Apr 2022 06:49:05 GMT",
|
||||||
|
"uid": 2
|
||||||
|
},
|
||||||
|
"2": {
|
||||||
|
"id": 2,
|
||||||
|
"etudid": 1,
|
||||||
|
"evaluation_id": 1,
|
||||||
|
"value": 12.0,
|
||||||
|
"comment": "",
|
||||||
|
"date": "Wed, 20 Apr 2022 06:49:06 GMT",
|
||||||
|
"uid": 2
|
||||||
|
},
|
||||||
|
...
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
# Fonction utilisée : app.scodoc.sco_evaluation_db.do_evaluation_get_all_notes()
|
||||||
|
|
||||||
|
eval = models.Evaluation.query.filter_by(id=evaluation_id).first_or_404()
|
||||||
|
|
||||||
|
moduleimpl = models.ModuleImpl.query.filter_by(id=eval.moduleimpl_id).first_or_404()
|
||||||
|
|
||||||
|
formsemestre = models.FormSemestre.query.filter_by(
|
||||||
|
id=moduleimpl.formsemestre_id
|
||||||
|
).first_or_404()
|
||||||
|
|
||||||
|
dept = models.Departement.query.filter_by(id=formsemestre.dept_id).first_or_404()
|
||||||
|
|
||||||
|
app.set_sco_dept(dept.acronym)
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Utilisation de la fonction do_evaluation_get_all_notes
|
||||||
|
data = do_evaluation_get_all_notes(evaluation_id)
|
||||||
|
except AttributeError:
|
||||||
|
return error_response(
|
||||||
|
409,
|
||||||
|
message="La requête ne peut être traitée en l’état actuel. \n"
|
||||||
|
"Veillez vérifier la conformité du 'evaluation_id'",
|
||||||
|
)
|
||||||
|
|
||||||
|
return jsonify(data)
|
260
app/api/formations.py
Normal file
260
app/api/formations.py
Normal file
@ -0,0 +1,260 @@
|
|||||||
|
##############################################" Formations ############################################################
|
||||||
|
from flask import jsonify
|
||||||
|
|
||||||
|
from app import models
|
||||||
|
from app.api import bp
|
||||||
|
from app.api.errors import error_response
|
||||||
|
from app.api.auth import token_permission_required
|
||||||
|
from app.scodoc.sco_formations import formation_export
|
||||||
|
from app.scodoc.sco_permissions import Permission
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route("/formations", methods=["GET"])
|
||||||
|
@token_permission_required(Permission.APIView)
|
||||||
|
def formations():
|
||||||
|
"""
|
||||||
|
Retourne la liste des formations
|
||||||
|
|
||||||
|
Exemple de résultat :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"acronyme": "BUT R&T",
|
||||||
|
"titre_officiel": "Bachelor technologique r\u00e9seaux et t\u00e9l\u00e9communications",
|
||||||
|
"formation_code": "V1RET",
|
||||||
|
"code_specialite": null,
|
||||||
|
"dept_id": 1,
|
||||||
|
"titre": "BUT R&T",
|
||||||
|
"version": 1,
|
||||||
|
"type_parcours": 700,
|
||||||
|
"referentiel_competence_id": null,
|
||||||
|
"formation_id": 1
|
||||||
|
},
|
||||||
|
...
|
||||||
|
]
|
||||||
|
|
||||||
|
"""
|
||||||
|
# Récupération de toutes les formations
|
||||||
|
list_formations = models.Formation.query.all()
|
||||||
|
|
||||||
|
# Mise en forme des données
|
||||||
|
data = [d.to_dict() for d in list_formations]
|
||||||
|
|
||||||
|
return jsonify(data)
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route("/formations/<int:formation_id>", methods=["GET"])
|
||||||
|
@token_permission_required(Permission.APIView)
|
||||||
|
def formations_by_id(formation_id: int):
|
||||||
|
"""
|
||||||
|
Retourne une formation en fonction d'un id donné
|
||||||
|
|
||||||
|
formation_id : l'id d'une formation
|
||||||
|
|
||||||
|
Exemple de résultat :
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"acronyme": "BUT R&T",
|
||||||
|
"titre_officiel": "Bachelor technologique r\u00e9seaux et t\u00e9l\u00e9communications",
|
||||||
|
"formation_code": "V1RET",
|
||||||
|
"code_specialite": null,
|
||||||
|
"dept_id": 1,
|
||||||
|
"titre": "BUT R&T",
|
||||||
|
"version": 1,
|
||||||
|
"type_parcours": 700,
|
||||||
|
"referentiel_competence_id": null,
|
||||||
|
"formation_id": 1
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
# Récupération de la formation
|
||||||
|
forma = models.Formation.query.filter_by(id=formation_id).first_or_404()
|
||||||
|
|
||||||
|
# Mise en forme des données
|
||||||
|
data = forma.to_dict()
|
||||||
|
|
||||||
|
return jsonify(data)
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route("/formations/formation_export/<int:formation_id>", methods=["GET"])
|
||||||
|
@token_permission_required(Permission.APIView)
|
||||||
|
def formation_export_by_formation_id(formation_id: int, export_ids=False):
|
||||||
|
"""
|
||||||
|
Retourne la formation, avec UE, matières, modules
|
||||||
|
|
||||||
|
formation_id : l'id d'une formation
|
||||||
|
|
||||||
|
Exemple de résultat :
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"acronyme": "BUT R&T",
|
||||||
|
"titre_officiel": "Bachelor technologique r\u00e9seaux et t\u00e9l\u00e9communications",
|
||||||
|
"formation_code": "V1RET",
|
||||||
|
"code_specialite": null,
|
||||||
|
"dept_id": 1,
|
||||||
|
"titre": "BUT R&T",
|
||||||
|
"version": 1,
|
||||||
|
"type_parcours": 700,
|
||||||
|
"referentiel_competence_id": null,
|
||||||
|
"formation_id": 1,
|
||||||
|
"ue": [
|
||||||
|
{
|
||||||
|
"acronyme": "RT1.1",
|
||||||
|
"numero": 1,
|
||||||
|
"titre": "Administrer les r\u00e9seaux et l\u2019Internet",
|
||||||
|
"type": 0,
|
||||||
|
"ue_code": "UCOD11",
|
||||||
|
"ects": 12.0,
|
||||||
|
"is_external": false,
|
||||||
|
"code_apogee": "",
|
||||||
|
"coefficient": 0.0,
|
||||||
|
"semestre_idx": 1,
|
||||||
|
"color": "#B80004",
|
||||||
|
"reference": 1,
|
||||||
|
"matiere": [
|
||||||
|
{
|
||||||
|
"titre": "Administrer les r\u00e9seaux et l\u2019Internet",
|
||||||
|
"numero": 1,
|
||||||
|
"module": [
|
||||||
|
{
|
||||||
|
"titre": "Initiation aux r\u00e9seaux informatiques",
|
||||||
|
"abbrev": "Init aux r\u00e9seaux informatiques",
|
||||||
|
"code": "R101",
|
||||||
|
"heures_cours": 0.0,
|
||||||
|
"heures_td": 0.0,
|
||||||
|
"heures_tp": 0.0,
|
||||||
|
"coefficient": 1.0,
|
||||||
|
"ects": "",
|
||||||
|
"semestre_id": 1,
|
||||||
|
"numero": 10,
|
||||||
|
"code_apogee": "",
|
||||||
|
"module_type": 2,
|
||||||
|
"coefficients": [
|
||||||
|
{
|
||||||
|
"ue_reference": "1",
|
||||||
|
"coef": "12.0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ue_reference": "2",
|
||||||
|
"coef": "4.0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ue_reference": "3",
|
||||||
|
"coef": "4.0"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"titre": "Se sensibiliser \u00e0 l'hygi\u00e8ne informatique et \u00e0 la cybers\u00e9curit\u00e9",
|
||||||
|
"abbrev": "Hygi\u00e8ne informatique",
|
||||||
|
"code": "SAE11",
|
||||||
|
"heures_cours": 0.0,
|
||||||
|
"heures_td": 0.0,
|
||||||
|
"heures_tp": 0.0,
|
||||||
|
"coefficient": 1.0,
|
||||||
|
"ects": "",
|
||||||
|
"semestre_id": 1,
|
||||||
|
"numero": 10,
|
||||||
|
"code_apogee": "",
|
||||||
|
"module_type": 3,
|
||||||
|
"coefficients": [
|
||||||
|
{
|
||||||
|
"ue_reference": "1",
|
||||||
|
"coef": "16.0"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
...
|
||||||
|
]
|
||||||
|
},
|
||||||
|
...
|
||||||
|
]
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
"""
|
||||||
|
# Fonction utilité : app.scodoc.sco_formations.formation_export()
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Utilisation de la fonction formation_export
|
||||||
|
data = formation_export(formation_id)
|
||||||
|
except ValueError:
|
||||||
|
return error_response(
|
||||||
|
409,
|
||||||
|
message="La requête ne peut être traitée en l’état actuel. \n"
|
||||||
|
"Veillez vérifier la conformité du 'formation_id'",
|
||||||
|
)
|
||||||
|
|
||||||
|
return jsonify(data)
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route("/formations/moduleimpl/<int:moduleimpl_id>", methods=["GET"])
|
||||||
|
@token_permission_required(Permission.APIView)
|
||||||
|
def moduleimpls(moduleimpl_id: int):
|
||||||
|
"""
|
||||||
|
Retourne la liste des moduleimpl
|
||||||
|
|
||||||
|
moduleimpl_id : l'id d'un moduleimpl
|
||||||
|
"""
|
||||||
|
# Récupération des tous les moduleimpl
|
||||||
|
list_moduleimpls = models.ModuleImpl.query.filter_by(id=moduleimpl_id)
|
||||||
|
|
||||||
|
# Mise en forme des données
|
||||||
|
data = [moduleimpl.to_dict() for moduleimpl in list_moduleimpls]
|
||||||
|
|
||||||
|
return jsonify(data)
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route(
|
||||||
|
"/formations/moduleimpl/formsemestre/<int:formsemestre_id>/liste",
|
||||||
|
methods=["GET"],
|
||||||
|
) # XXX TODO penser à changer la route sur la doc
|
||||||
|
@token_permission_required(Permission.APIView)
|
||||||
|
def moduleimpls_sem(formsemestre_id: int):
|
||||||
|
"""
|
||||||
|
Retourne la liste des moduleimpl d'un semestre
|
||||||
|
|
||||||
|
formsemestre_id : l'id d'un formsemestre
|
||||||
|
|
||||||
|
Exemple d'utilisation :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"formsemestre_id": 1,
|
||||||
|
"computation_expr": null,
|
||||||
|
"module_id": 1,
|
||||||
|
"responsable_id": 2,
|
||||||
|
"module": {
|
||||||
|
"heures_tp": 0.0,
|
||||||
|
"code_apogee": "",
|
||||||
|
"titre": "Initiation aux r\u00e9seaux informatiques",
|
||||||
|
"coefficient": 1.0,
|
||||||
|
"module_type": 2,
|
||||||
|
"id": 1,
|
||||||
|
"ects": null,
|
||||||
|
"abbrev": "Init aux r\u00e9seaux informatiques",
|
||||||
|
"ue_id": 1,
|
||||||
|
"code": "R101",
|
||||||
|
"formation_id": 1,
|
||||||
|
"heures_cours": 0.0,
|
||||||
|
"matiere_id": 1,
|
||||||
|
"heures_td": 0.0,
|
||||||
|
"semestre_id": 1,
|
||||||
|
"numero": 10,
|
||||||
|
"module_id": 1
|
||||||
|
},
|
||||||
|
"moduleimpl_id": 1,
|
||||||
|
"ens": []
|
||||||
|
},
|
||||||
|
...
|
||||||
|
]
|
||||||
|
"""
|
||||||
|
formsemestre = models.FormSemestre.query.filter_by(
|
||||||
|
id=formsemestre_id
|
||||||
|
).first_or_404()
|
||||||
|
|
||||||
|
moduleimpls = formsemestre.modimpls_sorted
|
||||||
|
|
||||||
|
data = [moduleimpl.to_dict() for moduleimpl in moduleimpls]
|
||||||
|
|
||||||
|
return jsonify(data)
|
472
app/api/formsemestres.py
Normal file
472
app/api/formsemestres.py
Normal file
@ -0,0 +1,472 @@
|
|||||||
|
########################################## Formsemestres ##############################################################
|
||||||
|
from flask import jsonify
|
||||||
|
|
||||||
|
import app
|
||||||
|
from app import models
|
||||||
|
from app.api import bp
|
||||||
|
from app.api.errors import error_response
|
||||||
|
from app.api.auth import token_permission_required
|
||||||
|
from app.api.tools import get_etu_from_etudid_or_nip_or_ine
|
||||||
|
from app.models import FormSemestre, FormSemestreEtape
|
||||||
|
from app.scodoc.sco_bulletins import get_formsemestre_bulletin_etud_json
|
||||||
|
from app.scodoc.sco_bulletins_json import make_json_formsemestre_bulletinetud
|
||||||
|
from app.scodoc.sco_permissions import Permission
|
||||||
|
from app.scodoc.sco_pvjury import formsemestre_pvjury
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route("/formsemestre/<int:formsemestre_id>", methods=["GET"])
|
||||||
|
@token_permission_required(Permission.APIView)
|
||||||
|
def formsemestre(formsemestre_id: int):
|
||||||
|
"""
|
||||||
|
Retourne l'information sur le formsemestre correspondant au formsemestre_id
|
||||||
|
|
||||||
|
formsemestre_id : l'id d'un formsemestre
|
||||||
|
|
||||||
|
Exemple de résultat :
|
||||||
|
{
|
||||||
|
"date_fin": "31/08/2022",
|
||||||
|
"resp_can_edit": false,
|
||||||
|
"dept_id": 1,
|
||||||
|
"etat": true,
|
||||||
|
"resp_can_change_ens": true,
|
||||||
|
"id": 1,
|
||||||
|
"modalite": "FI",
|
||||||
|
"ens_can_edit_eval": false,
|
||||||
|
"formation_id": 1,
|
||||||
|
"gestion_compensation": false,
|
||||||
|
"elt_sem_apo": null,
|
||||||
|
"semestre_id": 1,
|
||||||
|
"bul_hide_xml": false,
|
||||||
|
"elt_annee_apo": null,
|
||||||
|
"titre": "Semestre test",
|
||||||
|
"block_moyennes": false,
|
||||||
|
"scodoc7_id": null,
|
||||||
|
"date_debut": "01/09/2021",
|
||||||
|
"gestion_semestrielle": false,
|
||||||
|
"bul_bgcolor": "white",
|
||||||
|
"formsemestre_id": 1,
|
||||||
|
"titre_num": "Semestre test semestre 1",
|
||||||
|
"date_debut_iso": "2021-09-01",
|
||||||
|
"date_fin_iso": "2022-08-31",
|
||||||
|
"responsables": []
|
||||||
|
}
|
||||||
|
|
||||||
|
"""
|
||||||
|
# Récupération de tous les formsemestres
|
||||||
|
formsemetre = models.FormSemestre.query.filter_by(id=formsemestre_id).first_or_404()
|
||||||
|
|
||||||
|
# Mise en forme des données
|
||||||
|
data = formsemetre.to_dict()
|
||||||
|
|
||||||
|
return jsonify(data)
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route("/formsemestre/apo/<string:etape_apo>", methods=["GET"])
|
||||||
|
@token_permission_required(Permission.APIView)
|
||||||
|
def formsemestre_apo(etape_apo: str):
|
||||||
|
"""
|
||||||
|
Retourne les informations sur les formsemestres
|
||||||
|
|
||||||
|
etape_apo : l'id d'une étape apogée
|
||||||
|
"""
|
||||||
|
formsemestres = FormSemestre.query.filter(
|
||||||
|
FormSemestreEtape.etape_apo == etape_apo,
|
||||||
|
FormSemestreEtape.formsemestre_id == FormSemestre.id,
|
||||||
|
)
|
||||||
|
|
||||||
|
return jsonify([formsemestre.to_dict() for formsemestre in formsemestres])
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route(
|
||||||
|
"/formsemestre/<int:formsemestre_id>/departements/<string:dept>/etudiant/etudid/<int:etudid>/bulletin",
|
||||||
|
methods=["GET"],
|
||||||
|
)
|
||||||
|
@bp.route(
|
||||||
|
"/formsemestre/<int:formsemestre_id>/departements/<string:dept>/etudiant/nip/<int:nip>/bulletin",
|
||||||
|
methods=["GET"],
|
||||||
|
)
|
||||||
|
@bp.route(
|
||||||
|
"/formsemestre/<int:formsemestre_id>/departements/<string:dept>/etudiant/ine/<int:ine>/bulletin",
|
||||||
|
methods=["GET"],
|
||||||
|
)
|
||||||
|
@token_permission_required(Permission.APIView)
|
||||||
|
def etudiant_bulletin(
|
||||||
|
formsemestre_id,
|
||||||
|
dept,
|
||||||
|
etudid: int = None,
|
||||||
|
nip: int = None,
|
||||||
|
ine: int = None,
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Retourne le bulletin de note d'un étudiant
|
||||||
|
|
||||||
|
formsemestre_id : l'id d'un formsemestre
|
||||||
|
etudid : l'etudid d'un étudiant
|
||||||
|
nip : le code nip d'un étudiant
|
||||||
|
ine : le code ine d'un étudiant
|
||||||
|
|
||||||
|
Exemple de résultat :
|
||||||
|
{
|
||||||
|
"etudid":1,
|
||||||
|
"formsemestre_id":1,
|
||||||
|
"date":"2022-04-27T10:44:47.448094",
|
||||||
|
"publie":true,
|
||||||
|
"etapes":[
|
||||||
|
|
||||||
|
],
|
||||||
|
"etudiant":{
|
||||||
|
"etudid":1,
|
||||||
|
"code_nip":"1",
|
||||||
|
"code_ine":"1",
|
||||||
|
"nom":"COSTA",
|
||||||
|
"prenom":"Sacha",
|
||||||
|
"civilite":"",
|
||||||
|
"photo_url":"/ScoDoc/TAPI/Scolarite/get_photo_image?etudid=1&size=small",
|
||||||
|
"email":"SACHA.COSTA@example.com",
|
||||||
|
"emailperso":"",
|
||||||
|
"sexe":""
|
||||||
|
},
|
||||||
|
"note":{
|
||||||
|
"value":"10.60",
|
||||||
|
"min":"-",
|
||||||
|
"max":"-",
|
||||||
|
"moy":"-"
|
||||||
|
},
|
||||||
|
"rang":{
|
||||||
|
"value":"10",
|
||||||
|
"ninscrits":16
|
||||||
|
},
|
||||||
|
"rang_group":[
|
||||||
|
{
|
||||||
|
"group_type":"TD",
|
||||||
|
"group_name":"",
|
||||||
|
"value":"",
|
||||||
|
"ninscrits":""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"note_max":{
|
||||||
|
"value":20
|
||||||
|
},
|
||||||
|
"bonus_sport_culture":{
|
||||||
|
"value":0.0
|
||||||
|
},
|
||||||
|
"ue":[
|
||||||
|
{
|
||||||
|
"id":1,
|
||||||
|
"numero":"1",
|
||||||
|
"acronyme":"RT1.1",
|
||||||
|
"titre":"Administrer les r\u00e9seaux et l\u2019Internet",
|
||||||
|
"note":{
|
||||||
|
"value":"08.50",
|
||||||
|
"min":"06.00",
|
||||||
|
"max":"16.50",
|
||||||
|
"moy":"11.31"
|
||||||
|
},
|
||||||
|
"rang":"12",
|
||||||
|
"effectif":16,
|
||||||
|
"ects":"12",
|
||||||
|
"code_apogee":"",
|
||||||
|
"module":[
|
||||||
|
{
|
||||||
|
"id":1,
|
||||||
|
"code":"R101",
|
||||||
|
"coefficient":1.0,
|
||||||
|
"numero":10,
|
||||||
|
"titre":"Initiation aux r\u00e9seaux informatiques",
|
||||||
|
"abbrev":"Init aux r\u00e9seaux informatiques",
|
||||||
|
"note":{
|
||||||
|
"value":"12.00",
|
||||||
|
"moy":"-",
|
||||||
|
"max":"-",
|
||||||
|
"min":"-",
|
||||||
|
"nb_notes":"-",
|
||||||
|
"nb_missing":"-",
|
||||||
|
"nb_valid_evals":"-"
|
||||||
|
},
|
||||||
|
"code_apogee":"",
|
||||||
|
"evaluation":[
|
||||||
|
{
|
||||||
|
"jour":"2022-04-20",
|
||||||
|
"heure_debut":"08:00:00",
|
||||||
|
"heure_fin":"09:00:00",
|
||||||
|
"coefficient":1.0,
|
||||||
|
"evaluation_type":0,
|
||||||
|
"evaluation_id":1,
|
||||||
|
"description":"eval1",
|
||||||
|
"note":"12.00"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
...
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ue_capitalisee":[],
|
||||||
|
"absences":{
|
||||||
|
"nbabs":2,
|
||||||
|
"nbabsjust":1
|
||||||
|
},
|
||||||
|
"appreciation":[]
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
# Fonction utilisée : app.scodoc.sco_bulletins_json.make_json_formsemestre_bulletinetud()
|
||||||
|
|
||||||
|
try:
|
||||||
|
app.set_sco_dept(dept)
|
||||||
|
except:
|
||||||
|
return error_response(
|
||||||
|
409,
|
||||||
|
message="La requête ne peut être traitée en l’état actuel.\n "
|
||||||
|
"Veilliez vérifier que le nom de département est valide",
|
||||||
|
)
|
||||||
|
if etudid is None:
|
||||||
|
# Récupération de l'étudiant
|
||||||
|
try:
|
||||||
|
etu = get_etu_from_etudid_or_nip_or_ine(etudid, nip, ine)
|
||||||
|
etudid = etu.etudid
|
||||||
|
except AttributeError:
|
||||||
|
return error_response(
|
||||||
|
409,
|
||||||
|
message="La requête ne peut être traitée en l’état actuel.\n "
|
||||||
|
"Veilliez vérifier que l'id de l'étudiant (etudid, nip, ine) est valide",
|
||||||
|
)
|
||||||
|
|
||||||
|
data = make_json_formsemestre_bulletinetud(formsemestre_id, etudid)
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route("/formsemestre/<int:formsemestre_id>/bulletins", methods=["GET"])
|
||||||
|
@token_permission_required(Permission.APIView)
|
||||||
|
def bulletins(formsemestre_id: int):
|
||||||
|
"""
|
||||||
|
Retourne les bulletins d'un formsemestre donné
|
||||||
|
|
||||||
|
formsemestre_id : l'id d'un formesemestre
|
||||||
|
|
||||||
|
Exemple de résultat :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"version": "0",
|
||||||
|
"type": "BUT",
|
||||||
|
"date": "2022-04-27T07:18:16.450634Z",
|
||||||
|
"publie": true,
|
||||||
|
"etudiant": {
|
||||||
|
"civilite": "X",
|
||||||
|
"code_ine": "1",
|
||||||
|
"code_nip": "1",
|
||||||
|
"date_naissance": "",
|
||||||
|
"email": "SACHA.COSTA@example.com",
|
||||||
|
"emailperso": "",
|
||||||
|
"etudid": 1,
|
||||||
|
"nom": "COSTA",
|
||||||
|
"prenom": "SACHA",
|
||||||
|
"nomprenom": "Sacha COSTA",
|
||||||
|
"lieu_naissance": "",
|
||||||
|
"dept_naissance": "",
|
||||||
|
"nationalite": "",
|
||||||
|
"boursier": "",
|
||||||
|
"fiche_url": "/ScoDoc/TAPI/Scolarite/ficheEtud?etudid=1",
|
||||||
|
"photo_url": "/ScoDoc/TAPI/Scolarite/get_photo_image?etudid=1&size=small",
|
||||||
|
"id": 1,
|
||||||
|
"codepostaldomicile": "",
|
||||||
|
"paysdomicile": "",
|
||||||
|
"telephonemobile": "",
|
||||||
|
"typeadresse": "domicile",
|
||||||
|
"domicile": "",
|
||||||
|
"villedomicile": "",
|
||||||
|
"telephone": "",
|
||||||
|
"fax": "",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"formation": {
|
||||||
|
"id": 1,
|
||||||
|
"acronyme": "BUT R&T",
|
||||||
|
"titre_officiel": "Bachelor technologique r\u00e9seaux et t\u00e9l\u00e9communications",
|
||||||
|
"titre": "BUT R&T"
|
||||||
|
},
|
||||||
|
"formsemestre_id": 1,
|
||||||
|
"etat_inscription": "I",
|
||||||
|
"options": {
|
||||||
|
"show_abs": true,
|
||||||
|
"show_abs_modules": false,
|
||||||
|
"show_ects": true,
|
||||||
|
"show_codemodules": false,
|
||||||
|
"show_matieres": false,
|
||||||
|
"show_rangs": true,
|
||||||
|
"show_ue_rangs": true,
|
||||||
|
"show_mod_rangs": true,
|
||||||
|
"show_moypromo": false,
|
||||||
|
"show_minmax": false,
|
||||||
|
"show_minmax_mod": false,
|
||||||
|
"show_minmax_eval": false,
|
||||||
|
"show_coef": true,
|
||||||
|
"show_ue_cap_details": false,
|
||||||
|
"show_ue_cap_current": true,
|
||||||
|
"show_temporary": true,
|
||||||
|
"temporary_txt": "Provisoire",
|
||||||
|
"show_uevalid": true,
|
||||||
|
"show_date_inscr": true
|
||||||
|
},
|
||||||
|
"ressources": {
|
||||||
|
"R101": {
|
||||||
|
"id": 1,
|
||||||
|
"titre": "Initiation aux r\u00e9seaux informatiques",
|
||||||
|
"code_apogee": null,
|
||||||
|
"url": "/ScoDoc/TAPI/Scolarite/Notes/moduleimpl_status?moduleimpl_id=1",
|
||||||
|
"moyenne": {},
|
||||||
|
"evaluations": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"description": "eval1",
|
||||||
|
"date": "2022-04-20",
|
||||||
|
"heure_debut": "08:00",
|
||||||
|
"heure_fin": "09:00",
|
||||||
|
"coef": "01.00",
|
||||||
|
"poids": {
|
||||||
|
"RT1.1": 1.0,
|
||||||
|
},
|
||||||
|
"note": {
|
||||||
|
"value": "12.00",
|
||||||
|
"min": "00.00",
|
||||||
|
"max": "18.00",
|
||||||
|
"moy": "10.88"
|
||||||
|
},
|
||||||
|
"url": "/ScoDoc/TAPI/Scolarite/Notes/evaluation_listenotes?evaluation_id=1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"saes": {
|
||||||
|
"SAE11": {
|
||||||
|
"id": 2,
|
||||||
|
"titre": "Se sensibiliser \u00e0 l'hygi\u00e8ne informatique et \u00e0 la cybers\u00e9curit\u00e9",
|
||||||
|
"code_apogee": null,
|
||||||
|
"url": "/ScoDoc/TAPI/Scolarite/Notes/moduleimpl_status?moduleimpl_id=2",
|
||||||
|
"moyenne": {},
|
||||||
|
"evaluations": []
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"ues": {
|
||||||
|
"RT1.1": {
|
||||||
|
"id": 1,
|
||||||
|
"titre": "Administrer les r\u00e9seaux et l\u2019Internet",
|
||||||
|
"numero": 1,
|
||||||
|
"type": 0,
|
||||||
|
"color": "#B80004",
|
||||||
|
"competence": null,
|
||||||
|
"moyenne": {
|
||||||
|
"value": "08.50",
|
||||||
|
"min": "06.00",
|
||||||
|
"max": "16.50",
|
||||||
|
"moy": "11.31",
|
||||||
|
"rang": "12",
|
||||||
|
"total": 16
|
||||||
|
},
|
||||||
|
"bonus": "00.00",
|
||||||
|
"malus": "00.00",
|
||||||
|
"capitalise": null,
|
||||||
|
"ressources": {
|
||||||
|
"R101": {
|
||||||
|
"id": 1,
|
||||||
|
"coef": 12.0,
|
||||||
|
"moyenne": "12.00"
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"saes": {
|
||||||
|
"SAE11": {
|
||||||
|
"id": 2,
|
||||||
|
"coef": 16.0,
|
||||||
|
"moyenne": "~"
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"ECTS": {
|
||||||
|
"acquis": 0.0,
|
||||||
|
"total": 12.0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"semestre": {
|
||||||
|
"etapes": [],
|
||||||
|
"date_debut": "2021-09-01",
|
||||||
|
"date_fin": "2022-08-31",
|
||||||
|
"annee_universitaire": "2021 - 2022",
|
||||||
|
"numero": 1,
|
||||||
|
"inscription": "",
|
||||||
|
"groupes": [],
|
||||||
|
"absences": {
|
||||||
|
"injustifie": 1,
|
||||||
|
"total": 2
|
||||||
|
},
|
||||||
|
"ECTS": {
|
||||||
|
"acquis": 0,
|
||||||
|
"total": 30.0
|
||||||
|
},
|
||||||
|
"notes": {
|
||||||
|
"value": "10.60",
|
||||||
|
"min": "02.40",
|
||||||
|
"moy": "11.05",
|
||||||
|
"max": "17.40"
|
||||||
|
},
|
||||||
|
"rang": {
|
||||||
|
"value": "10",
|
||||||
|
"total": 16
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
...
|
||||||
|
]
|
||||||
|
"""
|
||||||
|
# Fonction utilisée : app.scodoc.sco_bulletins.get_formsemestre_bulletin_etud_json()
|
||||||
|
|
||||||
|
formsemestre = models.FormSemestre.query.filter_by(
|
||||||
|
id=formsemestre_id
|
||||||
|
).first_or_404()
|
||||||
|
|
||||||
|
dept = models.Departement.query.filter_by(id=formsemestre.dept_id).first_or_404()
|
||||||
|
|
||||||
|
app.set_sco_dept(dept.acronym)
|
||||||
|
|
||||||
|
etuds = formsemestre.etuds
|
||||||
|
|
||||||
|
data = []
|
||||||
|
for etu in etuds:
|
||||||
|
bul_etu = get_formsemestre_bulletin_etud_json(formsemestre, etu)
|
||||||
|
data.append(bul_etu.json)
|
||||||
|
|
||||||
|
return jsonify(data)
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route("/formsemestre/<int:formsemestre_id>/jury", methods=["GET"])
|
||||||
|
@token_permission_required(Permission.APIView)
|
||||||
|
def jury(formsemestre_id: int):
|
||||||
|
"""
|
||||||
|
Retourne le récapitulatif des décisions jury
|
||||||
|
|
||||||
|
formsemestre_id : l'id d'un formsemestre
|
||||||
|
|
||||||
|
Exemple de résultat :
|
||||||
|
|
||||||
|
"""
|
||||||
|
# Fonction utilisée : app.scodoc.sco_pvjury.formsemestre_pvjury()
|
||||||
|
|
||||||
|
formsemestre = models.FormSemestre.query.filter_by(
|
||||||
|
id=formsemestre_id
|
||||||
|
).first_or_404()
|
||||||
|
|
||||||
|
dept = models.Departement.query.filter_by(id=formsemestre.dept_id).first_or_404()
|
||||||
|
|
||||||
|
app.set_sco_dept(dept.acronym)
|
||||||
|
|
||||||
|
data = formsemestre_pvjury(formsemestre_id)
|
||||||
|
|
||||||
|
# try:
|
||||||
|
# # Utilisation de la fonction formsemestre_pvjury
|
||||||
|
# data = formsemestre_pvjury(formsemestre_id)
|
||||||
|
# except AttributeError:
|
||||||
|
# return error_response(
|
||||||
|
# 409,
|
||||||
|
# message="La requête ne peut être traitée en l’état actuel. \n"
|
||||||
|
# "Veillez vérifier la conformité du 'formation_id'",
|
||||||
|
# )
|
||||||
|
|
||||||
|
return jsonify(data)
|
41
app/api/jury.py
Normal file
41
app/api/jury.py
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
#################################################### Jury #############################################################
|
||||||
|
from flask import jsonify
|
||||||
|
|
||||||
|
from app import models
|
||||||
|
from app.api import bp
|
||||||
|
from app.api.errors import error_response
|
||||||
|
from app.api.auth import token_permission_required
|
||||||
|
from app.scodoc.sco_prepajury import feuille_preparation_jury
|
||||||
|
from app.scodoc.sco_pvjury import formsemestre_pvjury
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route("/jury/formsemestre/<int:formsemestre_id>/preparation_jury", methods=["GET"])
|
||||||
|
# @token_permission_required(Permission.?)
|
||||||
|
def jury_preparation(formsemestre_id: int):
|
||||||
|
"""
|
||||||
|
Retourne la feuille de préparation du jury
|
||||||
|
|
||||||
|
formsemestre_id : l'id d'un formsemestre
|
||||||
|
"""
|
||||||
|
# Fonction utilisée : app.scodoc.sco_prepajury.feuille_preparation_jury()
|
||||||
|
|
||||||
|
# Utilisation de la fonction feuille_preparation_jury
|
||||||
|
prepa_jury = feuille_preparation_jury(formsemestre_id)
|
||||||
|
|
||||||
|
return error_response(501, message="Not implemented")
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route("/jury/formsemestre/<int:formsemestre_id>/decisions_jury", methods=["GET"])
|
||||||
|
# @token_permission_required(Permission.?)
|
||||||
|
def jury_decisions(formsemestre_id: int):
|
||||||
|
"""
|
||||||
|
Retourne les décisions du jury suivant un formsemestre donné
|
||||||
|
|
||||||
|
formsemestre_id : l'id d'un formsemestre
|
||||||
|
"""
|
||||||
|
# Fonction utilisée : app.scodoc.sco_pvjury.formsemestre_pvjury()
|
||||||
|
|
||||||
|
# Utilisation de la fonction formsemestre_pvjury
|
||||||
|
decision_jury = formsemestre_pvjury(formsemestre_id)
|
||||||
|
|
||||||
|
return error_response(501, message="Not implemented")
|
@ -36,13 +36,15 @@ from app.api import bp
|
|||||||
from app.api import requested_format
|
from app.api import requested_format
|
||||||
from app.api.auth import token_auth
|
from app.api.auth import token_auth
|
||||||
from app.api.errors import error_response
|
from app.api.errors import error_response
|
||||||
|
from app.decorators import permission_required
|
||||||
from app.models import Departement
|
from app.models import Departement
|
||||||
from app.scodoc.sco_logos import list_logos, find_logo
|
from app.scodoc.sco_logos import list_logos, find_logo
|
||||||
|
from app.api.auth import token_auth, token_permission_required
|
||||||
from app.scodoc.sco_permissions import Permission
|
from app.scodoc.sco_permissions import Permission
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/logos", methods=["GET"])
|
@bp.route("/logos", methods=["GET"])
|
||||||
@token_auth.login_required
|
@token_permission_required(Permission.APIView)
|
||||||
def api_get_glob_logos():
|
def api_get_glob_logos():
|
||||||
if not g.current_user.has_permission(Permission.ScoSuperAdmin, None):
|
if not g.current_user.has_permission(Permission.ScoSuperAdmin, None):
|
||||||
return error_response(401, message="accès interdit")
|
return error_response(401, message="accès interdit")
|
||||||
@ -54,7 +56,7 @@ def api_get_glob_logos():
|
|||||||
|
|
||||||
|
|
||||||
@bp.route("/logos/<string:logoname>", methods=["GET"])
|
@bp.route("/logos/<string:logoname>", methods=["GET"])
|
||||||
@token_auth.login_required
|
@token_permission_required(Permission.APIView)
|
||||||
def api_get_glob_logo(logoname):
|
def api_get_glob_logo(logoname):
|
||||||
if not g.current_user.has_permission(Permission.ScoSuperAdmin, None):
|
if not g.current_user.has_permission(Permission.ScoSuperAdmin, None):
|
||||||
return error_response(401, message="accès interdit")
|
return error_response(401, message="accès interdit")
|
||||||
@ -70,7 +72,7 @@ def api_get_glob_logo(logoname):
|
|||||||
|
|
||||||
|
|
||||||
@bp.route("/departements/<string:departement>/logos", methods=["GET"])
|
@bp.route("/departements/<string:departement>/logos", methods=["GET"])
|
||||||
@token_auth.login_required
|
@token_permission_required(Permission.APIView)
|
||||||
def api_get_local_logos(departement):
|
def api_get_local_logos(departement):
|
||||||
dept_id = Departement.from_acronym(departement).id
|
dept_id = Departement.from_acronym(departement).id
|
||||||
if not g.current_user.has_permission(Permission.ScoChangePreferences, departement):
|
if not g.current_user.has_permission(Permission.ScoChangePreferences, departement):
|
||||||
@ -80,7 +82,7 @@ def api_get_local_logos(departement):
|
|||||||
|
|
||||||
|
|
||||||
@bp.route("/departements/<string:departement>/logos/<string:logoname>", methods=["GET"])
|
@bp.route("/departements/<string:departement>/logos/<string:logoname>", methods=["GET"])
|
||||||
@token_auth.login_required
|
@token_permission_required(Permission.APIView)
|
||||||
def api_get_local_logo(departement, logoname):
|
def api_get_local_logo(departement, logoname):
|
||||||
# format = requested_format("jpg", ['png', 'jpg']) XXX ?
|
# format = requested_format("jpg", ['png', 'jpg']) XXX ?
|
||||||
dept_id = Departement.from_acronym(departement).id
|
dept_id = Departement.from_acronym(departement).id
|
||||||
|
150
app/api/partitions.py
Normal file
150
app/api/partitions.py
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
############################################### Partitions ############################################################
|
||||||
|
from flask import jsonify
|
||||||
|
|
||||||
|
from app import models
|
||||||
|
from app.api import bp
|
||||||
|
|
||||||
|
from app.api.errors import error_response
|
||||||
|
from app.api.auth import token_permission_required
|
||||||
|
from app.scodoc.sco_groups import get_group_members, setGroups, get_partitions_list
|
||||||
|
from app.scodoc.sco_permissions import Permission
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route("/partitions/<int:formsemestre_id>", methods=["GET"])
|
||||||
|
@token_permission_required(Permission.APIView)
|
||||||
|
def partition(formsemestre_id: int):
|
||||||
|
"""
|
||||||
|
Retourne la liste de toutes les partitions d'un formsemestre
|
||||||
|
|
||||||
|
formsemestre_id : l'id d'un formsemestre
|
||||||
|
|
||||||
|
Exemple de résultat :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"partition_id": 2,
|
||||||
|
"id": 2,
|
||||||
|
"formsemestre_id": 1,
|
||||||
|
"partition_name": "TD",
|
||||||
|
"numero": 1,
|
||||||
|
"bul_show_rank": false,
|
||||||
|
"show_in_lists": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"partition_id": 1,
|
||||||
|
"id": 1,
|
||||||
|
"formsemestre_id": 1,
|
||||||
|
"partition_name": null,
|
||||||
|
"numero": 0,
|
||||||
|
"bul_show_rank": false,
|
||||||
|
"show_in_lists": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
"""
|
||||||
|
# # Récupération de toutes les partitions
|
||||||
|
# partitions = models.Partition.query.filter_by(id=formsemestre_id)
|
||||||
|
#
|
||||||
|
# # Mise en forme des données
|
||||||
|
# data = [partition.to_dict() for partition in partitions]
|
||||||
|
|
||||||
|
data = get_partitions_list(formsemestre_id)
|
||||||
|
|
||||||
|
return jsonify(data)
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route("/partitions/groups/<int:group_id>", methods=["GET"])
|
||||||
|
@bp.route("/partitions/groups/<int:group_id>/etat/<string:etat>", methods=["GET"])
|
||||||
|
@token_permission_required(Permission.APIView)
|
||||||
|
def etud_in_group(group_id: int, etat=None):
|
||||||
|
"""
|
||||||
|
Retourne la liste des étudiants dans un groupe
|
||||||
|
|
||||||
|
group_id : l'id d'un groupe
|
||||||
|
etat : état de l'inscription
|
||||||
|
|
||||||
|
Exemple de résultat :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"etudid": 10,
|
||||||
|
"id": 10,
|
||||||
|
"dept_id": 1,
|
||||||
|
"nom": "BOUTET",
|
||||||
|
"prenom": "Marguerite",
|
||||||
|
"nom_usuel": "",
|
||||||
|
"civilite": "F",
|
||||||
|
"date_naissance": null,
|
||||||
|
"lieu_naissance": null,
|
||||||
|
"dept_naissance": null,
|
||||||
|
"nationalite": null,
|
||||||
|
"statut": null,
|
||||||
|
"boursier": null,
|
||||||
|
"photo_filename": null,
|
||||||
|
"code_nip": "10",
|
||||||
|
"code_ine": "10",
|
||||||
|
"scodoc7_id": null,
|
||||||
|
"email": "MARGUERITE.BOUTET@example.com",
|
||||||
|
"emailperso": null,
|
||||||
|
"domicile": null,
|
||||||
|
"codepostaldomicile": null,
|
||||||
|
"villedomicile": null,
|
||||||
|
"paysdomicile": null,
|
||||||
|
"telephone": null,
|
||||||
|
"telephonemobile": null,
|
||||||
|
"fax": null,
|
||||||
|
"typeadresse": "domicile",
|
||||||
|
"description": null,
|
||||||
|
"group_id": 1,
|
||||||
|
"etat": "I",
|
||||||
|
"civilite_str": "Mme",
|
||||||
|
"nom_disp": "BOUTET",
|
||||||
|
"nomprenom": "Mme Marguerite BOUTET",
|
||||||
|
"ne": "e",
|
||||||
|
"email_default": "MARGUERITE.BOUTET@example.com"
|
||||||
|
},
|
||||||
|
...
|
||||||
|
]
|
||||||
|
"""
|
||||||
|
# Fonction utilisée : app.scodoc.sco_groups.get_group_members()
|
||||||
|
|
||||||
|
if etat is None:
|
||||||
|
data = get_group_members(group_id)
|
||||||
|
else:
|
||||||
|
data = get_group_members(group_id, etat)
|
||||||
|
|
||||||
|
if len(data) == 0:
|
||||||
|
return error_response(
|
||||||
|
409,
|
||||||
|
message="La requête ne peut être traitée en l’état actuel. \n"
|
||||||
|
"Aucun groupe ne correspond au 'group_id' renseigné",
|
||||||
|
)
|
||||||
|
|
||||||
|
return jsonify(data)
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route(
|
||||||
|
"/partitions/set_groups?partition_id=<int:partition_id>&groups_lists=<int:groups_lists>&"
|
||||||
|
"groups_to_create=<int:groups_to_create>&groups_to_delete=<int:groups_to_delete>",
|
||||||
|
methods=["POST"],
|
||||||
|
)
|
||||||
|
@token_permission_required(Permission.APIEtudChangeGroups)
|
||||||
|
def set_groups(
|
||||||
|
partition_id: int, groups_lists: int, groups_to_delete: int, groups_to_create: int
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Set les groups
|
||||||
|
|
||||||
|
partition_id : l'id d'une partition
|
||||||
|
groups_lists : membres de chaque groupe existant
|
||||||
|
groups_ti_delete : les groupes à supprimer
|
||||||
|
groups_to_create : les groupes à créer
|
||||||
|
"""
|
||||||
|
# Fonction utilisée : app.scodoc.sco_groups.setGroups()
|
||||||
|
try:
|
||||||
|
# Utilisation de la fonction setGroups
|
||||||
|
setGroups(partition_id, groups_lists, groups_to_create, groups_to_delete)
|
||||||
|
return error_response(200, message="Groups set")
|
||||||
|
except ValueError:
|
||||||
|
return error_response(
|
||||||
|
409,
|
||||||
|
message="La requête ne peut être traitée en l’état actuel. \n"
|
||||||
|
"Veillez vérifier la conformité des éléments passé en paramètres",
|
||||||
|
)
|
253
app/api/remiser.py
Normal file
253
app/api/remiser.py
Normal file
@ -0,0 +1,253 @@
|
|||||||
|
# @bp.route("/etudiants", methods=["GET"])
|
||||||
|
# @token_permission_required(Permission.APIView)
|
||||||
|
# def etudiants():
|
||||||
|
# """
|
||||||
|
# Retourne la liste de tous les étudiants
|
||||||
|
#
|
||||||
|
# Exemple de résultat :
|
||||||
|
# {
|
||||||
|
# "civilite": "X",
|
||||||
|
# "code_ine": null,
|
||||||
|
# "code_nip": null,
|
||||||
|
# "date_naissance": null,
|
||||||
|
# "email": null,
|
||||||
|
# "emailperso": null,
|
||||||
|
# "etudid": 18,
|
||||||
|
# "nom": "MOREL",
|
||||||
|
# "prenom": "JACQUES"
|
||||||
|
# },
|
||||||
|
# {
|
||||||
|
# "civilite": "X",
|
||||||
|
# "code_ine": null,
|
||||||
|
# "code_nip": null,
|
||||||
|
# "date_naissance": null,
|
||||||
|
# "email": null,
|
||||||
|
# "emailperso": null,
|
||||||
|
# "etudid": 19,
|
||||||
|
# "nom": "FOURNIER",
|
||||||
|
# "prenom": "ANNE"
|
||||||
|
# },
|
||||||
|
# ...
|
||||||
|
# """
|
||||||
|
# # Récupération de tous les étudiants
|
||||||
|
# etu = models.Identite.query.all()
|
||||||
|
#
|
||||||
|
# # Mise en forme des données
|
||||||
|
# data = [d.to_dict_bul(include_urls=False) for d in etu]
|
||||||
|
#
|
||||||
|
# return jsonify(data)
|
||||||
|
|
||||||
|
|
||||||
|
# @bp.route(
|
||||||
|
# "/evaluations/eval_set_notes?eval_id=<int:eval_id>&etudid=<int:etudid>¬e=<float:note>",
|
||||||
|
# methods=["POST"],
|
||||||
|
# )
|
||||||
|
# @bp.route(
|
||||||
|
# "/evaluations/eval_set_notes?eval_id=<int:eval_id>&nip=<int:nip>¬e=<float:note>",
|
||||||
|
# methods=["POST"],
|
||||||
|
# )
|
||||||
|
# @bp.route(
|
||||||
|
# "/evaluations/eval_set_notes?eval_id=<int:eval_id>&ine=<int:ine>¬e=<float:note>",
|
||||||
|
# methods=["POST"],
|
||||||
|
# )
|
||||||
|
# @token_permission_required(Permission.APIEditAllNotes)
|
||||||
|
# def evaluation_set_notes(
|
||||||
|
# eval_id: int, note: float, etudid: int = None, nip: int = None, ine: int = None
|
||||||
|
# ):
|
||||||
|
# """
|
||||||
|
# Set les notes d'une évaluation pour un étudiant donnée
|
||||||
|
#
|
||||||
|
# eval_id : l'id d'une évaluation
|
||||||
|
# note : la note à attribuer
|
||||||
|
# etudid : l'etudid d'un étudiant
|
||||||
|
# nip : le code nip d'un étudiant
|
||||||
|
# ine : le code ine d'un étudiant
|
||||||
|
# """
|
||||||
|
# # Fonction utilisée : app.scodoc.sco_saisie_notes.notes_add()
|
||||||
|
#
|
||||||
|
# # Qu'est ce qu'un user ???
|
||||||
|
# # notes_add()
|
||||||
|
# return error_response(501, message="Not implemented")
|
||||||
|
|
||||||
|
|
||||||
|
# ### Inutil en définitif ###
|
||||||
|
# @bp.route(
|
||||||
|
# "/absences/abs_signale?etudid=<int:etudid>&date=<string:date>&matin=<string:matin>&justif=<string:justif>"
|
||||||
|
# "&description=<string:description>",
|
||||||
|
# methods=["POST"],
|
||||||
|
# )
|
||||||
|
# @bp.route(
|
||||||
|
# "/absences/abs_signale?nip=<int:nip>&date=<string:date>&matin=<string:matin>&justif=<string:justif>"
|
||||||
|
# "&description=<string:description>",
|
||||||
|
# methods=["POST"],
|
||||||
|
# )
|
||||||
|
# @bp.route(
|
||||||
|
# "/absences/abs_signale?ine=<int:ine>&date=<string:date>&matin=<string:matin>&justif=<string:justif>"
|
||||||
|
# "&description=<string:description>",
|
||||||
|
# methods=["POST"],
|
||||||
|
# )
|
||||||
|
# @bp.route(
|
||||||
|
# "/absences/abs_signale?ine=<int:ine>&date=<string:date>&matin=<string:matin>&justif=<string:justif>"
|
||||||
|
# "&description=<string:description>&moduleimpl_id=<int:moduleimpl_id>",
|
||||||
|
# methods=["POST"],
|
||||||
|
# )
|
||||||
|
# @token_permission_required(Permission.APIAbsChange)
|
||||||
|
# def abs_signale(
|
||||||
|
# date: datetime,
|
||||||
|
# matin: bool,
|
||||||
|
# justif: bool,
|
||||||
|
# etudid: int = None,
|
||||||
|
# nip: int = None,
|
||||||
|
# ine: int = None, ### Inutil en définitif
|
||||||
|
# description: str = None,
|
||||||
|
# moduleimpl_id: int = None,
|
||||||
|
# ):
|
||||||
|
# """
|
||||||
|
# Permet d'ajouter une absence en base
|
||||||
|
#
|
||||||
|
# date : la date de l'absence
|
||||||
|
# matin : True ou False
|
||||||
|
# justif : True ou False
|
||||||
|
# etudid : l'etudid d'un étudiant
|
||||||
|
# nip: le code nip d'un étudiant
|
||||||
|
# ine : le code ine d'un étudiant
|
||||||
|
# description : description possible à ajouter sur l'absence
|
||||||
|
# moduleimpl_id : l'id d'un moduleimpl
|
||||||
|
# """
|
||||||
|
# # Fonctions utilisées : app.scodoc.sco_abs.add_absence() et app.scodoc.sco_abs.add_justif()
|
||||||
|
#
|
||||||
|
# if etudid is None:
|
||||||
|
# # Récupération de l'étudiant
|
||||||
|
# try:
|
||||||
|
# etu = get_etu_from_request(etudid, nip, ine)
|
||||||
|
# etudid = etu.etudid
|
||||||
|
# except AttributeError:
|
||||||
|
# return error_response(
|
||||||
|
# 409,
|
||||||
|
# message="La requête ne peut être traitée en l’état actuel.\n "
|
||||||
|
# "Veilliez vérifier que l'id de l'étudiant (etudid, nip, ine) est valide",
|
||||||
|
# )
|
||||||
|
# try:
|
||||||
|
# # Utilisation de la fonction add_absence
|
||||||
|
# add_absence(etudid, date, matin, justif, description, moduleimpl_id)
|
||||||
|
# if justif == True:
|
||||||
|
# # Utilisation de la fonction add_justif
|
||||||
|
# add_justif(etudid, date, matin, description)
|
||||||
|
# except ValueError:
|
||||||
|
# return error_response(
|
||||||
|
# 409, message="La requête ne peut être traitée en l’état actuel"
|
||||||
|
# )
|
||||||
|
# @bp.route(
|
||||||
|
# "/absences/abs_annule_justif?etudid=<int:etudid>&jour=<string:jour>&matin=<string:matin>",
|
||||||
|
# methods=["POST"],
|
||||||
|
# )
|
||||||
|
# @bp.route(
|
||||||
|
# "/absences/abs_annule_justif?nip=<int:nip>&jour=<string:jour>&matin=<string:matin>",
|
||||||
|
# methods=["POST"],
|
||||||
|
# )
|
||||||
|
# @bp.route(
|
||||||
|
# "/absences/abs_annule_justif?ine=<int:ine>&jour=<string:jour>&matin=<string:matin>",
|
||||||
|
# methods=["POST"],
|
||||||
|
# )
|
||||||
|
# @token_permission_required(Permission.APIAbsChange)
|
||||||
|
# def abs_annule_justif(
|
||||||
|
# jour: datetime, matin: str, etudid: int = None, nip: int = None, ine: int = None
|
||||||
|
# ):
|
||||||
|
# """
|
||||||
|
# Retourne un html
|
||||||
|
|
||||||
|
# jour : la date de l'absence a annulé
|
||||||
|
# matin : True ou False
|
||||||
|
# etudid : l'etudid d'un étudiant
|
||||||
|
# nip: le code nip d'un étudiant
|
||||||
|
# ine : le code ine d'un étudiant
|
||||||
|
# """
|
||||||
|
# # Fonction utilisée : app.scodoc.sco_abs.annule_justif()
|
||||||
|
|
||||||
|
# if etudid is None:
|
||||||
|
# # Récupération de l'étudiant
|
||||||
|
# try:
|
||||||
|
# etu = get_etu_from_etudid_or_nip_or_ine(etudid, nip, ine)
|
||||||
|
# etudid = etu.etudid
|
||||||
|
# except AttributeError:
|
||||||
|
# return error_response(
|
||||||
|
# 409,
|
||||||
|
# message="La requête ne peut être traitée en l’état actuel.\n "
|
||||||
|
# "Veilliez vérifier que l'id de l'étudiant (etudid, nip, ine) est valide",
|
||||||
|
# )
|
||||||
|
# try:
|
||||||
|
# # Utilisation de la fonction annule_justif
|
||||||
|
# annule_justif(etudid, jour, matin)
|
||||||
|
# except ValueError:
|
||||||
|
# return error_response(
|
||||||
|
# 409,
|
||||||
|
# message="La requête ne peut être traitée en l’état actuel.\n "
|
||||||
|
# "Veilliez vérifier que le 'jour' et le 'matin' sont valides",
|
||||||
|
# )
|
||||||
|
|
||||||
|
# return error_response(200, message="OK")
|
||||||
|
|
||||||
|
# @bp.route(
|
||||||
|
# "/jury/set_decision/etudid?etudid=<int:etudid>&formsemestre_id=<int:formesemestre_id>"
|
||||||
|
# "&jury=<string:decision_jury>&devenir=<string:devenir_jury>&assiduite=<bool>",
|
||||||
|
# methods=["POST"],
|
||||||
|
# )
|
||||||
|
# @bp.route(
|
||||||
|
# "/jury/set_decision/nip?etudid=<int:etudid>&formsemestre_id=<int:formesemestre_id>"
|
||||||
|
# "&jury=<string:decision_jury>&devenir=<string:devenir_jury>&assiduite=<bool>",
|
||||||
|
# methods=["POST"],
|
||||||
|
# )
|
||||||
|
# @bp.route(
|
||||||
|
# "/jury/set_decision/ine?etudid=<int:etudid>&formsemestre_id=<int:formesemestre_id>"
|
||||||
|
# "&jury=<string:decision_jury>&devenir=<string:devenir_jury>&assiduite=<bool>",
|
||||||
|
# methods=["POST"],
|
||||||
|
# )
|
||||||
|
# # @token_permission_required(Permission.)
|
||||||
|
# def set_decision_jury(
|
||||||
|
# formsemestre_id: int,
|
||||||
|
# decision_jury: str,
|
||||||
|
# devenir_jury: str,
|
||||||
|
# assiduite: bool,
|
||||||
|
# etudid: int = None,
|
||||||
|
# nip: int = None,
|
||||||
|
# ine: int = None,
|
||||||
|
# ):
|
||||||
|
# """
|
||||||
|
# Attribuer la décision du jury et le devenir à un etudiant
|
||||||
|
#
|
||||||
|
# formsemestre_id : l'id d'un formsemestre
|
||||||
|
# decision_jury : la décision du jury
|
||||||
|
# devenir_jury : le devenir du jury
|
||||||
|
# assiduite : True ou False
|
||||||
|
# etudid : l'etudid d'un étudiant
|
||||||
|
# nip: le code nip d'un étudiant
|
||||||
|
# ine : le code ine d'un étudiant
|
||||||
|
# """
|
||||||
|
# return error_response(501, message="Not implemented")
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# @bp.route(
|
||||||
|
# "/jury/etudid/<int:etudid>/formsemestre/<int:formsemestre_id>/annule_decision",
|
||||||
|
# methods=["DELETE"],
|
||||||
|
# )
|
||||||
|
# @bp.route(
|
||||||
|
# "/jury/nip/<int:nip>/formsemestre/<int:formsemestre_id>/annule_decision",
|
||||||
|
# methods=["DELETE"],
|
||||||
|
# )
|
||||||
|
# @bp.route(
|
||||||
|
# "/jury/ine/<int:ine>/formsemestre/<int:formsemestre_id>/annule_decision",
|
||||||
|
# methods=["DELETE"],
|
||||||
|
# )
|
||||||
|
# # @token_permission_required(Permission.)
|
||||||
|
# def annule_decision_jury(
|
||||||
|
# formsemestre_id: int, etudid: int = None, nip: int = None, ine: int = None
|
||||||
|
# ):
|
||||||
|
# """
|
||||||
|
# Supprime la déciosion du jury pour un étudiant donné
|
||||||
|
#
|
||||||
|
# formsemestre_id : l'id d'un formsemestre
|
||||||
|
# etudid : l'etudid d'un étudiant
|
||||||
|
# nip: le code nip d'un étudiant
|
||||||
|
# ine : le code ine d'un étudiant
|
||||||
|
# """
|
||||||
|
# return error_response(501, message="Not implemented")
|
@ -50,442 +50,103 @@ from app.api.errors import error_response
|
|||||||
from app import models
|
from app import models
|
||||||
from app.models import FormSemestre, FormSemestreInscription, Identite
|
from app.models import FormSemestre, FormSemestreInscription, Identite
|
||||||
from app.models import ApcReferentielCompetences
|
from app.models import ApcReferentielCompetences
|
||||||
|
from app.scodoc.sco_abs import (
|
||||||
|
annule_absence,
|
||||||
|
annule_justif,
|
||||||
|
add_absence,
|
||||||
|
add_justif,
|
||||||
|
list_abs_date,
|
||||||
|
)
|
||||||
|
from app.scodoc.sco_bulletins import formsemestre_bulletinetud_dict
|
||||||
|
from app.scodoc.sco_bulletins_json import make_json_formsemestre_bulletinetud
|
||||||
|
from app.scodoc.sco_evaluation_db import do_evaluation_get_all_notes
|
||||||
|
from app.scodoc.sco_formations import formation_export
|
||||||
|
from app.scodoc.sco_formsemestre_inscriptions import (
|
||||||
|
do_formsemestre_inscription_listinscrits,
|
||||||
|
)
|
||||||
|
from app.scodoc.sco_groups import setGroups, get_etud_groups, get_group_members
|
||||||
|
from app.scodoc.sco_logos import list_logos, find_logo, _list_dept_logos
|
||||||
|
from app.scodoc.sco_moduleimpl import moduleimpl_list
|
||||||
from app.scodoc.sco_permissions import Permission
|
from app.scodoc.sco_permissions import Permission
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/list_depts", methods=["GET"])
|
# ###################################################### Logos ##########################################################
|
||||||
@token_auth.login_required
|
#
|
||||||
def list_depts():
|
# # XXX TODO voir get_logo déjà existant dans app/views/scodoc.py
|
||||||
depts = models.Departement.query.filter_by(visible=True).all()
|
#
|
||||||
data = [d.to_dict() for d in depts]
|
# @bp.route("/logos", methods=["GET"])
|
||||||
return jsonify(data)
|
# def liste_logos(format="json"):
|
||||||
|
# """
|
||||||
|
# Liste des logos définis pour le site scodoc.
|
||||||
@bp.route("/etudiants/courant", methods=["GET"])
|
# """
|
||||||
@token_auth.login_required
|
# # fonction to use : list_logos()
|
||||||
def etudiants():
|
# # try:
|
||||||
"""Liste de tous les étudiants actuellement inscrits à un semestre
|
# # res = list_logos()
|
||||||
en cours.
|
# # except ValueError:
|
||||||
"""
|
# # return error_response(409, message="La requête ne peut être traitée en l’état actuel")
|
||||||
# Vérification de l'accès: permission Observateur sur tous les départements
|
# #
|
||||||
# (c'est un exemple à compléter)
|
# # if res is None:
|
||||||
if not g.current_user.has_permission(Permission.ScoObservateur, None):
|
# # return error_response(200, message="Aucun logo trouvé correspondant aux informations renseignés")
|
||||||
return error_response(401, message="accès interdit")
|
# #
|
||||||
|
# # return res
|
||||||
query = db.session.query(Identite).filter(
|
#
|
||||||
FormSemestreInscription.formsemestre_id == FormSemestre.id,
|
#
|
||||||
FormSemestreInscription.etudid == Identite.id,
|
#
|
||||||
FormSemestre.date_debut <= func.now(),
|
# @bp.route("/logos/<string:logo_name>", methods=["GET"])
|
||||||
FormSemestre.date_fin >= func.now(),
|
# def recup_logo_global(logo_name: str):
|
||||||
)
|
# """
|
||||||
return jsonify([e.to_dict_bul(include_urls=False) for e in query])
|
# Retourne l'image au format png ou jpg
|
||||||
|
#
|
||||||
|
# logo_name : le nom du logo rechercher
|
||||||
######################## Departements ##################################
|
# """
|
||||||
|
# # fonction to use find_logo
|
||||||
|
# # try:
|
||||||
@bp.route("/departements", methods=["GET"])
|
# # res = find_logo(logo_name)
|
||||||
@token_auth.login_required
|
# # except ValueError:
|
||||||
def departements():
|
# # return error_response(409, message="La requête ne peut être traitée en l’état actuel")
|
||||||
"""
|
# #
|
||||||
Liste des ids de départements
|
# # if res is None:
|
||||||
"""
|
# # return error_response(200, message="Aucun logo trouvé correspondant aux informations renseignés")
|
||||||
depts = models.Departement.query.filter_by(visible=True).all()
|
# #
|
||||||
data = [d.id for d in depts]
|
# # return res
|
||||||
return jsonify(data)
|
#
|
||||||
|
#
|
||||||
|
# @bp.route("/departements/<string:dept>/logos", methods=["GET"])
|
||||||
@bp.route("/departements/<string:dept>/etudiants/liste/<int:sem_id>", methods=["GET"])
|
# def logo_dept(dept: str):
|
||||||
@token_auth.login_required
|
# """
|
||||||
def liste_etudiants(dept, *args, sem_id): # XXX TODO A REVOIR
|
# Liste des logos définis pour le département visé.
|
||||||
"""
|
#
|
||||||
Liste des étudiants d'un département
|
# dept : l'id d'un département
|
||||||
"""
|
# """
|
||||||
# Test si le sem_id à été renseigné ou non
|
# # fonction to use: _list_dept_logos
|
||||||
if sem_id is not None:
|
# # dept_id = models.Departement.query.filter_by(acronym=dept).first()
|
||||||
# Récupération du/des depts
|
# # try:
|
||||||
list_depts = models.Departement.query.filter(
|
# # res = _list_dept_logos(dept_id.id)
|
||||||
models.Departement.acronym == dept,
|
# # except ValueError:
|
||||||
models.FormSemestre.semestre_id == sem_id,
|
# # return error_response(409, message="La requête ne peut être traitée en l’état actuel")
|
||||||
)
|
# #
|
||||||
list_etuds = []
|
# # if res is None:
|
||||||
for dept in list_depts:
|
# # return error_response(200, message="Aucun logo trouvé correspondant aux informations renseignés")
|
||||||
# Récupération des étudiants d'un département
|
# #
|
||||||
x = models.Identite.query.filter(models.Identite.dept_id == dept.getId())
|
# # return res
|
||||||
for y in x:
|
#
|
||||||
# Ajout des étudiants dans la liste global
|
#
|
||||||
list_etuds.append(y)
|
# @bp.route("/departement/<string:dept>/logos/<string:logo_name>", methods=["GET"])
|
||||||
else:
|
# def recup_logo_dept_global(dept: str, logo_name: str):
|
||||||
list_depts = models.Departement.query.filter(
|
# """
|
||||||
models.Departement.acronym == dept,
|
# L'image format png ou jpg
|
||||||
models.FormSemestre.semestre_id == models.Departement.formsemestres,
|
#
|
||||||
)
|
# dept : l'id d'un département
|
||||||
list_etuds = []
|
# logo_name : le nom du logo rechercher
|
||||||
for dept in list_depts:
|
# """
|
||||||
x = models.Identite.query.filter(models.Identite.dept_id == dept.getId())
|
# # fonction to use find_logo
|
||||||
for y in x:
|
# # dept_id = models.Departement.query.filter_by(acronym=dept).first()
|
||||||
list_etuds.append(y)
|
# # try:
|
||||||
|
# # res = find_logo(logo_name, dept_id.id)
|
||||||
data = [d.to_dict() for d in list_etuds]
|
# # except ValueError:
|
||||||
# return jsonify(data)
|
# # return error_response(409, message="La requête ne peut être traitée en l’état actuel")
|
||||||
return error_response(501, message="Not implemented")
|
# #
|
||||||
|
# # if res is None:
|
||||||
|
# # return error_response(200, message="Aucun logo trouvé correspondant aux informations renseignés")
|
||||||
@bp.route("/departements/<string:dept>/semestres_actifs", methods=["GET"])
|
# #
|
||||||
@token_auth.login_required
|
# # return res
|
||||||
def liste_semestres_actifs(dept): # TODO : changer nom
|
|
||||||
"""
|
|
||||||
Liste des semestres actifs d'un départements donné
|
|
||||||
"""
|
|
||||||
# Récupération de l'id du dept
|
|
||||||
dept_id = models.Departement.query.filter(models.Departement.acronym == dept)
|
|
||||||
# Puis ici récupération du FormSemestre correspondant
|
|
||||||
depts_actifs = models.FormSemestre.query.filter_by(
|
|
||||||
etat=True,
|
|
||||||
dept_id=dept_id,
|
|
||||||
)
|
|
||||||
data = [da.to_dict() for da in depts_actifs]
|
|
||||||
|
|
||||||
# return jsonify(data)
|
|
||||||
return error_response(501, message="Not implemented")
|
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/referentiel_competences/<int:referentiel_competence_id>")
|
|
||||||
@token_auth.login_required
|
|
||||||
def referentiel_competences(referentiel_competence_id):
|
|
||||||
"""
|
|
||||||
Le référentiel de compétences
|
|
||||||
"""
|
|
||||||
ref = ApcReferentielCompetences.query.get_or_404(referentiel_competence_id)
|
|
||||||
return jsonify(ref.to_dict())
|
|
||||||
|
|
||||||
|
|
||||||
####################### Etudiants ##################################
|
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/etudiant/<int:etudid>", methods=["GET"])
|
|
||||||
@token_auth.login_required
|
|
||||||
def etudiant(etudid):
|
|
||||||
"""
|
|
||||||
Un dictionnaire avec les informations de l'étudiant correspondant à l'id passé en paramètres.
|
|
||||||
"""
|
|
||||||
etud: Identite = Identite.query.get_or_404(etudid)
|
|
||||||
return jsonify(etud.to_dict_bul())
|
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/etudiant/<int:etudid>/semestre/<int:sem_id>/bulletin", methods=["GET"])
|
|
||||||
@token_auth.login_required
|
|
||||||
def etudiant_bulletin_semestre(etudid, sem_id):
|
|
||||||
"""
|
|
||||||
Le bulletin d'un étudiant en fonction de son id et d'un semestre donné
|
|
||||||
"""
|
|
||||||
# return jsonify(models.BulAppreciations.query.filter_by(etudid=etudid, formsemestre_id=sem_id))
|
|
||||||
return error_response(501, message="Not implemented")
|
|
||||||
|
|
||||||
|
|
||||||
@bp.route(
|
|
||||||
"/formsemestre/<int:formsemestre_id>/departements/<string:dept>/etudiant/nip/<int:NIP>/releve",
|
|
||||||
methods=["GET"],
|
|
||||||
)
|
|
||||||
@bp.route(
|
|
||||||
"/formsemestre/<int:formsemestre_id>/departements/<string:dept>/etudiant/id/<int:etudid>/releve",
|
|
||||||
methods=["GET"],
|
|
||||||
)
|
|
||||||
@bp.route(
|
|
||||||
"/formsemestre/<int:formsemestre_id>/departements/<string:dept>/etudiant/ine/<int:numScodoc>/releve",
|
|
||||||
methods=["GET"],
|
|
||||||
)
|
|
||||||
@token_auth.login_required
|
|
||||||
def etudiant_bulletin(formsemestre_id, dept, etudid, format="json", *args, size):
|
|
||||||
"""
|
|
||||||
Un bulletin de note
|
|
||||||
"""
|
|
||||||
formsemestres = models.FormSemestre.query.filter_by(id=formsemestre_id)
|
|
||||||
depts = models.Departement.query.filter_by(acronym=dept)
|
|
||||||
etud = ""
|
|
||||||
|
|
||||||
data = []
|
|
||||||
if args[0] == "short":
|
|
||||||
pass
|
|
||||||
elif args[0] == "selectevals":
|
|
||||||
pass
|
|
||||||
elif args[0] == "long":
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
return "erreur"
|
|
||||||
|
|
||||||
# return jsonify(data)
|
|
||||||
return error_response(501, message="Not implemented")
|
|
||||||
|
|
||||||
|
|
||||||
@bp.route(
|
|
||||||
"/etudiant/<int:etudid>/semestre/<int:formsemestre_id>/groups", methods=["GET"]
|
|
||||||
)
|
|
||||||
@token_auth.login_required
|
|
||||||
def etudiant_groups(etudid: int, formsemestre_id: int):
|
|
||||||
"""
|
|
||||||
Liste des groupes auxquels appartient l'étudiant dans le semestre indiqué
|
|
||||||
"""
|
|
||||||
semestre = models.FormSemestre.query.filter_by(id=formsemestre_id)
|
|
||||||
etudiant = models.Identite.query.filter_by(id=etudid)
|
|
||||||
|
|
||||||
groups = models.Partition.query.filter(
|
|
||||||
models.Partition.formsemestre_id == semestre,
|
|
||||||
models.GroupDescr.etudiants == etudiant,
|
|
||||||
)
|
|
||||||
data = [d.to_dict() for d in groups]
|
|
||||||
# return jsonify(data)
|
|
||||||
|
|
||||||
return error_response(501, message="Not implemented")
|
|
||||||
|
|
||||||
|
|
||||||
#######################" Programmes de formations #########################
|
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/formations", methods=["GET"])
|
|
||||||
@bp.route("/formations/<int:formation_id>", methods=["GET"])
|
|
||||||
@token_auth.login_required
|
|
||||||
def formations(formation_id: int):
|
|
||||||
"""
|
|
||||||
Liste des formations
|
|
||||||
"""
|
|
||||||
formations = models.Formation.query.filter_by(id=formation_id)
|
|
||||||
data = [d.to_dict() for d in formations]
|
|
||||||
# return jsonify(data)
|
|
||||||
|
|
||||||
return error_response(501, message="Not implemented")
|
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/formations/formation_export/<int:formation_id>", methods=["GET"])
|
|
||||||
@token_auth.login_required
|
|
||||||
def formation_export(formation_id: int, export_ids=False):
|
|
||||||
"""
|
|
||||||
La formation, avec UE, matières, modules
|
|
||||||
"""
|
|
||||||
return error_response(501, message="Not implemented")
|
|
||||||
|
|
||||||
|
|
||||||
###################### UE #######################################
|
|
||||||
|
|
||||||
|
|
||||||
@bp.route(
|
|
||||||
"/departements/<string:dept>/formations/programme/<string:sem_id>", methods=["GET"]
|
|
||||||
)
|
|
||||||
@token_auth.login_required
|
|
||||||
def eus(dept: str, sem_id: int):
|
|
||||||
"""
|
|
||||||
Liste des UES, ressources et SAE d'un semestre
|
|
||||||
"""
|
|
||||||
return error_response(501, message="Not implemented")
|
|
||||||
|
|
||||||
|
|
||||||
######## Semestres de formation ###############
|
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/formations/formsemestre/<int:formsemestre_id>", methods=["GET"])
|
|
||||||
@bp.route("/formations/apo/<int:etape_apo>", methods=["GET"])
|
|
||||||
@token_auth.login_required
|
|
||||||
def formsemestre(
|
|
||||||
id: int,
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
Information sur les formsemestres
|
|
||||||
"""
|
|
||||||
return error_response(501, message="Not implemented")
|
|
||||||
|
|
||||||
|
|
||||||
############ Modules de formation ##############
|
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/formations/moduleimpl/<int:moduleimpl_id>", methods=["GET"])
|
|
||||||
@bp.route(
|
|
||||||
"/formations/moduleimpl/<int:moduleimpl_id>/formsemestre/<int:formsemestre_id>",
|
|
||||||
methods=["GET"],
|
|
||||||
)
|
|
||||||
@token_auth.login_required
|
|
||||||
def moduleimpl(id: int):
|
|
||||||
"""
|
|
||||||
Liste de moduleimpl
|
|
||||||
"""
|
|
||||||
return error_response(501, message="Not implemented")
|
|
||||||
|
|
||||||
|
|
||||||
########### Groupes et partitions ###############
|
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/partitions/<int:formsemestre_id>", methods=["GET"])
|
|
||||||
@token_auth.login_required
|
|
||||||
def partition(formsemestre_id: int):
|
|
||||||
"""
|
|
||||||
La liste de toutes les partitions d'un formsemestre
|
|
||||||
"""
|
|
||||||
partitions = models.Partition.query.filter_by(id=formsemestre_id)
|
|
||||||
data = [d.to_dict() for d in partitions]
|
|
||||||
|
|
||||||
# return jsonify(data)
|
|
||||||
return error_response(501, message="Not implemented")
|
|
||||||
|
|
||||||
|
|
||||||
@bp.route(
|
|
||||||
"/partitions/formsemestre/<int:formsemestre_id>/groups/group_ids?with_codes=&all_groups=&etat=",
|
|
||||||
methods=["GET"],
|
|
||||||
)
|
|
||||||
@token_auth.login_required
|
|
||||||
def groups(formsemestre_id: int, group_ids: int):
|
|
||||||
"""
|
|
||||||
Liste des étudiants dans un groupe
|
|
||||||
"""
|
|
||||||
return error_response(501, message="Not implemented")
|
|
||||||
|
|
||||||
|
|
||||||
@bp.route(
|
|
||||||
"/partitions/set_groups?partition_id=<int:partition_id>&groups=<int:groups>&groups_to_delete=<int:groups_to_delete>&groups_to_create=<int:groups_to_create>",
|
|
||||||
methods=["POST"],
|
|
||||||
)
|
|
||||||
@token_auth.login_required
|
|
||||||
def set_groups(
|
|
||||||
partition_id: int, groups: int, groups_to_delete: int, groups_to_create: int
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
Set les groups
|
|
||||||
"""
|
|
||||||
return error_response(501, message="Not implemented")
|
|
||||||
|
|
||||||
|
|
||||||
####### Bulletins de notes ###########
|
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/evaluations/<int:moduleimpl_id>", methods=["GET"])
|
|
||||||
@token_auth.login_required
|
|
||||||
def evaluations(moduleimpl_id: int):
|
|
||||||
"""
|
|
||||||
Liste des évaluations à partir de l'id d'un moduleimpl
|
|
||||||
"""
|
|
||||||
evals = models.Evaluation.query.filter_by(id=moduleimpl_id)
|
|
||||||
data = [d.to_dict() for d in evals]
|
|
||||||
|
|
||||||
# return jsonify(data)
|
|
||||||
return error_response(501, message="Not implemented")
|
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/evaluations/eval_notes/<int:evaluation_id>", methods=["GET"])
|
|
||||||
@token_auth.login_required
|
|
||||||
def evaluation_notes(evaluation_id: int):
|
|
||||||
"""
|
|
||||||
Liste des notes à partir de l'id d'une évaluation donnée
|
|
||||||
"""
|
|
||||||
evals = models.Evaluation.query.filter_by(id=evaluation_id)
|
|
||||||
notes = evals.get_notes()
|
|
||||||
|
|
||||||
data = [d.to_dict() for d in notes]
|
|
||||||
# return jsonify(data)
|
|
||||||
return error_response(501, message="Not implemented")
|
|
||||||
|
|
||||||
|
|
||||||
@bp.route(
|
|
||||||
"/evaluations/eval_set_notes?eval_id=<int:eval_id>&etudid=<int:etudid>¬e=<int:note>",
|
|
||||||
methods=["POST"],
|
|
||||||
)
|
|
||||||
@token_auth.login_required
|
|
||||||
def evaluation_set_notes(eval_id: int, etudid: int, note: float):
|
|
||||||
"""
|
|
||||||
Set les notes d'une évaluation pour un étudiant donnée
|
|
||||||
"""
|
|
||||||
return error_response(501, message="Not implemented")
|
|
||||||
|
|
||||||
|
|
||||||
############## Absences #############
|
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/absences/<int:etudid>", methods=["GET"])
|
|
||||||
@bp.route("/absences/<int:etudid>/abs_just_only", methods=["GET"])
|
|
||||||
def absences(etudid: int):
|
|
||||||
"""
|
|
||||||
Liste des absences d'un étudiant donnée
|
|
||||||
"""
|
|
||||||
abs = models.Absence.query.filter_by(id=etudid)
|
|
||||||
|
|
||||||
data = [d.to_dict() for d in abs]
|
|
||||||
|
|
||||||
# return jsonify(data)
|
|
||||||
return error_response(501, message="Not implemented")
|
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/absences/abs_signale", methods=["POST"])
|
|
||||||
@token_auth.login_required
|
|
||||||
def abs_signale():
|
|
||||||
"""
|
|
||||||
Retourne un html
|
|
||||||
"""
|
|
||||||
return error_response(501, message="Not implemented")
|
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/absences/abs_annule", methods=["POST"])
|
|
||||||
@token_auth.login_required
|
|
||||||
def abs_annule():
|
|
||||||
"""
|
|
||||||
Retourne un html
|
|
||||||
"""
|
|
||||||
return error_response(501, message="Not implemented")
|
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/absences/abs_annule_justif", methods=["POST"])
|
|
||||||
@token_auth.login_required
|
|
||||||
def abs_annule_justif():
|
|
||||||
"""
|
|
||||||
Retourne un html
|
|
||||||
"""
|
|
||||||
return error_response(501, message="Not implemented")
|
|
||||||
|
|
||||||
|
|
||||||
@bp.route(
|
|
||||||
"/absences/abs_group_etat/?group_ids=<int:group_ids>&date_debut=date_debut&date_fin=date_fin",
|
|
||||||
methods=["GET"],
|
|
||||||
)
|
|
||||||
@token_auth.login_required
|
|
||||||
def abs_groupe_etat(
|
|
||||||
group_ids: int, date_debut, date_fin, with_boursier=True, format="html"
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
Liste des absences d'un ou plusieurs groupes entre deux dates
|
|
||||||
"""
|
|
||||||
return error_response(501, message="Not implemented")
|
|
||||||
|
|
||||||
|
|
||||||
################ Logos ################
|
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/logos", methods=["GET"])
|
|
||||||
@token_auth.login_required
|
|
||||||
def liste_logos(format="json"):
|
|
||||||
"""
|
|
||||||
Liste des logos définis pour le site scodoc.
|
|
||||||
"""
|
|
||||||
return error_response(501, message="Not implemented")
|
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/logos/<string:nom>", methods=["GET"])
|
|
||||||
@token_auth.login_required
|
|
||||||
def recup_logo_global(nom: str):
|
|
||||||
"""
|
|
||||||
Retourne l'image au format png ou jpg
|
|
||||||
"""
|
|
||||||
return error_response(501, message="Not implemented")
|
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/departements/<string:dept>/logos", methods=["GET"])
|
|
||||||
@token_auth.login_required
|
|
||||||
def logo_dept(dept: str):
|
|
||||||
"""
|
|
||||||
Liste des logos définis pour le département visé.
|
|
||||||
"""
|
|
||||||
return error_response(501, message="Not implemented")
|
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/departement/<string:dept>/logos/<string:nom>", methods=["GET"])
|
|
||||||
@token_auth.login_required
|
|
||||||
def recup_logo_dept_global(dept: str, nom: str):
|
|
||||||
"""
|
|
||||||
L'image format png ou jpg
|
|
||||||
"""
|
|
||||||
return error_response(501, message="Not implemented")
|
|
||||||
|
444
app/api/test_api.py
Normal file
444
app/api/test_api.py
Normal file
@ -0,0 +1,444 @@
|
|||||||
|
################################################## Tests ##############################################################
|
||||||
|
|
||||||
|
|
||||||
|
# XXX OBSOLETE ??? XXX
|
||||||
|
|
||||||
|
import requests
|
||||||
|
import os
|
||||||
|
|
||||||
|
from app import models
|
||||||
|
from app.api import bp, requested_format
|
||||||
|
from app.api.auth import token_auth
|
||||||
|
from app.api.errors import error_response
|
||||||
|
|
||||||
|
SCODOC_USER = "test"
|
||||||
|
SCODOC_PASSWORD = "test"
|
||||||
|
SCODOC_URL = "http://192.168.1.12:5000"
|
||||||
|
CHECK_CERTIFICATE = bool(int(os.environ.get("CHECK_CERTIFICATE", False)))
|
||||||
|
|
||||||
|
HEADERS = None
|
||||||
|
|
||||||
|
|
||||||
|
def get_token():
|
||||||
|
"""
|
||||||
|
Permet de set le token dans le header
|
||||||
|
"""
|
||||||
|
global HEADERS
|
||||||
|
global SCODOC_USER
|
||||||
|
global SCODOC_PASSWORD
|
||||||
|
|
||||||
|
r0 = requests.post(
|
||||||
|
SCODOC_URL + "/ScoDoc/api/tokens", auth=(SCODOC_USER, SCODOC_PASSWORD)
|
||||||
|
)
|
||||||
|
token = r0.json()["token"]
|
||||||
|
HEADERS = {"Authorization": f"Bearer {token}"}
|
||||||
|
|
||||||
|
|
||||||
|
DEPT = None
|
||||||
|
FORMSEMESTRE = None
|
||||||
|
ETU = None
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route("/test_dept", methods=["GET"])
|
||||||
|
def get_departement():
|
||||||
|
"""
|
||||||
|
Permet de tester departements() mais également de set un département dans DEPT pour la suite des tests
|
||||||
|
"""
|
||||||
|
|
||||||
|
get_token()
|
||||||
|
|
||||||
|
global HEADERS
|
||||||
|
global CHECK_CERTIFICATE
|
||||||
|
global SCODOC_USER
|
||||||
|
global SCODOC_PASSWORD
|
||||||
|
|
||||||
|
# print(HEADERS)
|
||||||
|
# departements
|
||||||
|
r = requests.get(
|
||||||
|
SCODOC_URL + "/ScoDoc/api/departements",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
|
)
|
||||||
|
|
||||||
|
if r.status_code == 200:
|
||||||
|
dept_id = r.json()[0]
|
||||||
|
# print(dept_id)
|
||||||
|
|
||||||
|
dept = models.Departement.query.filter_by(id=dept_id).first()
|
||||||
|
dept = dept.to_dict()
|
||||||
|
|
||||||
|
fields = ["id", "acronym", "description", "visible", "date_creation"]
|
||||||
|
|
||||||
|
for field in dept:
|
||||||
|
if field not in fields:
|
||||||
|
return error_response(501, field + " field missing")
|
||||||
|
|
||||||
|
global DEPT
|
||||||
|
DEPT = dept
|
||||||
|
|
||||||
|
return error_response(200, "OK")
|
||||||
|
|
||||||
|
return error_response(409, "La requête ne peut être traitée en l’état actuel")
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route("/test_formsemestre", methods=["GET"])
|
||||||
|
def get_formsemestre():
|
||||||
|
"""
|
||||||
|
Permet de tester liste_semestres_courant() mais également de set un formsemestre dans FORMSEMESTRE
|
||||||
|
pour la suite des tests
|
||||||
|
"""
|
||||||
|
get_departement()
|
||||||
|
|
||||||
|
global DEPT
|
||||||
|
dept_acronym = DEPT["acronym"]
|
||||||
|
|
||||||
|
# liste_semestres_courant
|
||||||
|
r = requests.get(
|
||||||
|
SCODOC_URL + "/ScoDoc/api/departements/" + dept_acronym + "/semestres_courants",
|
||||||
|
auth=(SCODOC_USER, SCODOC_PASSWORD),
|
||||||
|
)
|
||||||
|
|
||||||
|
if r.status_code == 200:
|
||||||
|
formsemestre = r.json()[0]
|
||||||
|
print(r.json()[0])
|
||||||
|
|
||||||
|
fields = [
|
||||||
|
"gestion_semestrielle",
|
||||||
|
"titre",
|
||||||
|
"scodoc7_id",
|
||||||
|
"date_debut",
|
||||||
|
"bul_bgcolor",
|
||||||
|
"date_fin",
|
||||||
|
"resp_can_edit",
|
||||||
|
"dept_id",
|
||||||
|
"etat",
|
||||||
|
"resp_can_change_ens",
|
||||||
|
"id",
|
||||||
|
"modalite",
|
||||||
|
"ens_can_edit_eval",
|
||||||
|
"formation_id",
|
||||||
|
"gestion_compensation",
|
||||||
|
"elt_sem_apo",
|
||||||
|
"semestre_id",
|
||||||
|
"bul_hide_xml",
|
||||||
|
"elt_annee_apo",
|
||||||
|
"block_moyennes",
|
||||||
|
"formsemestre_id",
|
||||||
|
"titre_num",
|
||||||
|
"date_debut_iso",
|
||||||
|
"date_fin_iso",
|
||||||
|
"responsables",
|
||||||
|
]
|
||||||
|
|
||||||
|
for field in formsemestre:
|
||||||
|
if field not in fields:
|
||||||
|
return error_response(501, field + " field missing")
|
||||||
|
|
||||||
|
global FORMSEMESTRE
|
||||||
|
FORMSEMESTRE = formsemestre
|
||||||
|
|
||||||
|
return error_response(200, "OK")
|
||||||
|
|
||||||
|
return error_response(409, "La requête ne peut être traitée en l’état actuel")
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route("/test_etu", methods=["GET"])
|
||||||
|
def get_etudiant():
|
||||||
|
"""
|
||||||
|
Permet de tester etudiants() mais également de set un etudiant dans ETU pour la suite des tests
|
||||||
|
"""
|
||||||
|
|
||||||
|
# etudiants
|
||||||
|
r = requests.get(
|
||||||
|
SCODOC_URL + "/ScoDoc/api/etudiants/courant",
|
||||||
|
auth=(SCODOC_USER, SCODOC_PASSWORD),
|
||||||
|
)
|
||||||
|
|
||||||
|
if r.status_code == 200:
|
||||||
|
etu = r.json()[0]
|
||||||
|
|
||||||
|
fields = [
|
||||||
|
"civilite",
|
||||||
|
"code_ine",
|
||||||
|
"code_nip",
|
||||||
|
"date_naissance",
|
||||||
|
"email",
|
||||||
|
"emailperso",
|
||||||
|
"etudid",
|
||||||
|
"nom",
|
||||||
|
"prenom",
|
||||||
|
]
|
||||||
|
|
||||||
|
for field in etu:
|
||||||
|
if field not in fields:
|
||||||
|
return error_response(501, field + " field missing")
|
||||||
|
|
||||||
|
global ETU
|
||||||
|
ETU = etu
|
||||||
|
print(etu)
|
||||||
|
|
||||||
|
return error_response(200, "OK")
|
||||||
|
|
||||||
|
return error_response(409, "La requête ne peut être traitée en l’état actuel")
|
||||||
|
|
||||||
|
|
||||||
|
############################################### Departements ##########################################################
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route("/test_liste_etudiants")
|
||||||
|
def test_departements_liste_etudiants():
|
||||||
|
"""
|
||||||
|
Test la route liste_etudiants
|
||||||
|
"""
|
||||||
|
# Set un département et un formsemestre pour les tests
|
||||||
|
get_departement()
|
||||||
|
get_formsemestre()
|
||||||
|
|
||||||
|
global DEPT
|
||||||
|
global FORMSEMESTRE
|
||||||
|
|
||||||
|
# Set les fields à vérifier
|
||||||
|
fields = [
|
||||||
|
"civilite",
|
||||||
|
"code_ine",
|
||||||
|
"code_nip",
|
||||||
|
"date_naissance",
|
||||||
|
"email",
|
||||||
|
"emailperso",
|
||||||
|
"etudid",
|
||||||
|
"nom",
|
||||||
|
"prenom",
|
||||||
|
]
|
||||||
|
|
||||||
|
# liste_etudiants (sans formsemestre)
|
||||||
|
r1 = requests.get(
|
||||||
|
SCODOC_URL + "/ScoDoc/api/departements/" + DEPT["acronym"] + "/etudiants/liste",
|
||||||
|
auth=(SCODOC_USER, SCODOC_PASSWORD),
|
||||||
|
)
|
||||||
|
|
||||||
|
if r1.status_code == 200: # Si la requête est "OK"
|
||||||
|
# On récupère la liste des étudiants
|
||||||
|
etudiants = r1.json()
|
||||||
|
|
||||||
|
# Vérification que tous les étudiants ont bien tous les bons champs
|
||||||
|
for etu in etudiants:
|
||||||
|
for field in etu:
|
||||||
|
if field not in fields:
|
||||||
|
return error_response(501, field + " field missing")
|
||||||
|
|
||||||
|
# liste_etudiants (avec formsemestre)
|
||||||
|
r2 = requests.get(
|
||||||
|
SCODOC_URL
|
||||||
|
+ "/ScoDoc/api/departements/"
|
||||||
|
+ DEPT["acronym"]
|
||||||
|
+ "/etudiants/liste/"
|
||||||
|
+ str(FORMSEMESTRE["formsemestre_id"]),
|
||||||
|
auth=(SCODOC_USER, SCODOC_PASSWORD),
|
||||||
|
)
|
||||||
|
|
||||||
|
if r2.status_code == 200: # Si la requête est "OK"
|
||||||
|
# On récupère la liste des étudiants
|
||||||
|
etudiants = r2.json()
|
||||||
|
|
||||||
|
# Vérification que tous les étudiants ont bien tous les bons champs
|
||||||
|
for etu in etudiants:
|
||||||
|
for field in etu:
|
||||||
|
if field not in fields:
|
||||||
|
return error_response(501, field + " field missing")
|
||||||
|
|
||||||
|
return error_response(200, "OK")
|
||||||
|
|
||||||
|
return error_response(409, "La requête ne peut être traitée en l’état actuel")
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route("/test_referenciel_competences")
|
||||||
|
def test_departements_referenciel_competences():
|
||||||
|
"""
|
||||||
|
Test la route referenciel_competences
|
||||||
|
"""
|
||||||
|
get_departement()
|
||||||
|
get_formsemestre()
|
||||||
|
|
||||||
|
global DEPT
|
||||||
|
global FORMSEMESTRE
|
||||||
|
|
||||||
|
# referenciel_competences
|
||||||
|
r = requests.post(
|
||||||
|
SCODOC_URL
|
||||||
|
+ "/ScoDoc/api/departements/"
|
||||||
|
+ DEPT["acronym"]
|
||||||
|
+ "/formations/"
|
||||||
|
+ FORMSEMESTRE["formation_id"]
|
||||||
|
+ "/referentiel_competences",
|
||||||
|
auth=(SCODOC_USER, SCODOC_PASSWORD),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route("/test_liste_semestre_index")
|
||||||
|
def test_departements_semestre_index():
|
||||||
|
"""
|
||||||
|
Test la route semestre_index
|
||||||
|
"""
|
||||||
|
# semestre_index
|
||||||
|
r5 = requests.post(
|
||||||
|
SCODOC_URL
|
||||||
|
+ "/ScoDoc/api/departements/"
|
||||||
|
+ DEPT["acronym"]
|
||||||
|
+ "/formsemestre/"
|
||||||
|
+ FORMSEMESTRE["formation_id"]
|
||||||
|
+ "/programme",
|
||||||
|
auth=(SCODOC_USER, SCODOC_PASSWORD),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
#################################################### Etudiants ########################################################
|
||||||
|
|
||||||
|
|
||||||
|
def test_routes_etudiants():
|
||||||
|
"""
|
||||||
|
Test les routes de la partie Etudiants
|
||||||
|
"""
|
||||||
|
# etudiants
|
||||||
|
r1 = requests.get(
|
||||||
|
SCODOC_URL + "/ScoDoc/api/etudiants", auth=(SCODOC_USER, SCODOC_PASSWORD)
|
||||||
|
)
|
||||||
|
|
||||||
|
# etudiants_courant
|
||||||
|
r2 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
|
|
||||||
|
# etudiant
|
||||||
|
r3 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
|
|
||||||
|
# etudiant_formsemestres
|
||||||
|
r4 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
|
|
||||||
|
# etudiant_bulletin_semestre
|
||||||
|
r5 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
|
|
||||||
|
# etudiant_groups
|
||||||
|
r6 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
|
|
||||||
|
|
||||||
|
def test_routes_formation():
|
||||||
|
"""
|
||||||
|
Test les routes de la partie Formation
|
||||||
|
"""
|
||||||
|
# formations
|
||||||
|
r1 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
|
|
||||||
|
# formations_by_id
|
||||||
|
r2 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
|
|
||||||
|
# formation_export_by_formation_id
|
||||||
|
r3 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
|
|
||||||
|
# formsemestre_apo
|
||||||
|
r4 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
|
|
||||||
|
# moduleimpls
|
||||||
|
r5 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
|
|
||||||
|
# moduleimpls_sem
|
||||||
|
r6 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
|
|
||||||
|
|
||||||
|
def test_routes_formsemestres():
|
||||||
|
"""
|
||||||
|
Test les routes de la partie Formsemestres
|
||||||
|
"""
|
||||||
|
# formsemestre
|
||||||
|
r1 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
|
|
||||||
|
# etudiant_bulletin
|
||||||
|
r2 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
|
|
||||||
|
# bulletins
|
||||||
|
r3 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
|
|
||||||
|
# jury
|
||||||
|
r4 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
|
|
||||||
|
|
||||||
|
def test_routes_partitions():
|
||||||
|
"""
|
||||||
|
Test les routes de la partie Partitions
|
||||||
|
"""
|
||||||
|
# partition
|
||||||
|
r1 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
|
|
||||||
|
# etud_in_group
|
||||||
|
r2 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
|
|
||||||
|
# set_groups
|
||||||
|
r3 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
|
|
||||||
|
|
||||||
|
def test_routes_evaluations():
|
||||||
|
"""
|
||||||
|
Test les routes de la partie Evaluations
|
||||||
|
"""
|
||||||
|
# evaluations
|
||||||
|
r1 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
|
|
||||||
|
# evaluation_notes
|
||||||
|
r2 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
|
|
||||||
|
# evaluation_set_notes
|
||||||
|
r3 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
|
|
||||||
|
|
||||||
|
def test_routes_jury():
|
||||||
|
"""
|
||||||
|
Test les routes de la partie Jury
|
||||||
|
"""
|
||||||
|
# jury_preparation
|
||||||
|
r1 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
|
|
||||||
|
# jury_decisions
|
||||||
|
r2 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
|
|
||||||
|
# set_decision_jury
|
||||||
|
r3 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
|
|
||||||
|
# annule_decision_jury
|
||||||
|
r4 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
|
|
||||||
|
|
||||||
|
def test_routes_absences():
|
||||||
|
"""
|
||||||
|
Test les routes de la partie Absences
|
||||||
|
"""
|
||||||
|
# absences
|
||||||
|
r1 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
|
|
||||||
|
# absences_justify
|
||||||
|
r2 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
|
|
||||||
|
# abs_signale
|
||||||
|
r3 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
|
|
||||||
|
# abs_annule
|
||||||
|
r4 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
|
|
||||||
|
# abs_annule_justif
|
||||||
|
r5 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
|
|
||||||
|
# abs_groupe_etat
|
||||||
|
r6 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
|
|
||||||
|
|
||||||
|
def test_routes_logos():
|
||||||
|
"""
|
||||||
|
Test les routes de la partie Logos
|
||||||
|
"""
|
||||||
|
# liste_logos
|
||||||
|
r1 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
|
|
||||||
|
# recup_logo_global
|
||||||
|
r2 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
|
|
||||||
|
# logo_dept
|
||||||
|
r3 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
||||||
|
|
||||||
|
# recup_logo_dept_global
|
||||||
|
r4 = requests.post(SCODOC_URL + "/ScoDoc/api", auth=(SCODOC_USER, SCODOC_PASSWORD))
|
22
app/api/tools.py
Normal file
22
app/api/tools.py
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
from app import models
|
||||||
|
|
||||||
|
|
||||||
|
def get_etu_from_etudid_or_nip_or_ine(etudid, nip, ine):
|
||||||
|
"""
|
||||||
|
Fonction qui retourne un etudiant en fonction de l'etudid, code nip et code ine rentré en paramètres
|
||||||
|
|
||||||
|
etudid : None ou un int etudid
|
||||||
|
nip : None ou un int code_nip
|
||||||
|
ine : None ou un int code_ine
|
||||||
|
|
||||||
|
Exemple de résultat: <Itendite>
|
||||||
|
"""
|
||||||
|
if etudid is None:
|
||||||
|
if nip is None: # si ine
|
||||||
|
etud = models.Identite.query.filter_by(code_ine=str(ine)).first()
|
||||||
|
else: # si nip
|
||||||
|
etud = models.Identite.query.filter_by(code_nip=str(nip)).first()
|
||||||
|
else: # si etudid
|
||||||
|
etud = models.Identite.query.filter_by(id=etudid).first()
|
||||||
|
|
||||||
|
return etud
|
@ -39,4 +39,12 @@ def get_dept_acronym(id):
|
|||||||
return dept.acronym
|
return dept.acronym
|
||||||
|
|
||||||
|
|
||||||
|
@bp.app_template_filter()
|
||||||
|
def get_civilité(civ):
|
||||||
|
if civ == "H":
|
||||||
|
return "Monsieur"
|
||||||
|
else:
|
||||||
|
return "Madame"
|
||||||
|
|
||||||
|
|
||||||
from app.entreprises import routes
|
from app.entreprises import routes
|
||||||
|
@ -131,38 +131,46 @@ def send_email_notifications_entreprise(subject, entreprise: Entreprise):
|
|||||||
def verif_correspondant_data(correspondant_data):
|
def verif_correspondant_data(correspondant_data):
|
||||||
"""
|
"""
|
||||||
Verifie les données d'une ligne Excel (correspondant)
|
Verifie les données d'une ligne Excel (correspondant)
|
||||||
correspondant_data[0]: nom
|
correspondant_data[0]: civilite
|
||||||
correspondant_data[1]: prenom
|
correspondant_data[1]: nom
|
||||||
correspondant_data[2]: telephone
|
correspondant_data[2]: prenom
|
||||||
correspondant_data[3]: mail
|
correspondant_data[3]: telephone
|
||||||
correspondant_data[4]: poste
|
correspondant_data[4]: mail
|
||||||
correspondant_data[5]: service
|
correspondant_data[5]: poste
|
||||||
correspondant_data[6]: entreprise_id
|
correspondant_data[6]: service
|
||||||
|
correspondant_data[7]: origine
|
||||||
|
correspondant_data[8]: notes
|
||||||
|
correspondant_data[9]: entreprise_siret
|
||||||
"""
|
"""
|
||||||
# champs obligatoires
|
# champs obligatoires
|
||||||
if (
|
if (
|
||||||
correspondant_data[0].strip() == ""
|
correspondant_data[0].strip() == ""
|
||||||
or correspondant_data[1].strip() == ""
|
or correspondant_data[1].strip() == ""
|
||||||
or correspondant_data[6].strip() == ""
|
or correspondant_data[2].strip() == ""
|
||||||
|
or correspondant_data[9].strip() == ""
|
||||||
):
|
):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
# civilite entre H ou F
|
||||||
|
if correspondant_data[0].strip() not in ["H", "F"]:
|
||||||
|
return False
|
||||||
|
|
||||||
# entreprise_id existant
|
# entreprise_id existant
|
||||||
entreprise = Entreprise.query.filter_by(siret=correspondant_data[6].strip()).first()
|
entreprise = Entreprise.query.filter_by(siret=correspondant_data[9].strip()).first()
|
||||||
if entreprise is None:
|
if entreprise is None:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# correspondant possède le meme nom et prénom dans la meme entreprise
|
# correspondant possède le meme nom et prénom dans la meme entreprise
|
||||||
correspondant = EntrepriseCorrespondant.query.filter_by(
|
correspondant = EntrepriseCorrespondant.query.filter_by(
|
||||||
nom=correspondant_data[0].strip(),
|
nom=correspondant_data[1].strip(),
|
||||||
prenom=correspondant_data[1].strip(),
|
prenom=correspondant_data[2].strip(),
|
||||||
entreprise_id=entreprise.id,
|
entreprise_id=entreprise.id,
|
||||||
).first()
|
).first()
|
||||||
if correspondant is not None:
|
if correspondant is not None:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if (
|
if (
|
||||||
correspondant_data[2].strip() == "" and correspondant_data[3].strip() == ""
|
correspondant_data[3].strip() == "" and correspondant_data[4].strip() == ""
|
||||||
): # 1 moyen de contact
|
): # 1 moyen de contact
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -182,7 +190,7 @@ def verif_entreprise_data(entreprise_data):
|
|||||||
if data.strip() == "":
|
if data.strip() == "":
|
||||||
return False
|
return False
|
||||||
if EntreprisePreferences.get_check_siret():
|
if EntreprisePreferences.get_check_siret():
|
||||||
siret = entreprise_data[0].replace(" ", "") # vérification sur le siret
|
siret = entreprise_data[0].strip().replace(" ", "") # vérification sur le siret
|
||||||
if re.match("^\d{14}$", siret) is None:
|
if re.match("^\d{14}$", siret) is None:
|
||||||
return False
|
return False
|
||||||
try:
|
try:
|
||||||
|
@ -80,6 +80,11 @@ class EntrepriseCreationForm(FlaskForm):
|
|||||||
ville = _build_string_field("Ville de l'entreprise (*)")
|
ville = _build_string_field("Ville de l'entreprise (*)")
|
||||||
pays = _build_string_field("Pays de l'entreprise", required=False)
|
pays = _build_string_field("Pays de l'entreprise", required=False)
|
||||||
|
|
||||||
|
civilite = SelectField(
|
||||||
|
"Civilité du correspondant",
|
||||||
|
choices=[("M", "Monsieur"), ("F", "Madame")],
|
||||||
|
validators=[DataRequired(message=CHAMP_REQUIS)],
|
||||||
|
)
|
||||||
nom_correspondant = _build_string_field("Nom du correspondant", required=False)
|
nom_correspondant = _build_string_field("Nom du correspondant", required=False)
|
||||||
prenom_correspondant = _build_string_field(
|
prenom_correspondant = _build_string_field(
|
||||||
"Prénom du correspondant", required=False
|
"Prénom du correspondant", required=False
|
||||||
@ -91,6 +96,8 @@ class EntrepriseCreationForm(FlaskForm):
|
|||||||
)
|
)
|
||||||
poste = _build_string_field("Poste du correspondant", required=False)
|
poste = _build_string_field("Poste du correspondant", required=False)
|
||||||
service = _build_string_field("Service du correspondant", required=False)
|
service = _build_string_field("Service du correspondant", required=False)
|
||||||
|
origine = _build_string_field("Origine du correspondant", required=False)
|
||||||
|
notes = _build_string_field("Notes sur le correspondant", required=False)
|
||||||
|
|
||||||
submit = SubmitField("Envoyer", render_kw=SUBMIT_MARGE)
|
submit = SubmitField("Envoyer", render_kw=SUBMIT_MARGE)
|
||||||
|
|
||||||
@ -106,6 +113,8 @@ class EntrepriseCreationForm(FlaskForm):
|
|||||||
or self.mail.data.strip()
|
or self.mail.data.strip()
|
||||||
or self.poste.data.strip()
|
or self.poste.data.strip()
|
||||||
or self.service.data.strip()
|
or self.service.data.strip()
|
||||||
|
or self.origine.data.strip()
|
||||||
|
or self.notes.data.strip()
|
||||||
):
|
):
|
||||||
if not self.nom_correspondant.data.strip():
|
if not self.nom_correspondant.data.strip():
|
||||||
self.nom_correspondant.errors.append("Ce champ est requis")
|
self.nom_correspondant.errors.append("Ce champ est requis")
|
||||||
@ -114,19 +123,16 @@ class EntrepriseCreationForm(FlaskForm):
|
|||||||
self.prenom_correspondant.errors.append("Ce champ est requis")
|
self.prenom_correspondant.errors.append("Ce champ est requis")
|
||||||
validate = False
|
validate = False
|
||||||
if not self.telephone.data.strip() and not self.mail.data.strip():
|
if not self.telephone.data.strip() and not self.mail.data.strip():
|
||||||
self.telephone.errors.append(
|
msg = "Saisir un moyen de contact (mail ou téléphone)"
|
||||||
"Saisir un moyen de contact (mail ou téléphone)"
|
self.telephone.errors.append(msg)
|
||||||
)
|
self.mail.errors.append(msg)
|
||||||
self.mail.errors.append(
|
|
||||||
"Saisir un moyen de contact (mail ou téléphone)"
|
|
||||||
)
|
|
||||||
validate = False
|
validate = False
|
||||||
|
|
||||||
return validate
|
return validate
|
||||||
|
|
||||||
def validate_siret(self, siret):
|
def validate_siret(self, siret):
|
||||||
if EntreprisePreferences.get_check_siret():
|
if EntreprisePreferences.get_check_siret():
|
||||||
siret_data = siret.data.replace(" ", "")
|
siret_data = siret.data.strip().replace(" ", "")
|
||||||
self.siret.data = siret_data
|
self.siret.data = siret_data
|
||||||
if re.match("^\d{14}$", siret_data) is None:
|
if re.match("^\d{14}$", siret_data) is None:
|
||||||
raise ValidationError("Format incorrect")
|
raise ValidationError("Format incorrect")
|
||||||
@ -164,6 +170,15 @@ class EntrepriseModificationForm(FlaskForm):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class SiteCreationForm(FlaskForm):
|
||||||
|
nom = _build_string_field("Nom du site (*)")
|
||||||
|
adresse = _build_string_field("Adresse (*)")
|
||||||
|
codepostal = _build_string_field("Code postal (*)")
|
||||||
|
ville = _build_string_field("Ville (*)")
|
||||||
|
pays = _build_string_field("Pays", required=False)
|
||||||
|
submit = SubmitField("Envoyer", render_kw=SUBMIT_MARGE)
|
||||||
|
|
||||||
|
|
||||||
class MultiCheckboxField(SelectMultipleField):
|
class MultiCheckboxField(SelectMultipleField):
|
||||||
widget = ListWidget(prefix_label=False)
|
widget = ListWidget(prefix_label=False)
|
||||||
option_widget = CheckboxInput()
|
option_widget = CheckboxInput()
|
||||||
@ -184,11 +199,11 @@ class OffreCreationForm(FlaskForm):
|
|||||||
"Missions (*)", validators=[DataRequired(message=CHAMP_REQUIS)]
|
"Missions (*)", validators=[DataRequired(message=CHAMP_REQUIS)]
|
||||||
)
|
)
|
||||||
duree = _build_string_field("Durée (*)")
|
duree = _build_string_field("Durée (*)")
|
||||||
depts = MultiCheckboxField("Départements", validators=[Optional()], coerce=int)
|
depts = MultiCheckboxField("Départements (*)", validators=[Optional()], coerce=int)
|
||||||
expiration_date = DateField("Date expiration", validators=[Optional()])
|
expiration_date = DateField("Date expiration", validators=[Optional()])
|
||||||
correspondant = SelectField("Correspondant à contacté", validators=[Optional()])
|
correspondant = SelectField("Correspondant à contacté", validators=[Optional()])
|
||||||
fichier = FileField(
|
fichier = FileField(
|
||||||
"Fichier (*)",
|
"Fichier",
|
||||||
validators=[
|
validators=[
|
||||||
Optional(),
|
Optional(),
|
||||||
FileAllowed(["pdf", "docx"], "Fichier .pdf ou .docx uniquement"),
|
FileAllowed(["pdf", "docx"], "Fichier .pdf ou .docx uniquement"),
|
||||||
@ -237,7 +252,7 @@ class OffreModificationForm(FlaskForm):
|
|||||||
"Missions (*)", validators=[DataRequired(message=CHAMP_REQUIS)]
|
"Missions (*)", validators=[DataRequired(message=CHAMP_REQUIS)]
|
||||||
)
|
)
|
||||||
duree = _build_string_field("Durée (*)")
|
duree = _build_string_field("Durée (*)")
|
||||||
depts = MultiCheckboxField("Départements", validators=[Optional()], coerce=int)
|
depts = MultiCheckboxField("Départements (*)", validators=[Optional()], coerce=int)
|
||||||
expiration_date = DateField("Date expiration", validators=[Optional()])
|
expiration_date = DateField("Date expiration", validators=[Optional()])
|
||||||
correspondant = SelectField("Correspondant à contacté", validators=[Optional()])
|
correspondant = SelectField("Correspondant à contacté", validators=[Optional()])
|
||||||
submit = SubmitField("Modifier", render_kw=SUBMIT_MARGE)
|
submit = SubmitField("Modifier", render_kw=SUBMIT_MARGE)
|
||||||
@ -269,6 +284,12 @@ class OffreModificationForm(FlaskForm):
|
|||||||
|
|
||||||
|
|
||||||
class CorrespondantCreationForm(FlaskForm):
|
class CorrespondantCreationForm(FlaskForm):
|
||||||
|
civilite = SelectField(
|
||||||
|
"Civilité (*)",
|
||||||
|
choices=[("H", "Monsieur"), ("F", "Madame")],
|
||||||
|
validators=[DataRequired(message=CHAMP_REQUIS)],
|
||||||
|
render_kw={"class": "form-control"},
|
||||||
|
)
|
||||||
nom = _build_string_field("Nom (*)", render_kw={"class": "form-control"})
|
nom = _build_string_field("Nom (*)", render_kw={"class": "form-control"})
|
||||||
prenom = _build_string_field("Prénom (*)", render_kw={"class": "form-control"})
|
prenom = _build_string_field("Prénom (*)", render_kw={"class": "form-control"})
|
||||||
telephone = _build_string_field(
|
telephone = _build_string_field(
|
||||||
@ -285,14 +306,12 @@ class CorrespondantCreationForm(FlaskForm):
|
|||||||
service = _build_string_field(
|
service = _build_string_field(
|
||||||
"Service", required=False, render_kw={"class": "form-control"}
|
"Service", required=False, render_kw={"class": "form-control"}
|
||||||
)
|
)
|
||||||
# depts = MultiCheckboxField("Départements", validators=[Optional()], coerce=int)
|
origine = _build_string_field(
|
||||||
|
"Origine", required=False, render_kw={"class": "form-control"}
|
||||||
# def __init__(self, *args, **kwargs):
|
)
|
||||||
# super().__init__(*args, **kwargs)
|
notes = _build_string_field(
|
||||||
|
"Notes", required=False, render_kw={"class": "form-control"}
|
||||||
# self.depts.choices = [
|
)
|
||||||
# (dept.id, dept.acronym) for dept in Departement.query.all()
|
|
||||||
# ]
|
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
validate = True
|
validate = True
|
||||||
@ -300,10 +319,9 @@ class CorrespondantCreationForm(FlaskForm):
|
|||||||
validate = False
|
validate = False
|
||||||
|
|
||||||
if not self.telephone.data and not self.mail.data:
|
if not self.telephone.data and not self.mail.data:
|
||||||
self.telephone.errors.append(
|
msg = "Saisir un moyen de contact (mail ou téléphone)"
|
||||||
"Saisir un moyen de contact (mail ou téléphone)"
|
self.telephone.errors.append(msg)
|
||||||
)
|
self.mail.errors.append(msg)
|
||||||
self.mail.errors.append("Saisir un moyen de contact (mail ou téléphone)")
|
|
||||||
validate = False
|
validate = False
|
||||||
|
|
||||||
return validate
|
return validate
|
||||||
@ -321,7 +339,7 @@ class CorrespondantsCreationForm(FlaskForm):
|
|||||||
|
|
||||||
correspondant_list = []
|
correspondant_list = []
|
||||||
for entry in self.correspondants.entries:
|
for entry in self.correspondants.entries:
|
||||||
if entry.nom.data.strip() and entry.prenom.data.strip():
|
if entry.nom.data and entry.prenom.data:
|
||||||
if (
|
if (
|
||||||
entry.nom.data.strip(),
|
entry.nom.data.strip(),
|
||||||
entry.prenom.data.strip(),
|
entry.prenom.data.strip(),
|
||||||
@ -351,6 +369,11 @@ class CorrespondantsCreationForm(FlaskForm):
|
|||||||
class CorrespondantModificationForm(FlaskForm):
|
class CorrespondantModificationForm(FlaskForm):
|
||||||
hidden_correspondant_id = HiddenField()
|
hidden_correspondant_id = HiddenField()
|
||||||
hidden_entreprise_id = HiddenField()
|
hidden_entreprise_id = HiddenField()
|
||||||
|
civilite = SelectField(
|
||||||
|
"Civilité (*)",
|
||||||
|
choices=[("H", "Monsieur"), ("F", "Madame")],
|
||||||
|
validators=[DataRequired(message=CHAMP_REQUIS)],
|
||||||
|
)
|
||||||
nom = _build_string_field("Nom (*)")
|
nom = _build_string_field("Nom (*)")
|
||||||
prenom = _build_string_field("Prénom (*)")
|
prenom = _build_string_field("Prénom (*)")
|
||||||
telephone = _build_string_field("Téléphone (*)", required=False)
|
telephone = _build_string_field("Téléphone (*)", required=False)
|
||||||
@ -360,16 +383,10 @@ class CorrespondantModificationForm(FlaskForm):
|
|||||||
)
|
)
|
||||||
poste = _build_string_field("Poste", required=False)
|
poste = _build_string_field("Poste", required=False)
|
||||||
service = _build_string_field("Service", required=False)
|
service = _build_string_field("Service", required=False)
|
||||||
# depts = MultiCheckboxField("Départements", validators=[Optional()], coerce=int)
|
origine = _build_string_field("Origine", required=False)
|
||||||
|
notes = _build_string_field("Notes", required=False)
|
||||||
submit = SubmitField("Modifier", render_kw=SUBMIT_MARGE)
|
submit = SubmitField("Modifier", render_kw=SUBMIT_MARGE)
|
||||||
|
|
||||||
# def __init__(self, *args, **kwargs):
|
|
||||||
# super().__init__(*args, **kwargs)
|
|
||||||
|
|
||||||
# self.depts.choices = [
|
|
||||||
# (dept.id, dept.acronym) for dept in Departement.query.all()
|
|
||||||
# ]
|
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
validate = True
|
validate = True
|
||||||
if not FlaskForm.validate(self):
|
if not FlaskForm.validate(self):
|
||||||
@ -387,10 +404,9 @@ class CorrespondantModificationForm(FlaskForm):
|
|||||||
validate = False
|
validate = False
|
||||||
|
|
||||||
if not self.telephone.data and not self.mail.data:
|
if not self.telephone.data and not self.mail.data:
|
||||||
self.telephone.errors.append(
|
msg = "Saisir un moyen de contact (mail ou téléphone)"
|
||||||
"Saisir un moyen de contact (mail ou téléphone)"
|
self.telephone.errors.append(msg)
|
||||||
)
|
self.mail.errors.append(msg)
|
||||||
self.mail.errors.append("Saisir un moyen de contact (mail ou téléphone)")
|
|
||||||
validate = False
|
validate = False
|
||||||
|
|
||||||
return validate
|
return validate
|
||||||
@ -593,6 +609,11 @@ class SuppressionConfirmationForm(FlaskForm):
|
|||||||
submit = SubmitField("Supprimer", render_kw=SUBMIT_MARGE)
|
submit = SubmitField("Supprimer", render_kw=SUBMIT_MARGE)
|
||||||
|
|
||||||
|
|
||||||
|
class DesactivationConfirmationForm(FlaskForm):
|
||||||
|
notes_active = TextAreaField("Notes sur la désactivation", validators=[Optional()])
|
||||||
|
submit = SubmitField("Désactiver", render_kw=SUBMIT_MARGE)
|
||||||
|
|
||||||
|
|
||||||
class ValidationConfirmationForm(FlaskForm):
|
class ValidationConfirmationForm(FlaskForm):
|
||||||
submit = SubmitField("Valider", render_kw=SUBMIT_MARGE)
|
submit = SubmitField("Valider", render_kw=SUBMIT_MARGE)
|
||||||
|
|
||||||
|
@ -9,14 +9,18 @@ class Entreprise(db.Model):
|
|||||||
adresse = db.Column(db.Text)
|
adresse = db.Column(db.Text)
|
||||||
codepostal = db.Column(db.Text)
|
codepostal = db.Column(db.Text)
|
||||||
ville = db.Column(db.Text)
|
ville = db.Column(db.Text)
|
||||||
pays = db.Column(db.Text, default="FRANCE")
|
pays = db.Column(db.Text)
|
||||||
visible = db.Column(db.Boolean, default=False)
|
visible = db.Column(db.Boolean, default=False)
|
||||||
correspondants = db.relationship(
|
active = db.Column(db.Boolean, default=True)
|
||||||
"EntrepriseCorrespondant",
|
notes_active = db.Column(db.Text)
|
||||||
|
|
||||||
|
sites = db.relationship(
|
||||||
|
"EntrepriseSite",
|
||||||
backref="entreprise",
|
backref="entreprise",
|
||||||
lazy="dynamic",
|
lazy="dynamic",
|
||||||
cascade="all, delete-orphan",
|
cascade="all, delete-orphan",
|
||||||
)
|
)
|
||||||
|
|
||||||
offres = db.relationship(
|
offres = db.relationship(
|
||||||
"EntrepriseOffre",
|
"EntrepriseOffre",
|
||||||
backref="entreprise",
|
backref="entreprise",
|
||||||
@ -35,13 +39,24 @@ class Entreprise(db.Model):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# class EntrepriseSite(db.Model):
|
class EntrepriseSite(db.Model):
|
||||||
# __tablename__ = "are_sites"
|
__tablename__ = "are_sites"
|
||||||
# id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
# entreprise_id = db.Column(
|
entreprise_id = db.Column(
|
||||||
# db.Integer, db.ForeignKey("are_entreprises.id", ondelete="cascade")
|
db.Integer, db.ForeignKey("are_entreprises.id", ondelete="cascade")
|
||||||
# )
|
)
|
||||||
# nom = db.Column(db.Text)
|
nom = db.Column(db.Text)
|
||||||
|
adresse = db.Column(db.Text)
|
||||||
|
codepostal = db.Column(db.Text)
|
||||||
|
ville = db.Column(db.Text)
|
||||||
|
pays = db.Column(db.Text)
|
||||||
|
|
||||||
|
correspondants = db.relationship(
|
||||||
|
"EntrepriseCorrespondant",
|
||||||
|
backref="site",
|
||||||
|
lazy="dynamic",
|
||||||
|
cascade="all, delete-orphan",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class EntrepriseCorrespondant(db.Model):
|
class EntrepriseCorrespondant(db.Model):
|
||||||
@ -50,23 +65,29 @@ class EntrepriseCorrespondant(db.Model):
|
|||||||
entreprise_id = db.Column(
|
entreprise_id = db.Column(
|
||||||
db.Integer, db.ForeignKey("are_entreprises.id", ondelete="cascade")
|
db.Integer, db.ForeignKey("are_entreprises.id", ondelete="cascade")
|
||||||
)
|
)
|
||||||
# site_id = db.Column(db.Integer, db.ForeignKey("are_sites.id", ondelete="cascade"))
|
site_id = db.Column(db.Integer, db.ForeignKey("are_sites.id", ondelete="cascade"))
|
||||||
|
civilite = db.Column(db.String(1))
|
||||||
nom = db.Column(db.Text)
|
nom = db.Column(db.Text)
|
||||||
prenom = db.Column(db.Text)
|
prenom = db.Column(db.Text)
|
||||||
telephone = db.Column(db.Text)
|
telephone = db.Column(db.Text)
|
||||||
mail = db.Column(db.Text)
|
mail = db.Column(db.Text)
|
||||||
poste = db.Column(db.Text)
|
poste = db.Column(db.Text)
|
||||||
service = db.Column(db.Text)
|
service = db.Column(db.Text)
|
||||||
|
origine = db.Column(db.Text)
|
||||||
|
notes = db.Column(db.Text)
|
||||||
|
|
||||||
def to_dict(self):
|
def to_dict(self):
|
||||||
entreprise = Entreprise.query.filter_by(id=self.entreprise_id).first()
|
entreprise = Entreprise.query.filter_by(id=self.entreprise_id).first()
|
||||||
return {
|
return {
|
||||||
|
"civilite": self.civilite,
|
||||||
"nom": self.nom,
|
"nom": self.nom,
|
||||||
"prenom": self.prenom,
|
"prenom": self.prenom,
|
||||||
"telephone": self.telephone,
|
"telephone": self.telephone,
|
||||||
"mail": self.mail,
|
"mail": self.mail,
|
||||||
"poste": self.poste,
|
"poste": self.poste,
|
||||||
"service": self.service,
|
"service": self.service,
|
||||||
|
"origine": self.origine,
|
||||||
|
"notes": self.notes,
|
||||||
"entreprise_siret": entreprise.siret,
|
"entreprise_siret": entreprise.siret,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,15 +182,6 @@ class EntrepriseOffreDepartement(db.Model):
|
|||||||
dept_id = db.Column(db.Integer, db.ForeignKey("departement.id", ondelete="cascade"))
|
dept_id = db.Column(db.Integer, db.ForeignKey("departement.id", ondelete="cascade"))
|
||||||
|
|
||||||
|
|
||||||
# class EntrepriseCorrespondantDepartement(db.Model):
|
|
||||||
# __tablename__ = "are_correspondant_departement"
|
|
||||||
# id = db.Column(db.Integer, primary_key=True)
|
|
||||||
# correspondant_id = db.Column(
|
|
||||||
# db.Integer, db.ForeignKey("are_correspondants.id", ondelete="cascade")
|
|
||||||
# )
|
|
||||||
# dept_id = db.Column(db.Integer, db.ForeignKey("departement.id", ondelete="cascade"))
|
|
||||||
|
|
||||||
|
|
||||||
class EntreprisePreferences(db.Model):
|
class EntreprisePreferences(db.Model):
|
||||||
__tablename__ = "are_preferences"
|
__tablename__ = "are_preferences"
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
|
@ -13,8 +13,10 @@ from app.decorators import permission_required
|
|||||||
from app.entreprises import LOGS_LEN
|
from app.entreprises import LOGS_LEN
|
||||||
from app.entreprises.forms import (
|
from app.entreprises.forms import (
|
||||||
CorrespondantsCreationForm,
|
CorrespondantsCreationForm,
|
||||||
|
DesactivationConfirmationForm,
|
||||||
EntrepriseCreationForm,
|
EntrepriseCreationForm,
|
||||||
EntrepriseModificationForm,
|
EntrepriseModificationForm,
|
||||||
|
SiteCreationForm,
|
||||||
SuppressionConfirmationForm,
|
SuppressionConfirmationForm,
|
||||||
OffreCreationForm,
|
OffreCreationForm,
|
||||||
OffreModificationForm,
|
OffreModificationForm,
|
||||||
@ -36,6 +38,7 @@ from app.entreprises.models import (
|
|||||||
EntrepriseCorrespondant,
|
EntrepriseCorrespondant,
|
||||||
EntrepriseLog,
|
EntrepriseLog,
|
||||||
EntrepriseContact,
|
EntrepriseContact,
|
||||||
|
EntrepriseSite,
|
||||||
EntrepriseStageApprentissage,
|
EntrepriseStageApprentissage,
|
||||||
EntrepriseEnvoiOffre,
|
EntrepriseEnvoiOffre,
|
||||||
EntrepriseOffreDepartement,
|
EntrepriseOffreDepartement,
|
||||||
@ -59,7 +62,7 @@ def index():
|
|||||||
"""
|
"""
|
||||||
Permet d'afficher une page avec la liste des entreprises (visible) et une liste des dernières opérations
|
Permet d'afficher une page avec la liste des entreprises (visible) et une liste des dernières opérations
|
||||||
"""
|
"""
|
||||||
entreprises = Entreprise.query.filter_by(visible=True)
|
entreprises = Entreprise.query.filter_by(visible=True, active=True)
|
||||||
logs = EntrepriseLog.query.order_by(EntrepriseLog.date.desc()).limit(LOGS_LEN).all()
|
logs = EntrepriseLog.query.order_by(EntrepriseLog.date.desc()).limit(LOGS_LEN).all()
|
||||||
return render_template(
|
return render_template(
|
||||||
"entreprises/entreprises.html",
|
"entreprises/entreprises.html",
|
||||||
@ -101,7 +104,7 @@ def validation():
|
|||||||
|
|
||||||
|
|
||||||
@bp.route("/correspondants", methods=["GET"])
|
@bp.route("/correspondants", methods=["GET"])
|
||||||
@permission_required(Permission.RelationsEntreprisesView)
|
@permission_required(Permission.RelationsEntreprisesCorrespondants)
|
||||||
def correspondants():
|
def correspondants():
|
||||||
"""
|
"""
|
||||||
Permet d'afficher une page avec la liste des correspondants des entreprises visibles et une liste des dernières opérations
|
Permet d'afficher une page avec la liste des correspondants des entreprises visibles et une liste des dernières opérations
|
||||||
@ -109,7 +112,7 @@ def correspondants():
|
|||||||
correspondants = (
|
correspondants = (
|
||||||
db.session.query(EntrepriseCorrespondant, Entreprise)
|
db.session.query(EntrepriseCorrespondant, Entreprise)
|
||||||
.join(Entreprise, EntrepriseCorrespondant.entreprise_id == Entreprise.id)
|
.join(Entreprise, EntrepriseCorrespondant.entreprise_id == Entreprise.id)
|
||||||
.filter_by(visible=True)
|
.filter_by(visible=True, active=True)
|
||||||
)
|
)
|
||||||
logs = EntrepriseLog.query.order_by(EntrepriseLog.date.desc()).limit(LOGS_LEN).all()
|
logs = EntrepriseLog.query.order_by(EntrepriseLog.date.desc()).limit(LOGS_LEN).all()
|
||||||
return render_template(
|
return render_template(
|
||||||
@ -129,9 +132,9 @@ def fiche_entreprise(id):
|
|||||||
La fiche entreprise comporte les informations de l'entreprise, les correspondants de l'entreprise et
|
La fiche entreprise comporte les informations de l'entreprise, les correspondants de l'entreprise et
|
||||||
les offres de l'entreprise.
|
les offres de l'entreprise.
|
||||||
"""
|
"""
|
||||||
entreprise = Entreprise.query.filter_by(id=id, visible=True).first_or_404(
|
entreprise = Entreprise.query.filter_by(
|
||||||
description=f"fiche entreprise {id} inconnue"
|
id=id, visible=True, active=True
|
||||||
)
|
).first_or_404(description=f"fiche entreprise {id} inconnue")
|
||||||
offres_with_files = []
|
offres_with_files = []
|
||||||
depts = are.get_depts()
|
depts = are.get_depts()
|
||||||
for offre in entreprise.offres:
|
for offre in entreprise.offres:
|
||||||
@ -145,7 +148,7 @@ def fiche_entreprise(id):
|
|||||||
offre_with_files = are.get_offre_files_and_depts(offre, depts)
|
offre_with_files = are.get_offre_files_and_depts(offre, depts)
|
||||||
if offre_with_files is not None:
|
if offre_with_files is not None:
|
||||||
offres_with_files.append(offre_with_files)
|
offres_with_files.append(offre_with_files)
|
||||||
correspondants = entreprise.correspondants[:]
|
sites = entreprise.sites[:]
|
||||||
logs = (
|
logs = (
|
||||||
EntrepriseLog.query.order_by(EntrepriseLog.date.desc())
|
EntrepriseLog.query.order_by(EntrepriseLog.date.desc())
|
||||||
.filter_by(object=id)
|
.filter_by(object=id)
|
||||||
@ -163,7 +166,7 @@ def fiche_entreprise(id):
|
|||||||
"entreprises/fiche_entreprise.html",
|
"entreprises/fiche_entreprise.html",
|
||||||
title="Fiche entreprise",
|
title="Fiche entreprise",
|
||||||
entreprise=entreprise,
|
entreprise=entreprise,
|
||||||
correspondants=correspondants,
|
sites=sites,
|
||||||
offres=offres_with_files,
|
offres=offres_with_files,
|
||||||
logs=logs,
|
logs=logs,
|
||||||
stages_apprentissages=stages_apprentissages,
|
stages_apprentissages=stages_apprentissages,
|
||||||
@ -294,16 +297,31 @@ def add_entreprise():
|
|||||||
)
|
)
|
||||||
db.session.add(entreprise)
|
db.session.add(entreprise)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
if form.nom_correspondant.data.strip():
|
|
||||||
db.session.refresh(entreprise)
|
db.session.refresh(entreprise)
|
||||||
|
site = EntrepriseSite(
|
||||||
|
entreprise_id=entreprise.id,
|
||||||
|
nom=form.nom_entreprise.data.strip(),
|
||||||
|
adresse=form.adresse.data.strip(),
|
||||||
|
codepostal=form.codepostal.data.strip(),
|
||||||
|
ville=form.ville.data.strip(),
|
||||||
|
pays=form.pays.data.strip() if form.pays.data.strip() else "FRANCE",
|
||||||
|
)
|
||||||
|
db.session.add(site)
|
||||||
|
db.session.commit()
|
||||||
|
if form.nom_correspondant.data.strip():
|
||||||
|
db.session.refresh(site)
|
||||||
correspondant = EntrepriseCorrespondant(
|
correspondant = EntrepriseCorrespondant(
|
||||||
entreprise_id=entreprise.id,
|
entreprise_id=entreprise.id,
|
||||||
|
site_id=site.id,
|
||||||
|
civilite=form.civilite.data,
|
||||||
nom=form.nom_correspondant.data.strip(),
|
nom=form.nom_correspondant.data.strip(),
|
||||||
prenom=form.prenom_correspondant.data.strip(),
|
prenom=form.prenom_correspondant.data.strip(),
|
||||||
telephone=form.telephone.data.strip(),
|
telephone=form.telephone.data.strip(),
|
||||||
mail=form.mail.data.strip(),
|
mail=form.mail.data.strip(),
|
||||||
poste=form.poste.data.strip(),
|
poste=form.poste.data.strip(),
|
||||||
service=form.service.data.strip(),
|
service=form.service.data.strip(),
|
||||||
|
origine=form.origine.data.strip(),
|
||||||
|
notes=form.notes.data.strip(),
|
||||||
)
|
)
|
||||||
db.session.add(correspondant)
|
db.session.add(correspondant)
|
||||||
if current_user.has_permission(Permission.RelationsEntreprisesValidate, None):
|
if current_user.has_permission(Permission.RelationsEntreprisesValidate, None):
|
||||||
@ -404,39 +422,27 @@ def edit_entreprise(id):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/fiche_entreprise/delete_entreprise/<int:id>", methods=["GET", "POST"])
|
@bp.route("/fiche_entreprise/desactiver/<int:id>", methods=["GET", "POST"])
|
||||||
@permission_required(Permission.RelationsEntreprisesChange)
|
@permission_required(Permission.RelationsEntreprisesChange)
|
||||||
def delete_entreprise(id):
|
def fiche_entreprise_desactiver(id):
|
||||||
"""
|
"""
|
||||||
Permet de supprimer une entreprise de la base avec un formulaire de confirmation
|
Permet de désactiver une entreprise
|
||||||
"""
|
"""
|
||||||
entreprise = Entreprise.query.filter_by(id=id, visible=True).first_or_404(
|
entreprise = Entreprise.query.filter_by(id=id, visible=True).first_or_404(
|
||||||
description=f"entreprise {id} inconnue"
|
description=f"entreprise {id} inconnue"
|
||||||
)
|
)
|
||||||
form = SuppressionConfirmationForm()
|
form = DesactivationConfirmationForm()
|
||||||
if form.validate_on_submit():
|
if form.validate_on_submit():
|
||||||
db.session.delete(entreprise)
|
entreprise.notes_active = form.notes_active.data.strip()
|
||||||
# supprime les fichiers attachés aux offres
|
entreprise.active = False
|
||||||
path = os.path.join(
|
|
||||||
Config.SCODOC_VAR_DIR,
|
|
||||||
"entreprises",
|
|
||||||
f"{entreprise.id}",
|
|
||||||
)
|
|
||||||
if os.path.isdir(path):
|
|
||||||
shutil.rmtree(path)
|
|
||||||
log = EntrepriseLog(
|
|
||||||
authenticated_user=current_user.user_name,
|
|
||||||
object=entreprise.id,
|
|
||||||
text=f"Suppression de la fiche entreprise ({entreprise.nom})",
|
|
||||||
)
|
|
||||||
db.session.add(log)
|
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
flash("L'entreprise a été supprimé de la liste.")
|
flash("L'entreprise a été désactivé.")
|
||||||
return redirect(url_for("entreprises.index"))
|
return redirect(url_for("entreprises.index"))
|
||||||
return render_template(
|
return render_template(
|
||||||
"entreprises/delete_confirmation.html",
|
"entreprises/confirmation_form.html",
|
||||||
title="Supression entreprise",
|
title="Désactiver entreprise",
|
||||||
form=form,
|
form=form,
|
||||||
|
info_message="Cliquez sur le bouton Désactiver pour confirmer la désactivation",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -489,9 +495,10 @@ def delete_validation_entreprise(id):
|
|||||||
flash("L'entreprise a été supprimé de la liste des entreprise à valider.")
|
flash("L'entreprise a été supprimé de la liste des entreprise à valider.")
|
||||||
return redirect(url_for("entreprises.validation"))
|
return redirect(url_for("entreprises.validation"))
|
||||||
return render_template(
|
return render_template(
|
||||||
"entreprises/delete_confirmation.html",
|
"entreprises/confirmation_form.html",
|
||||||
title="Supression entreprise",
|
title="Supression entreprise",
|
||||||
form=form,
|
form=form,
|
||||||
|
info_message="Cliquez sur le bouton Supprimer pour confirmer votre supression",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -645,9 +652,10 @@ def delete_offre(id):
|
|||||||
flash("L'offre a été supprimé de la fiche entreprise.")
|
flash("L'offre a été supprimé de la fiche entreprise.")
|
||||||
return redirect(url_for("entreprises.fiche_entreprise", id=entreprise_id))
|
return redirect(url_for("entreprises.fiche_entreprise", id=entreprise_id))
|
||||||
return render_template(
|
return render_template(
|
||||||
"entreprises/delete_confirmation.html",
|
"entreprises/confirmation_form.html",
|
||||||
title="Supression offre",
|
title="Supression offre",
|
||||||
form=form,
|
form=form,
|
||||||
|
info_message="Cliquez sur le bouton Supprimer pour confirmer votre supression",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -683,26 +691,66 @@ def expired(id):
|
|||||||
return redirect(url_for("entreprises.fiche_entreprise", id=offre.entreprise_id))
|
return redirect(url_for("entreprises.fiche_entreprise", id=offre.entreprise_id))
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/fiche_entreprise/<int:id>/add_correspondant", methods=["GET", "POST"])
|
@bp.route(
|
||||||
|
"/fiche_entreprise/<int:id>/add_site",
|
||||||
|
methods=["GET", "POST"],
|
||||||
|
)
|
||||||
@permission_required(Permission.RelationsEntreprisesChange)
|
@permission_required(Permission.RelationsEntreprisesChange)
|
||||||
def add_correspondant(id):
|
def add_site(id):
|
||||||
|
entreprise = Entreprise.query.filter_by(id=id, visible=True).first_or_404(
|
||||||
|
description=f"entreprise {id} inconnue"
|
||||||
|
)
|
||||||
|
form = SiteCreationForm()
|
||||||
|
if form.validate_on_submit():
|
||||||
|
site = EntrepriseSite(
|
||||||
|
entreprise_id=entreprise.id,
|
||||||
|
nom=form.nom.data.strip(),
|
||||||
|
adresse=form.adresse.data.strip(),
|
||||||
|
codepostal=form.codepostal.data.strip(),
|
||||||
|
ville=form.ville.data.strip(),
|
||||||
|
pays=form.pays.data.strip() if form.pays.data.strip() else "FRANCE",
|
||||||
|
)
|
||||||
|
db.session.add(site)
|
||||||
|
db.session.commit()
|
||||||
|
flash("Le site a été créé et ajouté à la fiche entreprise")
|
||||||
|
return redirect(url_for("entreprises.fiche_entreprise", id=entreprise.id))
|
||||||
|
return render_template(
|
||||||
|
"entreprises/form.html",
|
||||||
|
title="Ajout site",
|
||||||
|
form=form,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route(
|
||||||
|
"/fiche_entreprise/<int:id_entreprise>/add_correspondant/<int:id_site>",
|
||||||
|
methods=["GET", "POST"],
|
||||||
|
)
|
||||||
|
@permission_required(Permission.RelationsEntreprisesChange)
|
||||||
|
def add_correspondant(id_entreprise, id_site):
|
||||||
"""
|
"""
|
||||||
Permet d'ajouter un correspondant a une entreprise
|
Permet d'ajouter un correspondant a une entreprise
|
||||||
"""
|
"""
|
||||||
entreprise = Entreprise.query.filter_by(id=id, visible=True).first_or_404(
|
entreprise = Entreprise.query.filter_by(
|
||||||
description=f"entreprise {id} inconnue"
|
id=id_entreprise, visible=True
|
||||||
|
).first_or_404(description=f"entreprise {id_entreprise} inconnue")
|
||||||
|
site = EntrepriseSite.query.filter_by(id=id_site).first_or_404(
|
||||||
|
description=f"site {id_site} inconnue"
|
||||||
)
|
)
|
||||||
form = CorrespondantsCreationForm(hidden_entreprise_id=entreprise.id)
|
form = CorrespondantsCreationForm(hidden_entreprise_id=entreprise.id)
|
||||||
if form.validate_on_submit():
|
if form.validate_on_submit():
|
||||||
for correspondant_entry in form.correspondants.entries:
|
for correspondant_entry in form.correspondants.entries:
|
||||||
correspondant = EntrepriseCorrespondant(
|
correspondant = EntrepriseCorrespondant(
|
||||||
entreprise_id=entreprise.id,
|
entreprise_id=entreprise.id,
|
||||||
|
site_id=site.id,
|
||||||
|
civilite=correspondant_entry.civilite.data,
|
||||||
nom=correspondant_entry.nom.data.strip(),
|
nom=correspondant_entry.nom.data.strip(),
|
||||||
prenom=correspondant_entry.prenom.data.strip(),
|
prenom=correspondant_entry.prenom.data.strip(),
|
||||||
telephone=correspondant_entry.telephone.data.strip(),
|
telephone=correspondant_entry.telephone.data.strip(),
|
||||||
mail=correspondant_entry.mail.data.strip(),
|
mail=correspondant_entry.mail.data.strip(),
|
||||||
poste=correspondant_entry.poste.data.strip(),
|
poste=correspondant_entry.poste.data.strip(),
|
||||||
service=correspondant_entry.service.data.strip(),
|
service=correspondant_entry.service.data.strip(),
|
||||||
|
origine=correspondant_entry.origine.data.strip(),
|
||||||
|
notes=correspondant_entry.notes.data.strip(),
|
||||||
)
|
)
|
||||||
log = EntrepriseLog(
|
log = EntrepriseLog(
|
||||||
authenticated_user=current_user.user_name,
|
authenticated_user=current_user.user_name,
|
||||||
@ -735,12 +783,15 @@ def edit_correspondant(id):
|
|||||||
hidden_correspondant_id=correspondant.id,
|
hidden_correspondant_id=correspondant.id,
|
||||||
)
|
)
|
||||||
if form.validate_on_submit():
|
if form.validate_on_submit():
|
||||||
|
correspondant.civilite = form.civilite.data
|
||||||
correspondant.nom = form.nom.data.strip()
|
correspondant.nom = form.nom.data.strip()
|
||||||
correspondant.prenom = form.prenom.data.strip()
|
correspondant.prenom = form.prenom.data.strip()
|
||||||
correspondant.telephone = form.telephone.data.strip()
|
correspondant.telephone = form.telephone.data.strip()
|
||||||
correspondant.mail = form.mail.data.strip()
|
correspondant.mail = form.mail.data.strip()
|
||||||
correspondant.poste = form.poste.data.strip()
|
correspondant.poste = form.poste.data.strip()
|
||||||
correspondant.service = form.service.data.strip()
|
correspondant.service = form.service.data.strip()
|
||||||
|
correspondant.origine = form.origine.data.strip()
|
||||||
|
correspondant.notes = form.notes.data.strip()
|
||||||
log = EntrepriseLog(
|
log = EntrepriseLog(
|
||||||
authenticated_user=current_user.user_name,
|
authenticated_user=current_user.user_name,
|
||||||
object=correspondant.entreprise_id,
|
object=correspondant.entreprise_id,
|
||||||
@ -750,15 +801,18 @@ def edit_correspondant(id):
|
|||||||
db.session.commit()
|
db.session.commit()
|
||||||
flash("Le correspondant a été modifié.")
|
flash("Le correspondant a été modifié.")
|
||||||
return redirect(
|
return redirect(
|
||||||
url_for("entreprises.fiche_entreprise", id=correspondant.entreprise.id)
|
url_for("entreprises.fiche_entreprise", id=correspondant.entreprise_id)
|
||||||
)
|
)
|
||||||
elif request.method == "GET":
|
elif request.method == "GET":
|
||||||
|
form.civilite.data = correspondant.civilite
|
||||||
form.nom.data = correspondant.nom
|
form.nom.data = correspondant.nom
|
||||||
form.prenom.data = correspondant.prenom
|
form.prenom.data = correspondant.prenom
|
||||||
form.telephone.data = correspondant.telephone
|
form.telephone.data = correspondant.telephone
|
||||||
form.mail.data = correspondant.mail
|
form.mail.data = correspondant.mail
|
||||||
form.poste.data = correspondant.poste
|
form.poste.data = correspondant.poste
|
||||||
form.service.data = correspondant.service
|
form.service.data = correspondant.service
|
||||||
|
form.origine.data = correspondant.origine
|
||||||
|
form.notes.data = correspondant.notes
|
||||||
return render_template(
|
return render_template(
|
||||||
"entreprises/form.html",
|
"entreprises/form.html",
|
||||||
title="Modification correspondant",
|
title="Modification correspondant",
|
||||||
@ -790,9 +844,10 @@ def delete_correspondant(id):
|
|||||||
url_for("entreprises.fiche_entreprise", id=correspondant.entreprise_id)
|
url_for("entreprises.fiche_entreprise", id=correspondant.entreprise_id)
|
||||||
)
|
)
|
||||||
return render_template(
|
return render_template(
|
||||||
"entreprises/delete_confirmation.html",
|
"entreprises/confirmation_form.html",
|
||||||
title="Supression correspondant",
|
title="Supression correspondant",
|
||||||
form=form,
|
form=form,
|
||||||
|
info_message="Cliquez sur le bouton Supprimer pour confirmer votre supression",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -1016,9 +1071,10 @@ def delete_stage_apprentissage(id):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
return render_template(
|
return render_template(
|
||||||
"entreprises/delete_confirmation.html",
|
"entreprises/confirmation_form.html",
|
||||||
title="Supression stage/apprentissage",
|
title="Supression stage/apprentissage",
|
||||||
form=form,
|
form=form,
|
||||||
|
info_message="Cliquez sur le bouton Supprimer pour confirmer votre supression",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -1243,12 +1299,15 @@ def export_correspondants():
|
|||||||
)
|
)
|
||||||
if correspondants:
|
if correspondants:
|
||||||
keys = [
|
keys = [
|
||||||
|
"civilite",
|
||||||
"nom",
|
"nom",
|
||||||
"prenom",
|
"prenom",
|
||||||
"telephone",
|
"telephone",
|
||||||
"mail",
|
"mail",
|
||||||
"poste",
|
"poste",
|
||||||
"service",
|
"service",
|
||||||
|
"origine",
|
||||||
|
"notes",
|
||||||
"entreprise_siret",
|
"entreprise_siret",
|
||||||
]
|
]
|
||||||
titles = keys[:]
|
titles = keys[:]
|
||||||
@ -1272,12 +1331,15 @@ def get_import_correspondants_file_sample():
|
|||||||
Permet de récupérer un fichier exemple vide pour pouvoir importer des correspondants
|
Permet de récupérer un fichier exemple vide pour pouvoir importer des correspondants
|
||||||
"""
|
"""
|
||||||
keys = [
|
keys = [
|
||||||
|
"civilite",
|
||||||
"nom",
|
"nom",
|
||||||
"prenom",
|
"prenom",
|
||||||
"telephone",
|
"telephone",
|
||||||
"mail",
|
"mail",
|
||||||
"poste",
|
"poste",
|
||||||
"service",
|
"service",
|
||||||
|
"origine",
|
||||||
|
"notes",
|
||||||
"entreprise_siret",
|
"entreprise_siret",
|
||||||
]
|
]
|
||||||
titles = keys[:]
|
titles = keys[:]
|
||||||
@ -1306,12 +1368,15 @@ def import_correspondants():
|
|||||||
correspondant_list = []
|
correspondant_list = []
|
||||||
ligne = 0
|
ligne = 0
|
||||||
titles = [
|
titles = [
|
||||||
|
"civilite",
|
||||||
"nom",
|
"nom",
|
||||||
"prenom",
|
"prenom",
|
||||||
"telephone",
|
"telephone",
|
||||||
"mail",
|
"mail",
|
||||||
"poste",
|
"poste",
|
||||||
"service",
|
"service",
|
||||||
|
"origine",
|
||||||
|
"notes",
|
||||||
"entreprise_siret",
|
"entreprise_siret",
|
||||||
]
|
]
|
||||||
if data[1][0] != titles:
|
if data[1][0] != titles:
|
||||||
@ -1326,29 +1391,32 @@ def import_correspondants():
|
|||||||
if (
|
if (
|
||||||
are.verif_correspondant_data(correspondant_data)
|
are.verif_correspondant_data(correspondant_data)
|
||||||
and (
|
and (
|
||||||
correspondant_data[0].strip(),
|
|
||||||
correspondant_data[1].strip(),
|
correspondant_data[1].strip(),
|
||||||
correspondant_data[6].strip(),
|
correspondant_data[2].strip(),
|
||||||
|
correspondant_data[9].strip(),
|
||||||
)
|
)
|
||||||
not in correspondant_list
|
not in correspondant_list
|
||||||
):
|
):
|
||||||
correspondant_list.append(
|
correspondant_list.append(
|
||||||
(
|
(
|
||||||
correspondant_data[0].strip(),
|
|
||||||
correspondant_data[1].strip(),
|
correspondant_data[1].strip(),
|
||||||
correspondant_data[6].strip(),
|
correspondant_data[2].strip(),
|
||||||
|
correspondant_data[9].strip(),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
entreprise = Entreprise.query.filter_by(
|
entreprise = Entreprise.query.filter_by(
|
||||||
siret=correspondant_data[6].strip()
|
siret=correspondant_data[9].strip()
|
||||||
).first()
|
).first()
|
||||||
correspondant = EntrepriseCorrespondant(
|
correspondant = EntrepriseCorrespondant(
|
||||||
nom=correspondant_data[0].strip(),
|
civilite=correspondant_data[0].strip(),
|
||||||
prenom=correspondant_data[1].strip(),
|
nom=correspondant_data[1].strip(),
|
||||||
telephone=correspondant_data[2].strip(),
|
prenom=correspondant_data[2].strip(),
|
||||||
mail=correspondant_data[3].strip(),
|
telephone=correspondant_data[3].strip(),
|
||||||
poste=correspondant_data[4].strip(),
|
mail=correspondant_data[4].strip(),
|
||||||
service=correspondant_data[5].strip(),
|
poste=correspondant_data[5].strip(),
|
||||||
|
service=correspondant_data[6].strip(),
|
||||||
|
origine=correspondant_data[7].strip(),
|
||||||
|
notes=correspondant_data[8].strip(),
|
||||||
entreprise_id=entreprise.id,
|
entreprise_id=entreprise.id,
|
||||||
)
|
)
|
||||||
correspondants_import.append(correspondant)
|
correspondants_import.append(correspondant)
|
||||||
@ -1480,9 +1548,10 @@ def delete_offre_file(offre_id, filedir):
|
|||||||
url_for("entreprises.fiche_entreprise", id=offre.entreprise_id)
|
url_for("entreprises.fiche_entreprise", id=offre.entreprise_id)
|
||||||
)
|
)
|
||||||
return render_template(
|
return render_template(
|
||||||
"entreprises/delete_confirmation.html",
|
"entreprises/confirmation_form.html",
|
||||||
title="Suppression fichier d'une offre",
|
title="Suppression fichier d'une offre",
|
||||||
form=form,
|
form=form,
|
||||||
|
info_message="Cliquez sur le bouton Supprimer pour confirmer votre supression",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -27,6 +27,20 @@ class Absence(db.Model):
|
|||||||
# XXX TODO: contrainte ajoutée: vérifier suppression du module
|
# XXX TODO: contrainte ajoutée: vérifier suppression du module
|
||||||
# (mettre à NULL sans supprimer)
|
# (mettre à NULL sans supprimer)
|
||||||
|
|
||||||
|
def to_dict(self):
|
||||||
|
data = {
|
||||||
|
"id": self.id,
|
||||||
|
"etudid": self.etudid,
|
||||||
|
"jour": self.jour,
|
||||||
|
"estabs": self.estabs,
|
||||||
|
"estjust": self.estjust,
|
||||||
|
"matin": self.matin,
|
||||||
|
"description": self.description,
|
||||||
|
"entry_date": self.entry_date,
|
||||||
|
"moduleimpl_id": self.moduleimpl_id,
|
||||||
|
}
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
class AbsenceNotification(db.Model):
|
class AbsenceNotification(db.Model):
|
||||||
"""Notification d'absence émise"""
|
"""Notification d'absence émise"""
|
||||||
|
@ -303,12 +303,14 @@ def YearTable(
|
|||||||
return "\n".join(T)
|
return "\n".join(T)
|
||||||
|
|
||||||
|
|
||||||
def list_abs_in_range(etudid, debut, fin, matin=None, moduleimpl_id=None, cursor=None):
|
def list_abs_in_range(
|
||||||
|
etudid, debut=None, fin=None, matin=None, moduleimpl_id=None, cursor=None
|
||||||
|
):
|
||||||
"""Liste des absences entre deux dates.
|
"""Liste des absences entre deux dates.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
etudid:
|
etudid:
|
||||||
debut: string iso date ("2020-03-12")
|
debut: string iso date ("2020-03-12") ou None
|
||||||
end: string iso date ("2020-03-12")
|
end: string iso date ("2020-03-12")
|
||||||
matin: None, True, False
|
matin: None, True, False
|
||||||
moduleimpl_id: restreint le comptage aux absences dans ce module
|
moduleimpl_id: restreint le comptage aux absences dans ce module
|
||||||
@ -335,9 +337,13 @@ def list_abs_in_range(etudid, debut, fin, matin=None, moduleimpl_id=None, cursor
|
|||||||
AND A.ESTABS"""
|
AND A.ESTABS"""
|
||||||
+ ismatin
|
+ ismatin
|
||||||
+ modul
|
+ modul
|
||||||
+ """
|
+ (
|
||||||
|
""
|
||||||
|
if debut is None
|
||||||
|
else """
|
||||||
AND A.JOUR BETWEEN %(debut)s AND %(fin)s
|
AND A.JOUR BETWEEN %(debut)s AND %(fin)s
|
||||||
""",
|
"""
|
||||||
|
),
|
||||||
{
|
{
|
||||||
"etudid": etudid,
|
"etudid": etudid,
|
||||||
"debut": debut,
|
"debut": debut,
|
||||||
@ -412,22 +418,31 @@ WHERE A.ETUDID = %(etudid)s
|
|||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
def list_abs_date(etudid, beg_date, end_date):
|
def list_abs_date(etudid, beg_date=None, end_date=None):
|
||||||
"""Liste des absences et justifs entre deux dates (inclues)."""
|
"""Liste des absences et justifs entre deux dates (inclues)."""
|
||||||
|
print("On rentre")
|
||||||
cnx = ndb.GetDBConnexion()
|
cnx = ndb.GetDBConnexion()
|
||||||
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
|
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
|
||||||
cursor.execute(
|
|
||||||
"""SELECT jour, matin, estabs, estjust, description FROM ABSENCES A
|
req = """SELECT jour, matin, estabs, estjust, description
|
||||||
WHERE A.ETUDID = %(etudid)s
|
FROM ABSENCES A
|
||||||
|
WHERE A.ETUDID = %(etudid)s""" + (
|
||||||
|
""
|
||||||
|
if beg_date is None
|
||||||
|
else """
|
||||||
AND A.jour >= %(beg_date)s
|
AND A.jour >= %(beg_date)s
|
||||||
AND A.jour <= %(end_date)s
|
AND A.jour <= %(end_date)s
|
||||||
""",
|
"""
|
||||||
|
)
|
||||||
|
cursor.execute(
|
||||||
|
req,
|
||||||
vars(),
|
vars(),
|
||||||
)
|
)
|
||||||
Abs = cursor.dictfetchall()
|
|
||||||
|
absences = cursor.dictfetchall()
|
||||||
# remove duplicates
|
# remove duplicates
|
||||||
A = {} # { (jour, matin) : abs }
|
A = {} # { (jour, matin) : abs }
|
||||||
for a in Abs:
|
for a in absences:
|
||||||
jour, matin = a["jour"], a["matin"]
|
jour, matin = a["jour"], a["matin"]
|
||||||
if (jour, matin) in A:
|
if (jour, matin) in A:
|
||||||
# garde toujours la description
|
# garde toujours la description
|
||||||
|
@ -47,6 +47,13 @@ _SCO_PERMISSIONS = (
|
|||||||
),
|
),
|
||||||
(1 << 25, "RelationsEntreprisesSend", "Envoyer des offres"),
|
(1 << 25, "RelationsEntreprisesSend", "Envoyer des offres"),
|
||||||
(1 << 26, "RelationsEntreprisesValidate", "Valide les entreprises"),
|
(1 << 26, "RelationsEntreprisesValidate", "Valide les entreprises"),
|
||||||
|
(1 << 27, "RelationsEntreprisesCorrespondants", "Voir les correspondants"),
|
||||||
|
# 27 à 39 ... réservé pour "entreprises"
|
||||||
|
# Api scodoc9
|
||||||
|
(1 << 40, "APIView", "Voir"),
|
||||||
|
(1 << 41, "APIEtudChangeGroups", "Modifier les groupes"),
|
||||||
|
(1 << 42, "APIEditAllNotes", "Modifier toutes les notes"),
|
||||||
|
(1 << 43, "APIAbsChange", "Saisir des absences"),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -53,6 +53,7 @@ SCO_ROLES_DEFAULTS = {
|
|||||||
p.ScoUsersAdmin,
|
p.ScoUsersAdmin,
|
||||||
p.ScoUsersView,
|
p.ScoUsersView,
|
||||||
p.ScoView,
|
p.ScoView,
|
||||||
|
p.APIView,
|
||||||
),
|
),
|
||||||
# RespPE est le responsable poursuites d'études
|
# RespPE est le responsable poursuites d'études
|
||||||
# il peut ajouter des tags sur les formations:
|
# il peut ajouter des tags sur les formations:
|
||||||
@ -62,7 +63,11 @@ SCO_ROLES_DEFAULTS = {
|
|||||||
# ObservateurEntreprise est un observateur de l'application entreprise
|
# ObservateurEntreprise est un observateur de l'application entreprise
|
||||||
"ObservateurEntreprise": (p.RelationsEntreprisesView,),
|
"ObservateurEntreprise": (p.RelationsEntreprisesView,),
|
||||||
# UtilisateurEntreprise est un utilisateur de l'application entreprise (droit de modification)
|
# UtilisateurEntreprise est un utilisateur de l'application entreprise (droit de modification)
|
||||||
"UtilisateurEntreprise": (p.RelationsEntreprisesView, p.RelationsEntreprisesChange),
|
"UtilisateurEntreprise": (
|
||||||
|
p.RelationsEntreprisesView,
|
||||||
|
p.RelationsEntreprisesChange,
|
||||||
|
p.RelationsEntreprisesCorrespondants,
|
||||||
|
),
|
||||||
# AdminEntreprise est un admin de l'application entreprise (toutes les actions possibles de l'application)
|
# AdminEntreprise est un admin de l'application entreprise (toutes les actions possibles de l'application)
|
||||||
"AdminEntreprise": (
|
"AdminEntreprise": (
|
||||||
p.RelationsEntreprisesView,
|
p.RelationsEntreprisesView,
|
||||||
@ -70,7 +75,10 @@ SCO_ROLES_DEFAULTS = {
|
|||||||
p.RelationsEntreprisesExport,
|
p.RelationsEntreprisesExport,
|
||||||
p.RelationsEntreprisesSend,
|
p.RelationsEntreprisesSend,
|
||||||
p.RelationsEntreprisesValidate,
|
p.RelationsEntreprisesValidate,
|
||||||
|
p.RelationsEntreprisesCorrespondants,
|
||||||
),
|
),
|
||||||
|
# LecteurAPI peut utiliser l'API en lecture
|
||||||
|
"LecteurAPI": (p.APIView,),
|
||||||
# Super Admin est un root: création/suppression de départements
|
# Super Admin est un root: création/suppression de départements
|
||||||
# _tous_ les droits
|
# _tous_ les droits
|
||||||
# Afin d'avoir tous les droits, il ne doit pas être asscoié à un département
|
# Afin d'avoir tous les droits, il ne doit pas être asscoié à un département
|
||||||
@ -85,4 +93,5 @@ ROLES_ATTRIBUABLES_SCODOC = (
|
|||||||
"ObservateurEntreprise",
|
"ObservateurEntreprise",
|
||||||
"UtilisateurEntreprise",
|
"UtilisateurEntreprise",
|
||||||
"AdminEntreprise",
|
"AdminEntreprise",
|
||||||
|
"LecteurAPI",
|
||||||
)
|
)
|
||||||
|
@ -40,6 +40,11 @@
|
|||||||
*background-color: #151515;
|
*background-color: #151515;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.btn-remove {
|
||||||
|
margin-top: 5px;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
.fiche-entreprise .btn {
|
.fiche-entreprise .btn {
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
margin-bottom: 5px;
|
margin-bottom: 5px;
|
||||||
@ -54,23 +59,24 @@
|
|||||||
margin-bottom: -5px;
|
margin-bottom: -5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.entreprise, .correspondant, .offre {
|
.entreprise, .correspondant, .offre, .site{
|
||||||
border: solid 2px;
|
border: solid 2px;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
|
margin-top: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.correspondants-et-offres {
|
.sites-et-offres {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
|
|
||||||
.correspondants-et-offres > div {
|
.sites-et-offres > div {
|
||||||
flex: 1 0 0;
|
flex: 1 0 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.correspondants-et-offres > div:nth-child(2) {
|
.sites-et-offres > div:nth-child(2) {
|
||||||
margin-left: 20px;
|
margin-left: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
{# -*- mode: jinja-html -*- #}
|
{# -*- mode: jinja-html -*- #}
|
||||||
<div class="correspondant">
|
<div class="correspondant">
|
||||||
<div>
|
<div>
|
||||||
|
Civilité : {{ correspondant.civilite|get_civilité }}<br>
|
||||||
Nom : {{ correspondant.nom }}<br>
|
Nom : {{ correspondant.nom }}<br>
|
||||||
Prénom : {{ correspondant.prenom }}<br>
|
Prénom : {{ correspondant.prenom }}<br>
|
||||||
{% if correspondant.telephone %}
|
{% if correspondant.telephone %}
|
||||||
@ -15,6 +16,12 @@
|
|||||||
{% if correspondant.service %}
|
{% if correspondant.service %}
|
||||||
Service : {{ correspondant.service }}<br>
|
Service : {{ correspondant.service }}<br>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if correspondant.origine %}
|
||||||
|
Origine : {{ correspondant.origine }}<br>
|
||||||
|
{% endif %}
|
||||||
|
{% if correspondant.notes %}
|
||||||
|
Notes : {{ correspondant.notes }}<br>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %}
|
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{# -*- mode: jinja-html -*- #}
|
{# -*- mode: jinja-html -*- #}
|
||||||
<div class="offre">
|
<div class="offre">
|
||||||
<div>
|
<div style="word-break:break-all; text-align: justify;">
|
||||||
Ajouté le {{ offre[0].date_ajout.strftime('%d/%m/%y') }} à {{ offre[0].date_ajout.strftime('%Hh%M') }}<br>
|
Ajouté le {{ offre[0].date_ajout.strftime('%d/%m/%y') }} à {{ offre[0].date_ajout.strftime('%Hh%M') }}<br>
|
||||||
Intitulé : {{ offre[0].intitule }}<br>
|
Intitulé : {{ offre[0].intitule }}<br>
|
||||||
Description : {{ offre[0].description }}<br>
|
Description : {{ offre[0].description }}<br>
|
||||||
|
@ -35,6 +35,14 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
let allCorrepondantsFieldWrapper = document.getElementById('correspondants');
|
||||||
|
let allCorrepondantsForm = allCorrepondantsFieldWrapper.getElementsByTagName('li');
|
||||||
|
for(let i = 0; i < allCorrepondantsForm.length; i++) {
|
||||||
|
let form_id = allCorrepondantsForm[i].getElementsByTagName('table')[0].id
|
||||||
|
if(form_id.split('-')[1] != 0)
|
||||||
|
allCorrepondantsForm[i].insertAdjacentHTML('beforeend', `<div class="btn btn-default btn-remove" onclick="deleteForm('${form_id}')">Retirer ce correspondant</div>`)
|
||||||
|
}
|
||||||
|
|
||||||
window.onload = function(e) {
|
window.onload = function(e) {
|
||||||
let addCorrespondantFieldBtn = document.getElementById('add-correspondant-field');
|
let addCorrespondantFieldBtn = document.getElementById('add-correspondant-field');
|
||||||
addCorrespondantFieldBtn.addEventListener('click', function(e){
|
addCorrespondantFieldBtn.addEventListener('click', function(e){
|
||||||
@ -48,9 +56,16 @@
|
|||||||
}
|
}
|
||||||
let newFieldName = `correspondants-${Math.max(...correspondantInputIds) + 1}`;
|
let newFieldName = `correspondants-${Math.max(...correspondantInputIds) + 1}`;
|
||||||
allCorrepondantsFieldWrapper.insertAdjacentHTML('beforeend',`
|
allCorrepondantsFieldWrapper.insertAdjacentHTML('beforeend',`
|
||||||
<li><label for="${newFieldName}">Correspondants-${Math.max(...correspondantInputIds) + 1}</label> <table id="${newFieldName}"><tr><th><label for="${newFieldName}-nom">Nom (*)</label></th><td><input class="form-control" id="${newFieldName}-nom" name="${newFieldName}-nom" required type="text" value=""></td></tr><tr><th><label for="${newFieldName}-prenom">Prénom (*)</label></th><td><input class="form-control" id="${newFieldName}-prenom" name="${newFieldName}-prenom" required type="text" value=""></td></tr><tr><th><label for="${newFieldName}-telephone">Téléphone (*)</label></th><td><input class="form-control" id="${newFieldName}-telephone" name="${newFieldName}-telephone" type="text" value=""></td></tr><tr><th><label for="${newFieldName}-mail">Mail (*)</label></th><td><input class="form-control" id="${newFieldName}-mail" name="${newFieldName}-mail" type="text" value=""></td></tr><tr><th><label for="${newFieldName}-poste">Poste</label></th><td><input class="form-control" id="${newFieldName}-poste" name="${newFieldName}-poste" type="text" value=""></td></tr><tr><th><label for="${newFieldName}-service">Service</label></th><td><input class="form-control" id="${newFieldName}-service" name="${newFieldName}-service" type="text" value=""></td></tr></table><input id="${newFieldName}-csrf_token" name="${newFieldName}-csrf_token" type="hidden" value=${csrf_token}></li>
|
<li><label for="${newFieldName}">Correspondants-${Math.max(...correspondantInputIds) + 1}</label><table id="${newFieldName}"><tr><th><label for="${newFieldName}-civilite">Civilité (*)</label></th><td><select class="form-control" id="${newFieldName}-civilite" name="${newFieldName}-civilite" required><option value="H">Monsieur</option><option value="F">Madame</option></select></td></tr><tr><th><label for="${newFieldName}-nom">Nom (*)</label></th><td><input class="form-control" id="${newFieldName}-nom" name="${newFieldName}-nom" required type="text" value=""></td></tr><tr><th><label for="${newFieldName}-prenom">Prénom (*)</label></th><td><input class="form-control" id="${newFieldName}-prenom" name="${newFieldName}-prenom" required type="text" value=""></td></tr><tr><th><label for="${newFieldName}-telephone">Téléphone (*)</label></th><td><input class="form-control" id="${newFieldName}-telephone" name="${newFieldName}-telephone" type="text" value=""></td></tr><tr><th><label for="${newFieldName}-mail">Mail (*)</label></th><td><input class="form-control" id="${newFieldName}-mail" name="${newFieldName}-mail" type="text" value=""></td></tr><tr><th><label for="${newFieldName}-poste">Poste</label></th><td><input class="form-control" id="${newFieldName}-poste" name="${newFieldName}-poste" type="text" value=""></td></tr><tr><th><label for="${newFieldName}-service">Service</label></th><td><input class="form-control" id="${newFieldName}-service" name="${newFieldName}-service" type="text" value=""></td></tr><tr><th><label for="${newFieldName}-origine">Origine</label></th><td><input class="form-control" id="${newFieldName}-origine" name="${newFieldName}-origine" type="text" value=""></td></tr><tr><th><label for="${newFieldName}-notes">Notes</label></th><td><input class="form-control" id="${newFieldName}-notes" name="${newFieldName}-notes" type="text" value=""></td></tr></table><input id="${newFieldName}-csrf_token" name="${newFieldName}-csrf_token" type="hidden" value=${csrf_token}><div class="btn btn-default btn-remove" onclick="deleteForm('${newFieldName}')">Retirer ce correspondant</div></li>
|
||||||
`);
|
`);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function deleteForm(x) {
|
||||||
|
var li_form = document.querySelector(`label[for=${x}]`).closest('li');
|
||||||
|
if (li_form) {
|
||||||
|
li_form.remove()
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
@ -5,7 +5,7 @@
|
|||||||
{% block app_content %}
|
{% block app_content %}
|
||||||
<h1>{{ title }}</h1>
|
<h1>{{ title }}</h1>
|
||||||
<br>
|
<br>
|
||||||
<div style="color:red;">Cliquez sur le bouton Supprimer pour confirmer votre supression</div>
|
<div style="color:red;">{{ info_message }}</div>
|
||||||
<br>
|
<br>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
@ -67,7 +67,7 @@
|
|||||||
</a>
|
</a>
|
||||||
<ul class="dropdown-menu pull-left">
|
<ul class="dropdown-menu pull-left">
|
||||||
<li><a href="{{ url_for('entreprises.edit_entreprise', id=entreprise.id) }}">Modifier</a></li>
|
<li><a href="{{ url_for('entreprises.edit_entreprise', id=entreprise.id) }}">Modifier</a></li>
|
||||||
<li><a href="{{ url_for('entreprises.delete_entreprise', id=entreprise.id) }}" style="color:red">Supprimer</a></li>
|
<li><a href="{{ url_for('entreprises.fiche_entreprise_desactiver', id=entreprise.id)}}" style="color:red">Désactiver</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
@ -36,6 +36,14 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
let allResponsablesFieldWrapper = document.getElementById('responsables');
|
||||||
|
let allResponsablesField = allResponsablesFieldWrapper.getElementsByTagName('li');
|
||||||
|
for(let i = 0; i < allResponsablesField.length; i++) {
|
||||||
|
let form_id = allResponsablesField[i].getElementsByTagName('input')[0].id
|
||||||
|
if(form_id.split('-')[1] != 0)
|
||||||
|
allResponsablesField[i].insertAdjacentHTML('beforeend', `<div class="btn btn-default btn-remove" onclick="deleteForm('${form_id}')">Retirer</div>`)
|
||||||
|
}
|
||||||
|
|
||||||
window.onload = function(e) {
|
window.onload = function(e) {
|
||||||
var responsables_options = {
|
var responsables_options = {
|
||||||
script: "/ScoDoc/entreprises/responsables?",
|
script: "/ScoDoc/entreprises/responsables?",
|
||||||
@ -63,10 +71,17 @@
|
|||||||
}
|
}
|
||||||
let newFieldName = `responsables-${Math.max(...responsableInputIds) + 1}`;
|
let newFieldName = `responsables-${Math.max(...responsableInputIds) + 1}`;
|
||||||
allResponsablesFieldWrapper.insertAdjacentHTML('beforeend',`
|
allResponsablesFieldWrapper.insertAdjacentHTML('beforeend',`
|
||||||
<li><label for="${newFieldName}">Responsable (*)</label> <input class="form-control" id="${newFieldName}" name="${newFieldName}" type="text" value="" placeholder="Tapez le nom du responsable de formation"></li>
|
<li><label for="${newFieldName}">Responsable (*)</label><input class="form-control" id="${newFieldName}" name="${newFieldName}" type="text" value="" placeholder="Tapez le nom du responsable de formation"><div class="btn btn-default btn-remove" onclick="deleteForm('${newFieldName}')">Retirer</div></li>
|
||||||
`);
|
`);
|
||||||
var as_r = new bsn.AutoSuggest(newFieldName, responsables_options);
|
var as_r = new bsn.AutoSuggest(newFieldName, responsables_options);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function deleteForm(x) {
|
||||||
|
var li_form = document.querySelector(`label[for=${x}]`).closest('li');
|
||||||
|
if (li_form) {
|
||||||
|
li_form.remove()
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
@ -37,25 +37,39 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %}
|
|
||||||
<div>
|
<div>
|
||||||
|
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %}
|
||||||
<a class="btn btn-primary" href="{{ url_for('entreprises.edit_entreprise', id=entreprise.id) }}">Modifier</a>
|
<a class="btn btn-primary" href="{{ url_for('entreprises.edit_entreprise', id=entreprise.id) }}">Modifier</a>
|
||||||
<a class="btn btn-danger" href="{{ url_for('entreprises.delete_entreprise', id=entreprise.id) }}">Supprimer</a>
|
<a class="btn btn-danger" href="{{ url_for('entreprises.fiche_entreprise_desactiver', id=entreprise.id) }}">Désactiver</a>
|
||||||
|
<a class="btn btn-primary" href="{{ url_for('entreprises.add_site', id=entreprise.id) }}">Ajouter site</a>
|
||||||
<a class="btn btn-primary" href="{{ url_for('entreprises.add_offre', id=entreprise.id) }}">Ajouter offre</a>
|
<a class="btn btn-primary" href="{{ url_for('entreprises.add_offre', id=entreprise.id) }}">Ajouter offre</a>
|
||||||
<a class="btn btn-primary" href="{{ url_for('entreprises.add_correspondant', id=entreprise.id) }}">Ajouter correspondant</a>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<a class="btn btn-primary" href="{{ url_for('entreprises.contacts', id=entreprise.id) }}">Liste contacts</a>
|
<a class="btn btn-primary" href="{{ url_for('entreprises.contacts', id=entreprise.id) }}">Liste contacts</a>
|
||||||
<a class="btn btn-primary" href="{{ url_for('entreprises.offres_expirees', id=entreprise.id) }}">Voir les offres expirées</a>
|
<a class="btn btn-primary" href="{{ url_for('entreprises.offres_expirees', id=entreprise.id) }}">Voir les offres expirées</a>
|
||||||
<div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div class="correspondants-et-offres">
|
<div class="sites-et-offres">
|
||||||
{% if correspondants %}
|
{% if sites %}
|
||||||
<div>
|
<div>
|
||||||
<h3>Correspondants</h3>
|
<h3>Sites</h3>
|
||||||
{% for correspondant in correspondants %}
|
{% for site in sites %}
|
||||||
|
<div class="site">
|
||||||
|
Nom : {{ site.nom }}<br>
|
||||||
|
Adresse : {{ site.adresse }}<br>
|
||||||
|
Code postal : {{ site.codepostal }}<br>
|
||||||
|
Ville : {{ site.ville }}<br>
|
||||||
|
Pays : {{ site.pays }}
|
||||||
|
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %}
|
||||||
|
<br><a class="btn btn-primary" href="{{ url_for('entreprises.add_correspondant', id_entreprise=entreprise.id, id_site=site.id) }}">Ajouter correspondant</a>
|
||||||
|
{% endif %}
|
||||||
|
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesCorrespondants, None) %}
|
||||||
|
{% for correspondant in site.correspondants %}
|
||||||
{% include 'entreprises/_correspondant.html' %}
|
{% include 'entreprises/_correspondant.html' %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
@ -71,20 +85,20 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="margin-bottom: 10px;">
|
<div style="margin-bottom: 10px;">
|
||||||
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %}
|
|
||||||
<a class="btn btn-primary" href="{{ url_for('entreprises.add_stage_apprentissage', id=entreprise.id) }}">Ajouter stage ou apprentissage</a>
|
|
||||||
{% endif %}
|
|
||||||
<h3>Liste des stages et apprentissages réalisés au sein de l'entreprise</h3>
|
<h3>Liste des stages et apprentissages réalisés au sein de l'entreprise</h3>
|
||||||
|
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %}
|
||||||
|
<a class="btn btn-primary" href="{{ url_for('entreprises.add_stage_apprentissage', id=entreprise.id) }}" style="margin-bottom:10px;">Ajouter stage ou apprentissage</a>
|
||||||
|
{% endif %}
|
||||||
<table id="table-stages-apprentissages">
|
<table id="table-stages-apprentissages">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<td data-priority="">Date début</td>
|
<td data-priority="3">Date début</td>
|
||||||
<td data-priority="">Date fin</td>
|
<td data-priority="4">Date fin</td>
|
||||||
<td data-priority="">Durée</td>
|
<td data-priority="5">Durée</td>
|
||||||
<td data-priority="">Type</td>
|
<td data-priority="2">Type</td>
|
||||||
<td data-priority="">Étudiant</td>
|
<td data-priority="1">Étudiant</td>
|
||||||
<td data-priority="">Formation</td>
|
<td data-priority="6">Formation</td>
|
||||||
<td data-priority="">Notes</td>
|
<td data-priority="7">Notes</td>
|
||||||
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %}
|
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %}
|
||||||
<td data-priority="3">Action</td>
|
<td data-priority="3">Action</td>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -23,15 +23,15 @@
|
|||||||
<script>
|
<script>
|
||||||
{# pour les formulaires offre #}
|
{# pour les formulaires offre #}
|
||||||
var champ_depts = document.getElementById("depts")
|
var champ_depts = document.getElementById("depts")
|
||||||
if (champ_depts !== null) {
|
if (champ_depts) {
|
||||||
var closest_form_control = champ_depts.closest(".form-control")
|
var closest_form_control = champ_depts.closest(".form-control")
|
||||||
closest_form_control.classList.remove("form-control")
|
closest_form_control.classList.remove("form-control")
|
||||||
}
|
}
|
||||||
|
|
||||||
if(document.getElementById("expiration_date") !== null && document.getElementById("expiration_date").value === "")
|
if(document.getElementById("expiration_date") && document.getElementById("expiration_date").value === "")
|
||||||
expiration()
|
expiration()
|
||||||
|
|
||||||
if(document.getElementById("type_offre") !== null)
|
if(document.getElementById("type_offre"))
|
||||||
document.getElementById("type_offre").addEventListener("change", expiration);
|
document.getElementById("type_offre").addEventListener("change", expiration);
|
||||||
|
|
||||||
function expiration() {
|
function expiration() {
|
||||||
|
@ -25,13 +25,16 @@
|
|||||||
{% if not correspondants_import %}
|
{% if not correspondants_import %}
|
||||||
<table class="table">
|
<table class="table">
|
||||||
<thead><tr><td><b>Attribut</b></td><td><b>Type</b></td><td><b>Description</b></td></tr></thead>
|
<thead><tr><td><b>Attribut</b></td><td><b>Type</b></td><td><b>Description</b></td></tr></thead>
|
||||||
|
<tr><td>civilite</td><td>text</td><td>civilite du correspondant (H ou F)</td></tr>
|
||||||
<tr><td>nom</td><td>text</td><td>nom du correspondant</td></tr>
|
<tr><td>nom</td><td>text</td><td>nom du correspondant</td></tr>
|
||||||
<tr><td>prenom</td><td>text</td><td>prenom du correspondant</td></tr>
|
<tr><td>prenom</td><td>text</td><td>prenom du correspondant</td></tr>
|
||||||
<tr><td>telephone</td><td>text</td><td>telephone du correspondant</td></tr>
|
<tr><td>telephone</td><td>text</td><td>telephone du correspondant</td></tr>
|
||||||
<tr><td>mail</td><td>text</td><td>mail du correspondant</td></tr>
|
<tr><td>mail</td><td>text</td><td>mail du correspondant</td></tr>
|
||||||
<tr><td>poste</td><td>text</td><td>poste du correspondant</td></tr>
|
<tr><td>poste</td><td>text</td><td>poste du correspondant</td></tr>
|
||||||
<tr><td>service</td><td>text</td><td>service dans lequel travaille le correspondant</td></tr>
|
<tr><td>service</td><td>text</td><td>service dans lequel travaille le correspondant</td></tr>
|
||||||
<tr><td>entreprise_siret</td><td>integer</td><td>SIRET de l'entreprise</td></tr>
|
<tr><td>origine</td><td>text</td><td>origine du correspondant</td></tr>
|
||||||
|
<tr><td>notes</td><td>text</td><td>notes sur le correspondant</td></tr>
|
||||||
|
<tr><td>entreprise_siret</td><td>text</td><td>SIRET de l'entreprise</td></tr>
|
||||||
</table>
|
</table>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
@ -40,6 +43,7 @@
|
|||||||
{% for correspondant in correspondants_import %}
|
{% for correspondant in correspondants_import %}
|
||||||
<div class="correspondant">
|
<div class="correspondant">
|
||||||
<div>
|
<div>
|
||||||
|
Civilité : {{ correspondant.civilite|get_civilité }}<br>
|
||||||
Nom : {{ correspondant.nom }}<br>
|
Nom : {{ correspondant.nom }}<br>
|
||||||
Prénom : {{ correspondant.prenom }}<br>
|
Prénom : {{ correspondant.prenom }}<br>
|
||||||
{% if correspondant.telephone %}
|
{% if correspondant.telephone %}
|
||||||
@ -54,7 +58,13 @@
|
|||||||
{% if correspondant.service %}
|
{% if correspondant.service %}
|
||||||
Service : {{ correspondant.service }}<br>
|
Service : {{ correspondant.service }}<br>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<a href="{{ url_for('entreprises.fiche_entreprise', id=correspondant.entreprise_id )}}">lien vers l'entreprise</a>
|
{% if correspondant.origine %}
|
||||||
|
Origine : {{ correspondant.origine }}<br>
|
||||||
|
{% endif %}
|
||||||
|
{% if correspondant.notes %}
|
||||||
|
Notes : {{ correspondant.notes }}<br>
|
||||||
|
{% endif %}
|
||||||
|
<a href="{{ url_for('entreprises.fiche_entreprise', id=correspondant.entreprise_id )}}" target="_blank">lien vers l'entreprise</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
@ -2,7 +2,9 @@
|
|||||||
<nav class="nav-entreprise">
|
<nav class="nav-entreprise">
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="{{ url_for('entreprises.index') }}">Entreprises</a></li>
|
<li><a href="{{ url_for('entreprises.index') }}">Entreprises</a></li>
|
||||||
|
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesCorrespondants, None) %}
|
||||||
<li><a href="{{ url_for('entreprises.correspondants') }}">Correspondants</a></li>
|
<li><a href="{{ url_for('entreprises.correspondants') }}">Correspondants</a></li>
|
||||||
|
{% endif %}
|
||||||
<li><a href="{{ url_for('entreprises.offres_recues') }}">Offres reçues</a></li>
|
<li><a href="{{ url_for('entreprises.offres_recues') }}">Offres reçues</a></li>
|
||||||
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesValidate, None) %}
|
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesValidate, None) %}
|
||||||
<li><a href="{{ url_for('entreprises.validation') }}">Entreprises à valider</a></li>
|
<li><a href="{{ url_for('entreprises.validation') }}">Entreprises à valider</a></li>
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
{% if offres_recues %}
|
{% if offres_recues %}
|
||||||
{% for offre in offres_recues %}
|
{% for offre in offres_recues %}
|
||||||
<div class="offre offre-recue">
|
<div class="offre offre-recue">
|
||||||
<div>
|
<div style="word-break:break-all; text-align: justify;">
|
||||||
Envoyé le {{ offre[0].date_envoi.strftime('%d/%m/%Y') }} à {{ offre[0].date_envoi.strftime('%Hh%M') }} par {{ offre[0].sender_id|get_nomcomplet_by_id }}<br>
|
Envoyé le {{ offre[0].date_envoi.strftime('%d/%m/%Y') }} à {{ offre[0].date_envoi.strftime('%Hh%M') }} par {{ offre[0].sender_id|get_nomcomplet_by_id }}<br>
|
||||||
Intitulé : {{ offre[1].intitule }}<br>
|
Intitulé : {{ offre[1].intitule }}<br>
|
||||||
Description : {{ offre[1].description }}<br>
|
Description : {{ offre[1].description }}<br>
|
||||||
@ -20,12 +20,20 @@
|
|||||||
{% if offre[1].correspondant_id %}
|
{% if offre[1].correspondant_id %}
|
||||||
Contacté {{ offre[3].nom }} {{ offre[3].prenom }}
|
Contacté {{ offre[3].nom }} {{ offre[3].prenom }}
|
||||||
{% if offre[3].mail and offre[3].telephone %}
|
{% if offre[3].mail and offre[3].telephone %}
|
||||||
({{ offre[3].mail }} - {{ offre[3].telephone }})<br>
|
({{ offre[3].mail }} - {{ offre[3].telephone }})
|
||||||
{% else %}
|
{% else %}
|
||||||
({{ offre[3].mail }}{{offre[3].telephone}})<br>
|
({{ offre[3].mail }}{{ offre[3].telephone }})
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
{% if offre[3].poste %}
|
||||||
|
, poste : {{ offre[3].poste }}
|
||||||
|
{% endif %}
|
||||||
|
{% if offre[3].service %}
|
||||||
|
, service : {{ offre[3].service }}
|
||||||
|
{% endif %}
|
||||||
|
<br>
|
||||||
|
|
||||||
<a href="{{ url_for('entreprises.fiche_entreprise', id=offre[1].entreprise_id) }}">lien vers l'entreprise</a><br>
|
<a href="{{ url_for('entreprises.fiche_entreprise', id=offre[1].entreprise_id) }}">lien vers l'entreprise</a><br>
|
||||||
|
|
||||||
{% for fichier in offre[2] %}
|
{% for fichier in offre[2] %}
|
||||||
|
@ -0,0 +1,65 @@
|
|||||||
|
"""ajout colonnes tables relations entreprises, sites
|
||||||
|
|
||||||
|
Revision ID: d5b3bdd1d622
|
||||||
|
Revises: e97b2a10f86c
|
||||||
|
Create Date: 2022-04-25 18:29:50.841280
|
||||||
|
|
||||||
|
"""
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = "d5b3bdd1d622"
|
||||||
|
down_revision = "e97b2a10f86c"
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.create_table(
|
||||||
|
"are_sites",
|
||||||
|
sa.Column("id", sa.Integer(), nullable=False),
|
||||||
|
sa.Column("entreprise_id", sa.Integer(), nullable=True),
|
||||||
|
sa.Column("nom", sa.Text(), nullable=True),
|
||||||
|
sa.Column("adresse", sa.Text(), nullable=True),
|
||||||
|
sa.Column("codepostal", sa.Text(), nullable=True),
|
||||||
|
sa.Column("ville", sa.Text(), nullable=True),
|
||||||
|
sa.Column("pays", sa.Text(), nullable=True),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["entreprise_id"], ["are_entreprises.id"], ondelete="cascade"
|
||||||
|
),
|
||||||
|
sa.PrimaryKeyConstraint("id"),
|
||||||
|
)
|
||||||
|
op.add_column(
|
||||||
|
"are_correspondants", sa.Column("site_id", sa.Integer(), nullable=True)
|
||||||
|
)
|
||||||
|
op.add_column(
|
||||||
|
"are_correspondants", sa.Column("civilite", sa.String(length=1), nullable=True)
|
||||||
|
)
|
||||||
|
op.add_column("are_correspondants", sa.Column("origine", sa.Text(), nullable=True))
|
||||||
|
op.add_column("are_correspondants", sa.Column("notes", sa.Text(), nullable=True))
|
||||||
|
op.create_foreign_key(
|
||||||
|
None, "are_correspondants", "are_sites", ["site_id"], ["id"], ondelete="cascade"
|
||||||
|
)
|
||||||
|
op.add_column("are_entreprises", sa.Column("active", sa.Boolean(), nullable=True))
|
||||||
|
op.add_column(
|
||||||
|
"are_entreprises", sa.Column("notes_active", sa.Text(), nullable=True)
|
||||||
|
)
|
||||||
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.drop_column("are_entreprises", "notes_active")
|
||||||
|
op.drop_column("are_entreprises", "active")
|
||||||
|
op.drop_constraint(
|
||||||
|
"are_correspondants_site_id_fkey", "are_correspondants", type_="foreignkey"
|
||||||
|
)
|
||||||
|
op.drop_column("are_correspondants", "notes")
|
||||||
|
op.drop_column("are_correspondants", "origine")
|
||||||
|
op.drop_column("are_correspondants", "civilite")
|
||||||
|
op.drop_column("are_correspondants", "site_id")
|
||||||
|
op.drop_table("are_sites")
|
||||||
|
# ### end Alembic commands ###
|
@ -93,7 +93,9 @@ def upgrade():
|
|||||||
|
|
||||||
def downgrade():
|
def downgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.drop_constraint(None, "are_offres", type_="foreignkey")
|
op.drop_constraint(
|
||||||
|
"are_offres_correspondant_id_fkey", "are_offres", type_="foreignkey"
|
||||||
|
)
|
||||||
op.drop_column("are_offres", "correspondant_id")
|
op.drop_column("are_offres", "correspondant_id")
|
||||||
op.add_column(
|
op.add_column(
|
||||||
"are_contacts",
|
"are_contacts",
|
||||||
@ -121,8 +123,10 @@ def downgrade():
|
|||||||
op.add_column(
|
op.add_column(
|
||||||
"are_contacts", sa.Column("nom", sa.TEXT(), autoincrement=False, nullable=True)
|
"are_contacts", sa.Column("nom", sa.TEXT(), autoincrement=False, nullable=True)
|
||||||
)
|
)
|
||||||
op.drop_constraint(None, "are_contacts", type_="foreignkey")
|
op.drop_constraint(
|
||||||
op.drop_constraint(None, "are_contacts", type_="foreignkey")
|
"are_contacts_entreprise_fkey", "are_contacts", type_="foreignkey"
|
||||||
|
)
|
||||||
|
op.drop_constraint("are_contacts_user_fkey", "are_contacts", type_="foreignkey")
|
||||||
op.create_foreign_key(
|
op.create_foreign_key(
|
||||||
"are_contacts_entreprise_id_fkey",
|
"are_contacts_entreprise_id_fkey",
|
||||||
"are_contacts",
|
"are_contacts",
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# -*- mode: python -*-
|
# -*- mode: python -*-
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
SCOVERSION = "9.2.12"
|
SCOVERSION = "9.2.14"
|
||||||
|
|
||||||
SCONAME = "ScoDoc"
|
SCONAME = "ScoDoc"
|
||||||
|
|
||||||
|
@ -73,7 +73,9 @@ token = r.json()["token"]
|
|||||||
HEADERS = {"Authorization": f"Bearer {token}"}
|
HEADERS = {"Authorization": f"Bearer {token}"}
|
||||||
|
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
SCODOC_URL + "/ScoDoc/api/list_depts", headers=HEADERS, verify=CHECK_CERTIFICATE
|
SCODOC_URL + "/ScoDoc/api/list_depts",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
)
|
)
|
||||||
if r.status_code != 200:
|
if r.status_code != 200:
|
||||||
raise ScoError("erreur de connexion: vérifier adresse et identifiants")
|
raise ScoError("erreur de connexion: vérifier adresse et identifiants")
|
||||||
|
37
tests/api/setup_test_api.py
Normal file
37
tests/api/setup_test_api.py
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
"""Test Logos
|
||||||
|
|
||||||
|
Utilisation :
|
||||||
|
créer les variables d'environnement: (indiquer les valeurs
|
||||||
|
pour le serveur ScoDoc que vous voulez interroger)
|
||||||
|
|
||||||
|
export SCODOC_URL="https://scodoc.xxx.net/"
|
||||||
|
export SCODOC_USER="xxx"
|
||||||
|
export SCODOC_PASSWD="xxx"
|
||||||
|
export CHECK_CERTIFICATE=0 # ou 1 si serveur de production avec certif SSL valide
|
||||||
|
|
||||||
|
(on peut aussi placer ces valeurs dans un fichier .env du répertoire tests/api).
|
||||||
|
"""
|
||||||
|
import os
|
||||||
|
import requests
|
||||||
|
|
||||||
|
|
||||||
|
SCODOC_USER = "test"
|
||||||
|
SCODOC_PASSWORD = "test"
|
||||||
|
SCODOC_URL = "http://192.168.1.12:5000"
|
||||||
|
CHECK_CERTIFICATE = bool(int(os.environ.get("CHECK_CERTIFICATE", False)))
|
||||||
|
|
||||||
|
|
||||||
|
def get_token():
|
||||||
|
"""
|
||||||
|
Permet de set le token dans le header
|
||||||
|
"""
|
||||||
|
r0 = requests.post(
|
||||||
|
SCODOC_URL + "/ScoDoc/api/tokens", auth=(SCODOC_USER, SCODOC_PASSWORD)
|
||||||
|
)
|
||||||
|
token = r0.json()["token"]
|
||||||
|
return {"Authorization": f"Bearer {token}"}
|
||||||
|
|
||||||
|
|
||||||
|
HEADERS = get_token()
|
80
tests/api/test_api_absences.py
Normal file
80
tests/api/test_api_absences.py
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
"""Test Logos
|
||||||
|
|
||||||
|
Utilisation :
|
||||||
|
créer les variables d'environnement: (indiquer les valeurs
|
||||||
|
pour le serveur ScoDoc que vous voulez interroger)
|
||||||
|
|
||||||
|
export SCODOC_URL="https://scodoc.xxx.net/"
|
||||||
|
export SCODOC_USER="xxx"
|
||||||
|
export SCODOC_PASSWD="xxx"
|
||||||
|
export CHECK_CERTIFICATE=0 # ou 1 si serveur de production avec certif SSL valide
|
||||||
|
|
||||||
|
(on peut aussi placer ces valeurs dans un fichier .env du répertoire tests/api).
|
||||||
|
|
||||||
|
Lancer :
|
||||||
|
pytest tests/api/test_api_absences.py
|
||||||
|
"""
|
||||||
|
|
||||||
|
import requests
|
||||||
|
from tests.api.setup_test_api import SCODOC_URL, CHECK_CERTIFICATE, HEADERS
|
||||||
|
|
||||||
|
|
||||||
|
# absences
|
||||||
|
def test_absences():
|
||||||
|
r = requests.get(
|
||||||
|
SCODOC_URL + "/ScoDoc/api/absences/etudid/<int:etudid>",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
|
)
|
||||||
|
assert r.status_code == 200
|
||||||
|
|
||||||
|
r = requests.get(
|
||||||
|
SCODOC_URL + "/ScoDoc/api/absences/nip/<int:nip>",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
|
)
|
||||||
|
assert r.status_code == 200
|
||||||
|
|
||||||
|
r = requests.get(
|
||||||
|
SCODOC_URL + "/ScoDoc/api/absences/ine/<int:ine>",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
|
)
|
||||||
|
assert r.status_code == 200
|
||||||
|
|
||||||
|
|
||||||
|
# absences_justify
|
||||||
|
def test_absences_justify():
|
||||||
|
r = requests.get(
|
||||||
|
SCODOC_URL + "/ScoDoc/api/absences/etudid/1/just",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
|
)
|
||||||
|
assert r.status_code == 200
|
||||||
|
|
||||||
|
r = requests.get(
|
||||||
|
SCODOC_URL + "/ScoDoc/api/absences/nip/1/just",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
|
)
|
||||||
|
assert r.status_code == 200
|
||||||
|
|
||||||
|
r = requests.get(
|
||||||
|
SCODOC_URL + "/ScoDoc/api/absences/ine/1/just",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
|
)
|
||||||
|
assert r.status_code == 200
|
||||||
|
|
||||||
|
|
||||||
|
# abs_groupe_etat
|
||||||
|
def test_abs_groupe_etat():
|
||||||
|
r = requests.get(
|
||||||
|
SCODOC_URL
|
||||||
|
+ "/ScoDoc/api/absences/abs_group_etat/?group_id=<int:group_id>&date_debut=date_debut&date_fin=date_fin",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
|
)
|
||||||
|
assert r.status_code == 200
|
165
tests/api/test_api_departements.py
Normal file
165
tests/api/test_api_departements.py
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
"""Test Logos
|
||||||
|
|
||||||
|
Utilisation :
|
||||||
|
créer les variables d'environnement: (indiquer les valeurs
|
||||||
|
pour le serveur ScoDoc que vous voulez interroger)
|
||||||
|
|
||||||
|
export SCODOC_URL="https://scodoc.xxx.net/"
|
||||||
|
export SCODOC_USER="xxx"
|
||||||
|
export SCODOC_PASSWD="xxx"
|
||||||
|
export CHECK_CERTIFICATE=0 # ou 1 si serveur de production avec certif SSL valide
|
||||||
|
|
||||||
|
(on peut aussi placer ces valeurs dans un fichier .env du répertoire tests/api).
|
||||||
|
|
||||||
|
Lancer :
|
||||||
|
pytest tests/api/test_api_departements.py
|
||||||
|
"""
|
||||||
|
|
||||||
|
import requests
|
||||||
|
|
||||||
|
from tests.api.setup_test_api import SCODOC_URL, CHECK_CERTIFICATE, HEADERS
|
||||||
|
|
||||||
|
|
||||||
|
# departements
|
||||||
|
def test_departements(): #XXX TODO pour Seb
|
||||||
|
r = requests.get(
|
||||||
|
SCODOC_URL + "/ScoDoc/api/departements",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
|
)
|
||||||
|
assert r.status_code == 200
|
||||||
|
assert len(r.json()) == 1
|
||||||
|
|
||||||
|
|
||||||
|
# liste_etudiants
|
||||||
|
def test_liste_etudiants(): #XXX TODO pour Seb
|
||||||
|
r = requests.get(
|
||||||
|
SCODOC_URL + "/ScoDoc/api/departements/TAPI/etudiants/liste",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
|
)
|
||||||
|
assert r.status_code == 200
|
||||||
|
assert len(r.json()) == 16
|
||||||
|
|
||||||
|
r = requests.get(
|
||||||
|
SCODOC_URL + "/ScoDoc/api/departements/TAPI/etudiants/liste/1",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
|
)
|
||||||
|
assert r.status_code == 200
|
||||||
|
assert len(r.json()) == 16
|
||||||
|
|
||||||
|
|
||||||
|
# liste_semestres_courant
|
||||||
|
def test_semestres_courant(): #XXX TODO pour Seb
|
||||||
|
r = requests.get(
|
||||||
|
SCODOC_URL + "/ScoDoc/api/departements/TAPI/semestres_courants",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
|
)
|
||||||
|
assert r.status_code == 200
|
||||||
|
assert len(r.json()) == 1
|
||||||
|
|
||||||
|
|
||||||
|
# referenciel_competences
|
||||||
|
def test_referenciel_competences():
|
||||||
|
r = requests.get(
|
||||||
|
SCODOC_URL
|
||||||
|
+ "/ScoDoc/api/departements/TAPI/formations/1/referentiel_competences",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
|
)
|
||||||
|
assert r.status_code == 200 or 204
|
||||||
|
|
||||||
|
|
||||||
|
# semestre_index
|
||||||
|
def test_semestre_index(): #XXX TODO pour Seb
|
||||||
|
|
||||||
|
ue_fields = [
|
||||||
|
"semestre_idx",
|
||||||
|
"type",
|
||||||
|
"formation_id",
|
||||||
|
"ue_code",
|
||||||
|
"id",
|
||||||
|
"ects",
|
||||||
|
"acronyme",
|
||||||
|
"is_external",
|
||||||
|
"numero",
|
||||||
|
"code_apogee",
|
||||||
|
"titre",
|
||||||
|
"coefficient",
|
||||||
|
"color",
|
||||||
|
"ue_id",
|
||||||
|
]
|
||||||
|
|
||||||
|
ressource_fields = [
|
||||||
|
"heures_tp",
|
||||||
|
"code_apogee",
|
||||||
|
"titre",
|
||||||
|
"coefficient",
|
||||||
|
"module_type",
|
||||||
|
"id",
|
||||||
|
"ects",
|
||||||
|
"abbrev",
|
||||||
|
"ue_id",
|
||||||
|
"code",
|
||||||
|
"formation_id",
|
||||||
|
"heures_cours",
|
||||||
|
"matiere_id",
|
||||||
|
"heures_td",
|
||||||
|
"semestre_id",
|
||||||
|
"numero",
|
||||||
|
"module_id",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
sae_fields = [
|
||||||
|
"heures_tp",
|
||||||
|
"code_apogee",
|
||||||
|
"titre",
|
||||||
|
"coefficient",
|
||||||
|
"module_type",
|
||||||
|
"id",
|
||||||
|
"ects",
|
||||||
|
"abbrev",
|
||||||
|
"ue_id",
|
||||||
|
"code",
|
||||||
|
"formation_id",
|
||||||
|
"heures_cours",
|
||||||
|
"matiere_id",
|
||||||
|
"heures_td",
|
||||||
|
"semestre_id",
|
||||||
|
"numero",
|
||||||
|
"module_id",
|
||||||
|
]
|
||||||
|
|
||||||
|
r = requests.get(
|
||||||
|
SCODOC_URL + "/ScoDoc/api/departements/TAPI/formsemestre/1/programme",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
|
)
|
||||||
|
assert r.status_code == 200
|
||||||
|
assert len(r.json()) == 3
|
||||||
|
|
||||||
|
ue = r.json()["ues"][0]
|
||||||
|
ressource = r.json()["ressources"][0]
|
||||||
|
sae = r.json()["saes"][0]
|
||||||
|
|
||||||
|
fields_OK = True
|
||||||
|
|
||||||
|
# Vérifie si tous les champs sont bien présents
|
||||||
|
for field in ue:
|
||||||
|
if field not in ue_fields:
|
||||||
|
fields_OK = False
|
||||||
|
|
||||||
|
for field in ressource:
|
||||||
|
if field not in ressource_fields:
|
||||||
|
fields_OK = False
|
||||||
|
|
||||||
|
for field in sae:
|
||||||
|
if field not in sae_fields:
|
||||||
|
fields_OK = False
|
||||||
|
|
||||||
|
assert fields_OK is True
|
478
tests/api/test_api_etudiants.py
Normal file
478
tests/api/test_api_etudiants.py
Normal file
@ -0,0 +1,478 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
"""Test Logos
|
||||||
|
|
||||||
|
Utilisation :
|
||||||
|
créer les variables d'environnement: (indiquer les valeurs
|
||||||
|
pour le serveur ScoDoc que vous voulez interroger)
|
||||||
|
|
||||||
|
export SCODOC_URL="https://scodoc.xxx.net/"
|
||||||
|
export SCODOC_USER="xxx"
|
||||||
|
export SCODOC_PASSWD="xxx"
|
||||||
|
export CHECK_CERTIFICATE=0 # ou 1 si serveur de production avec certif SSL valide
|
||||||
|
|
||||||
|
(on peut aussi placer ces valeurs dans un fichier .env du répertoire tests/api).
|
||||||
|
|
||||||
|
Lancer :
|
||||||
|
pytest tests/api/test_api_etudiants.py
|
||||||
|
"""
|
||||||
|
from random import randint
|
||||||
|
|
||||||
|
import requests
|
||||||
|
|
||||||
|
from tests.api.setup_test_api import SCODOC_URL, CHECK_CERTIFICATE, HEADERS
|
||||||
|
|
||||||
|
|
||||||
|
# # etudiants
|
||||||
|
# def test_etudiants():
|
||||||
|
#
|
||||||
|
# fields = [
|
||||||
|
# "civilite",
|
||||||
|
# "code_ine",
|
||||||
|
# "code_nip",
|
||||||
|
# "date_naissance",
|
||||||
|
# "email",
|
||||||
|
# "emailperso",
|
||||||
|
# "etudid",
|
||||||
|
# "nom",
|
||||||
|
# "prenom",
|
||||||
|
# "nomprenom",
|
||||||
|
# "lieu_naissance",
|
||||||
|
# "dept_naissance",
|
||||||
|
# "nationalite",
|
||||||
|
# "boursier",
|
||||||
|
# "id",
|
||||||
|
# "domicile",
|
||||||
|
# "villedomicile",
|
||||||
|
# "telephone",
|
||||||
|
# "fax",
|
||||||
|
# "description",
|
||||||
|
# "codepostaldomicile",
|
||||||
|
# "paysdomicile",
|
||||||
|
# "telephonemobile",
|
||||||
|
# "typeadresse",
|
||||||
|
# ]
|
||||||
|
#
|
||||||
|
# r = requests.get(
|
||||||
|
# SCODOC_URL + "/ScoDoc/api/etudiants",
|
||||||
|
# headers=HEADERS,
|
||||||
|
# verify=CHECK_CERTIFICATE,
|
||||||
|
# )
|
||||||
|
# assert r.status_code == 200
|
||||||
|
# assert len(r.json()) == 16
|
||||||
|
#
|
||||||
|
# # Choisis aléatoirement un étudiant dans la liste des étudiants
|
||||||
|
# etu = r.json()[randint(0, len(r.json())) - 1]
|
||||||
|
#
|
||||||
|
# fields_OK = True
|
||||||
|
#
|
||||||
|
# # Vérifie si tous les champs sont bien présents
|
||||||
|
# for field in etu:
|
||||||
|
# if field not in fields:
|
||||||
|
# fields_OK = False
|
||||||
|
#
|
||||||
|
# assert fields_OK is True
|
||||||
|
|
||||||
|
|
||||||
|
# etudiants_courant
|
||||||
|
def test_etudiants_courant(): # XXX TODO pour Seb
|
||||||
|
|
||||||
|
fields = [
|
||||||
|
"civilite",
|
||||||
|
"code_ine",
|
||||||
|
"code_nip",
|
||||||
|
"date_naissance",
|
||||||
|
"email",
|
||||||
|
"emailperso",
|
||||||
|
"etudid",
|
||||||
|
"nom",
|
||||||
|
"prenom",
|
||||||
|
"nomprenom",
|
||||||
|
"lieu_naissance",
|
||||||
|
"dept_naissance",
|
||||||
|
"nationalite",
|
||||||
|
"boursier",
|
||||||
|
"id",
|
||||||
|
"domicile",
|
||||||
|
"villedomicile",
|
||||||
|
"telephone",
|
||||||
|
"fax",
|
||||||
|
"description",
|
||||||
|
"codepostaldomicile",
|
||||||
|
"paysdomicile",
|
||||||
|
"telephonemobile",
|
||||||
|
"typeadresse",
|
||||||
|
]
|
||||||
|
|
||||||
|
r = requests.get(
|
||||||
|
SCODOC_URL + "/ScoDoc/api/etudiants/courant",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
|
)
|
||||||
|
assert r.status_code == 200
|
||||||
|
assert len(r.json()) == 16
|
||||||
|
|
||||||
|
# Choisis aléatoirement un étudiant dans la liste des étudiants
|
||||||
|
etu = r.json()[randint(0, len(r.json())) - 1]
|
||||||
|
|
||||||
|
fields_OK = True
|
||||||
|
|
||||||
|
# Vérifie si tous les champs sont bien présents
|
||||||
|
for field in etu:
|
||||||
|
if field not in fields:
|
||||||
|
fields_OK = False
|
||||||
|
|
||||||
|
assert fields_OK is True
|
||||||
|
|
||||||
|
|
||||||
|
# etudiant
|
||||||
|
def test_etudiant(): # XXX TODO pour Seb
|
||||||
|
|
||||||
|
fields = [
|
||||||
|
"civilite",
|
||||||
|
"code_ine",
|
||||||
|
"code_nip",
|
||||||
|
"date_naissance",
|
||||||
|
"email",
|
||||||
|
"emailperso",
|
||||||
|
"etudid",
|
||||||
|
"nom",
|
||||||
|
"prenom",
|
||||||
|
"nomprenom",
|
||||||
|
"lieu_naissance",
|
||||||
|
"dept_naissance",
|
||||||
|
"nationalite",
|
||||||
|
"boursier",
|
||||||
|
"id",
|
||||||
|
"domicile",
|
||||||
|
"villedomicile",
|
||||||
|
"telephone",
|
||||||
|
"fax",
|
||||||
|
"description",
|
||||||
|
"codepostaldomicile",
|
||||||
|
"paysdomicile",
|
||||||
|
"telephonemobile",
|
||||||
|
"typeadresse",
|
||||||
|
]
|
||||||
|
|
||||||
|
######### Test etudid #########
|
||||||
|
|
||||||
|
r = requests.get(
|
||||||
|
SCODOC_URL + "/ScoDoc/api/etudiant/etudid/1",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
|
)
|
||||||
|
assert r.status_code == 200
|
||||||
|
assert len(r.json()) == 24
|
||||||
|
|
||||||
|
etu = r.json()
|
||||||
|
|
||||||
|
fields_OK = True
|
||||||
|
|
||||||
|
# Vérifie si tous les champs sont bien présents
|
||||||
|
for field in etu:
|
||||||
|
if field not in fields:
|
||||||
|
fields_OK = False
|
||||||
|
|
||||||
|
assert fields_OK is True
|
||||||
|
|
||||||
|
######### Test code nip #########
|
||||||
|
|
||||||
|
r = requests.get(
|
||||||
|
SCODOC_URL + "/ScoDoc/api/etudiant/nip/1",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
|
)
|
||||||
|
assert r.status_code == 200
|
||||||
|
assert len(r.json()) == 24
|
||||||
|
|
||||||
|
etu = r.json()
|
||||||
|
|
||||||
|
fields_OK = True
|
||||||
|
|
||||||
|
# Vérifie si tous les champs sont bien présents
|
||||||
|
for field in etu:
|
||||||
|
if field not in fields:
|
||||||
|
fields_OK = False
|
||||||
|
|
||||||
|
assert fields_OK is True
|
||||||
|
|
||||||
|
######### Test code ine #########
|
||||||
|
|
||||||
|
r = requests.get(
|
||||||
|
SCODOC_URL + "/ScoDoc/api/etudiant/ine/1",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
|
)
|
||||||
|
assert r.status_code == 200
|
||||||
|
assert len(r.json()) == 24
|
||||||
|
|
||||||
|
etu = r.json()
|
||||||
|
|
||||||
|
fields_OK = True
|
||||||
|
|
||||||
|
# Vérifie si tous les champs sont bien présents
|
||||||
|
for field in etu:
|
||||||
|
if field not in fields:
|
||||||
|
fields_OK = False
|
||||||
|
|
||||||
|
assert fields_OK is True
|
||||||
|
|
||||||
|
|
||||||
|
# etudiant_formsemestres
|
||||||
|
def test_etudiant_formsemestres(): # XXX TODO pour Seb
|
||||||
|
|
||||||
|
fields = [
|
||||||
|
"date_fin",
|
||||||
|
"resp_can_edit",
|
||||||
|
"dept_id",
|
||||||
|
"etat",
|
||||||
|
"resp_can_change_ens",
|
||||||
|
"id",
|
||||||
|
"modalite",
|
||||||
|
"ens_can_edit_eval",
|
||||||
|
"formation_id",
|
||||||
|
"gestion_compensation",
|
||||||
|
"elt_sem_apo",
|
||||||
|
"semestre_id",
|
||||||
|
"bul_hide_xml",
|
||||||
|
"elt_annee_apo",
|
||||||
|
"titre",
|
||||||
|
"block_moyennes",
|
||||||
|
"scodoc7_id",
|
||||||
|
"date_debut",
|
||||||
|
"gestion_semestrielle",
|
||||||
|
"bul_bgcolor",
|
||||||
|
"formsemestre_id",
|
||||||
|
"titre_num",
|
||||||
|
"date_debut_iso",
|
||||||
|
"date_fin_iso",
|
||||||
|
"responsables",
|
||||||
|
]
|
||||||
|
|
||||||
|
######### Test etudid #########
|
||||||
|
|
||||||
|
r = requests.get(
|
||||||
|
SCODOC_URL + "/ScoDoc/api/etudiant/etudid/1/formsemestres",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
|
)
|
||||||
|
assert r.status_code == 200
|
||||||
|
assert len(r.json()) == 1
|
||||||
|
|
||||||
|
formsemestre = r.json()[0]
|
||||||
|
|
||||||
|
fields_OK = True
|
||||||
|
|
||||||
|
# Vérifie si tous les champs sont bien présents
|
||||||
|
for field in formsemestre:
|
||||||
|
if field not in fields:
|
||||||
|
fields_OK = False
|
||||||
|
|
||||||
|
assert fields_OK is True
|
||||||
|
|
||||||
|
######### Test code nip #########
|
||||||
|
|
||||||
|
r = requests.get(
|
||||||
|
SCODOC_URL + "/ScoDoc/api/etudiant/nip/1/formsemestres",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
|
)
|
||||||
|
assert r.status_code == 200
|
||||||
|
assert len(r.json()) == 1
|
||||||
|
|
||||||
|
formsemestre = r.json()[0]
|
||||||
|
|
||||||
|
fields_OK = True
|
||||||
|
|
||||||
|
# Vérifie si tous les champs sont bien présents
|
||||||
|
for field in formsemestre:
|
||||||
|
if field not in fields:
|
||||||
|
fields_OK = False
|
||||||
|
|
||||||
|
assert fields_OK is True
|
||||||
|
|
||||||
|
######### Test code ine #########
|
||||||
|
|
||||||
|
r = requests.get(
|
||||||
|
SCODOC_URL + "/ScoDoc/api/etudiant/ine/1/formsemestres",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
|
)
|
||||||
|
assert r.status_code == 200
|
||||||
|
assert len(r.json()) == 1
|
||||||
|
|
||||||
|
formsemestre = r.json()[0]
|
||||||
|
|
||||||
|
fields_OK = True
|
||||||
|
|
||||||
|
# Vérifie si tous les champs sont bien présents
|
||||||
|
for field in formsemestre:
|
||||||
|
if field not in fields:
|
||||||
|
fields_OK = False
|
||||||
|
|
||||||
|
assert fields_OK is True
|
||||||
|
|
||||||
|
|
||||||
|
# etudiant_bulletin_semestre
|
||||||
|
def test_etudiant_bulletin_semestre():
|
||||||
|
|
||||||
|
# fields = [
|
||||||
|
# "etudid",
|
||||||
|
# "formsemestre_id",
|
||||||
|
# "date",
|
||||||
|
# "publie",
|
||||||
|
# "etapes",
|
||||||
|
# "etudiant",
|
||||||
|
# "note",
|
||||||
|
# "rang",
|
||||||
|
# "rang_group",
|
||||||
|
# "note_max",
|
||||||
|
# "bonus_sport_culture",
|
||||||
|
# "ue",
|
||||||
|
# "ue_capitalisee",
|
||||||
|
# "absences",
|
||||||
|
# "appreciation",
|
||||||
|
# ]
|
||||||
|
|
||||||
|
######### Test etudid #########
|
||||||
|
|
||||||
|
r = requests.get(
|
||||||
|
SCODOC_URL + "/ScoDoc/api/etudiant/etudid/1/formsemestre/1/bulletin",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
|
)
|
||||||
|
assert r.status_code == 200
|
||||||
|
assert len(r.json()) == 13
|
||||||
|
|
||||||
|
# bulletin = r.json()
|
||||||
|
#
|
||||||
|
# fields_OK = True
|
||||||
|
#
|
||||||
|
# # Vérifie si tous les champs sont bien présents
|
||||||
|
# for field in bulletin:
|
||||||
|
# if field not in fields:
|
||||||
|
# fields_OK = False
|
||||||
|
#
|
||||||
|
# assert fields_OK is True
|
||||||
|
|
||||||
|
######### Test code nip #########
|
||||||
|
|
||||||
|
r = requests.get(
|
||||||
|
SCODOC_URL + "/ScoDoc/api/etudiant/nip/1/formsemestre/1/bulletin",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
|
)
|
||||||
|
assert r.status_code == 200
|
||||||
|
assert len(r.json()) == 13
|
||||||
|
|
||||||
|
# bulletin = r.json()
|
||||||
|
#
|
||||||
|
# fields_OK = True
|
||||||
|
#
|
||||||
|
# # Vérifie si tous les champs sont bien présents
|
||||||
|
# for field in bulletin:
|
||||||
|
# if field not in fields:
|
||||||
|
# fields_OK = False
|
||||||
|
#
|
||||||
|
# assert fields_OK is True
|
||||||
|
|
||||||
|
######### Test code ine #########
|
||||||
|
|
||||||
|
r = requests.get(
|
||||||
|
SCODOC_URL + "/ScoDoc/api/etudiant/ine/1/formsemestre/1/bulletin",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
|
)
|
||||||
|
assert r.status_code == 200
|
||||||
|
assert len(r.json()) == 13
|
||||||
|
|
||||||
|
# bulletin = r.json()
|
||||||
|
#
|
||||||
|
# fields_OK = True
|
||||||
|
#
|
||||||
|
# # Vérifie si tous les champs sont bien présents
|
||||||
|
# for field in bulletin:
|
||||||
|
# if field not in fields:
|
||||||
|
# fields_OK = False
|
||||||
|
#
|
||||||
|
# assert fields_OK is True
|
||||||
|
|
||||||
|
|
||||||
|
# etudiant_groups
|
||||||
|
def test_etudiant_groups():
|
||||||
|
|
||||||
|
fields = [
|
||||||
|
"partition_id",
|
||||||
|
"id",
|
||||||
|
"formsemestre_id",
|
||||||
|
"partition_name",
|
||||||
|
"numero",
|
||||||
|
"bul_show_rank",
|
||||||
|
"show_in_lists",
|
||||||
|
"group_id",
|
||||||
|
"group_name",
|
||||||
|
]
|
||||||
|
|
||||||
|
######### Test etudid #########
|
||||||
|
|
||||||
|
r = requests.get(
|
||||||
|
SCODOC_URL + "/ScoDoc/api/etudiant/etudid/1/semestre/1/groups",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
|
)
|
||||||
|
assert r.status_code == 200
|
||||||
|
assert len(r.json()) == 1
|
||||||
|
|
||||||
|
groups = r.json()[0]
|
||||||
|
|
||||||
|
fields_OK = True
|
||||||
|
|
||||||
|
# Vérifie si tous les champs sont bien présents
|
||||||
|
for field in groups:
|
||||||
|
if field not in fields:
|
||||||
|
fields_OK = False
|
||||||
|
|
||||||
|
assert fields_OK is True
|
||||||
|
|
||||||
|
######### Test code nip #########
|
||||||
|
|
||||||
|
r = requests.get(
|
||||||
|
SCODOC_URL + "/ScoDoc/api/etudiant/nip/1/semestre/1/groups",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
|
)
|
||||||
|
assert r.status_code == 200
|
||||||
|
assert len(r.json()) == 1
|
||||||
|
|
||||||
|
groups = r.json()[0]
|
||||||
|
|
||||||
|
fields_OK = True
|
||||||
|
|
||||||
|
# Vérifie si tous les champs sont bien présents
|
||||||
|
for field in groups:
|
||||||
|
if field not in fields:
|
||||||
|
fields_OK = False
|
||||||
|
|
||||||
|
assert fields_OK is True
|
||||||
|
|
||||||
|
######### Test code ine #########
|
||||||
|
|
||||||
|
r = requests.get(
|
||||||
|
SCODOC_URL + "/ScoDoc/api/etudiant/ine/1/semestre/1/groups",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
|
)
|
||||||
|
assert r.status_code == 200
|
||||||
|
assert len(r.json()) == 1
|
||||||
|
|
||||||
|
groups = r.json()[0]
|
||||||
|
|
||||||
|
fields_OK = True
|
||||||
|
|
||||||
|
# Vérifie si tous les champs sont bien présents
|
||||||
|
for field in groups:
|
||||||
|
if field not in fields:
|
||||||
|
fields_OK = False
|
||||||
|
|
||||||
|
assert fields_OK is True
|
41
tests/api/test_api_evaluations.py
Normal file
41
tests/api/test_api_evaluations.py
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
"""Test Logos
|
||||||
|
|
||||||
|
Utilisation :
|
||||||
|
créer les variables d'environnement: (indiquer les valeurs
|
||||||
|
pour le serveur ScoDoc que vous voulez interroger)
|
||||||
|
|
||||||
|
export SCODOC_URL="https://scodoc.xxx.net/"
|
||||||
|
export SCODOC_USER="xxx"
|
||||||
|
export SCODOC_PASSWD="xxx"
|
||||||
|
export CHECK_CERTIFICATE=0 # ou 1 si serveur de production avec certif SSL valide
|
||||||
|
|
||||||
|
(on peut aussi placer ces valeurs dans un fichier .env du répertoire tests/api).
|
||||||
|
|
||||||
|
Lancer :
|
||||||
|
pytest tests/api/test_api_evaluations.py
|
||||||
|
"""
|
||||||
|
|
||||||
|
import requests
|
||||||
|
|
||||||
|
from tests.api.setup_test_api import SCODOC_URL, CHECK_CERTIFICATE, HEADERS
|
||||||
|
|
||||||
|
# evaluations
|
||||||
|
def test_evaluations():
|
||||||
|
r = requests.get(
|
||||||
|
SCODOC_URL + "/ScoDoc/api/evaluations/1",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
|
)
|
||||||
|
assert r.status_code == 200
|
||||||
|
|
||||||
|
|
||||||
|
# evaluation_notes
|
||||||
|
def test_evaluation_notes():
|
||||||
|
r = requests.get(
|
||||||
|
SCODOC_URL + "/ScoDoc/api/evaluations/eval_notes/1",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
|
)
|
||||||
|
assert r.status_code == 200
|
82
tests/api/test_api_formations.py
Normal file
82
tests/api/test_api_formations.py
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
"""Test Logos
|
||||||
|
|
||||||
|
Utilisation :
|
||||||
|
créer les variables d'environnement: (indiquer les valeurs
|
||||||
|
pour le serveur ScoDoc que vous voulez interroger)
|
||||||
|
|
||||||
|
export SCODOC_URL="https://scodoc.xxx.net/"
|
||||||
|
export SCODOC_USER="xxx"
|
||||||
|
export SCODOC_PASSWD="xxx"
|
||||||
|
export CHECK_CERTIFICATE=0 # ou 1 si serveur de production avec certif SSL valide
|
||||||
|
|
||||||
|
(on peut aussi placer ces valeurs dans un fichier .env du répertoire tests/api).
|
||||||
|
|
||||||
|
Lancer :
|
||||||
|
pytest tests/api/test_api_formations.py
|
||||||
|
"""
|
||||||
|
|
||||||
|
import requests
|
||||||
|
|
||||||
|
from tests.api.setup_test_api import SCODOC_URL, CHECK_CERTIFICATE, HEADERS
|
||||||
|
|
||||||
|
# formations
|
||||||
|
def test_formations():
|
||||||
|
r = requests.get(
|
||||||
|
SCODOC_URL + "/ScoDoc/api/formations",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
|
)
|
||||||
|
assert r.status_code == 200
|
||||||
|
|
||||||
|
|
||||||
|
# formations_by_id
|
||||||
|
def test_formations_by_id():
|
||||||
|
r = requests.get(
|
||||||
|
SCODOC_URL + "/ScoDoc/api/formations/1",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
|
)
|
||||||
|
assert r.status_code == 200
|
||||||
|
|
||||||
|
|
||||||
|
# formation_export_by_formation_id
|
||||||
|
def test_formation_export_by_formation_id():
|
||||||
|
r = requests.get(
|
||||||
|
SCODOC_URL + "/ScoDoc/api/formations/formation_export/1",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
|
)
|
||||||
|
assert r.status_code == 200
|
||||||
|
|
||||||
|
|
||||||
|
# formsemestre_apo
|
||||||
|
def test_formsemestre_apo():
|
||||||
|
r = requests.get(
|
||||||
|
SCODOC_URL + "/ScoDoc/api/formations/apo/<string:etape_apo>",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
|
)
|
||||||
|
assert r.status_code == 200
|
||||||
|
|
||||||
|
|
||||||
|
# moduleimpls
|
||||||
|
def test_moduleimpls():
|
||||||
|
r = requests.get(
|
||||||
|
SCODOC_URL + "/ScoDoc/api/formations/moduleimpl/<int:moduleimpl_id>",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
|
)
|
||||||
|
assert r.status_code == 200
|
||||||
|
|
||||||
|
|
||||||
|
# moduleimpls_sem
|
||||||
|
def test_moduleimpls_sem():
|
||||||
|
r = requests.get(
|
||||||
|
SCODOC_URL
|
||||||
|
+ "/ScoDoc/api/formations/moduleimpl/formsemestre/1/liste",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
|
)
|
||||||
|
assert r.status_code == 200
|
117
tests/api/test_api_formsemestre.py
Normal file
117
tests/api/test_api_formsemestre.py
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
"""Test Logos
|
||||||
|
|
||||||
|
Utilisation :
|
||||||
|
créer les variables d'environnement: (indiquer les valeurs
|
||||||
|
pour le serveur ScoDoc que vous voulez interroger)
|
||||||
|
|
||||||
|
export SCODOC_URL="https://scodoc.xxx.net/"
|
||||||
|
export SCODOC_USER="xxx"
|
||||||
|
export SCODOC_PASSWD="xxx"
|
||||||
|
export CHECK_CERTIFICATE=0 # ou 1 si serveur de production avec certif SSL valide
|
||||||
|
|
||||||
|
(on peut aussi placer ces valeurs dans un fichier .env du répertoire tests/api).
|
||||||
|
|
||||||
|
Lancer :
|
||||||
|
pytest tests/api/test_api_formsemestre.py
|
||||||
|
"""
|
||||||
|
|
||||||
|
import requests
|
||||||
|
|
||||||
|
from tests.api.setup_test_api import SCODOC_URL, CHECK_CERTIFICATE, HEADERS
|
||||||
|
|
||||||
|
# formsemestre
|
||||||
|
def test_formsemestre():
|
||||||
|
r = requests.get(
|
||||||
|
SCODOC_URL + "/ScoDoc/api/formsemestre/1",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
|
)
|
||||||
|
assert r.status_code == 200
|
||||||
|
|
||||||
|
formsemestre = r.json()
|
||||||
|
|
||||||
|
fields = [
|
||||||
|
"date_fin",
|
||||||
|
"resp_can_edit",
|
||||||
|
"dept_id",
|
||||||
|
"etat",
|
||||||
|
"resp_can_change_ens",
|
||||||
|
"id",
|
||||||
|
"modalite",
|
||||||
|
"ens_can_edit_eval",
|
||||||
|
"formation_id",
|
||||||
|
"gestion_compensation",
|
||||||
|
"elt_sem_apo",
|
||||||
|
"semestre_id",
|
||||||
|
"bul_hide_xml",
|
||||||
|
"elt_annee_apo",
|
||||||
|
"titre",
|
||||||
|
"block_moyennes",
|
||||||
|
"scodoc7_id",
|
||||||
|
"date_debut",
|
||||||
|
"gestion_semestrielle",
|
||||||
|
"bul_bgcolor",
|
||||||
|
"formsemestre_id",
|
||||||
|
"titre_num",
|
||||||
|
"date_debut_iso",
|
||||||
|
"date_fin_iso",
|
||||||
|
"responsables",
|
||||||
|
]
|
||||||
|
|
||||||
|
fields_OK = True
|
||||||
|
|
||||||
|
# Vérifie si tous les champs sont bien présents
|
||||||
|
for field in formsemestre:
|
||||||
|
if field not in fields:
|
||||||
|
fields_OK = False
|
||||||
|
|
||||||
|
assert fields_OK is True
|
||||||
|
|
||||||
|
|
||||||
|
# etudiant_bulletin
|
||||||
|
def test_etudiant_bulletin(): #XXX TODO pour Seb
|
||||||
|
r = requests.get(
|
||||||
|
SCODOC_URL
|
||||||
|
+ "/ScoDoc/api/formsemestre/1/departements/TAPI/etudiant/etudid/1/bulletin",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
|
)
|
||||||
|
assert r.status_code == 200
|
||||||
|
|
||||||
|
r = requests.get(
|
||||||
|
SCODOC_URL
|
||||||
|
+ "/ScoDoc/api/formsemestre/1/departements/TAPI/etudiant/nip/1/bulletin",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
|
)
|
||||||
|
assert r.status_code == 200
|
||||||
|
|
||||||
|
r = requests.get(
|
||||||
|
SCODOC_URL
|
||||||
|
+ "/ScoDoc/api/formsemestre/1/departements/TAPI/etudiant/ine/1/bulletin",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
|
)
|
||||||
|
assert r.status_code == 200
|
||||||
|
|
||||||
|
|
||||||
|
# bulletins
|
||||||
|
def test_bulletins():
|
||||||
|
r = requests.get(
|
||||||
|
SCODOC_URL + "/ScoDoc/api/formsemestre/1/bulletins",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
|
)
|
||||||
|
assert r.status_code == 200
|
||||||
|
|
||||||
|
|
||||||
|
# # jury
|
||||||
|
# def test_jury():
|
||||||
|
# r = requests.get(
|
||||||
|
# SCODOC_URL + "/ScoDoc/api/formsemestre/1/jury",
|
||||||
|
# headers=HEADERS,
|
||||||
|
# verify=CHECK_CERTIFICATE,
|
||||||
|
# )
|
||||||
|
# assert r.status_code == 200
|
100
tests/api/test_api_jury.py
Normal file
100
tests/api/test_api_jury.py
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
"""Test Logos
|
||||||
|
|
||||||
|
Utilisation :
|
||||||
|
créer les variables d'environnement: (indiquer les valeurs
|
||||||
|
pour le serveur ScoDoc que vous voulez interroger)
|
||||||
|
|
||||||
|
export SCODOC_URL="https://scodoc.xxx.net/"
|
||||||
|
export SCODOC_USER="xxx"
|
||||||
|
export SCODOC_PASSWD="xxx"
|
||||||
|
export CHECK_CERTIFICATE=0 # ou 1 si serveur de production avec certif SSL valide
|
||||||
|
|
||||||
|
(on peut aussi placer ces valeurs dans un fichier .env du répertoire tests/api).
|
||||||
|
|
||||||
|
Lancer :
|
||||||
|
pytest tests/api/test_api_jury.py
|
||||||
|
"""
|
||||||
|
|
||||||
|
import requests
|
||||||
|
|
||||||
|
from tests.api.setup_test_api import SCODOC_URL, CHECK_CERTIFICATE, HEADERS
|
||||||
|
|
||||||
|
# jury_preparation
|
||||||
|
def test_jury_preparation():
|
||||||
|
r = requests.get(
|
||||||
|
SCODOC_URL
|
||||||
|
+ "/ScoDoc/api/jury/formsemestre/<int:formsemestre_id>/preparation_jury",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
|
)
|
||||||
|
assert r.status_code == 200
|
||||||
|
|
||||||
|
|
||||||
|
# jury_decisions
|
||||||
|
def test_jury_decisions():
|
||||||
|
r = requests.get(
|
||||||
|
SCODOC_URL
|
||||||
|
+ "/ScoDoc/api/jury/formsemestre/<int:formsemestre_id>/decisions_jury",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
|
)
|
||||||
|
assert r.status_code == 200
|
||||||
|
|
||||||
|
|
||||||
|
# set_decision_jury
|
||||||
|
def test_set_decision_jury():
|
||||||
|
r = requests.get(
|
||||||
|
SCODOC_URL
|
||||||
|
+ "/ScoDoc/api/jury/set_decision/etudid?etudid=<int:etudid>&formsemestre_id=<int:formesemestre_id>"
|
||||||
|
"&jury=<string:decision_jury>&devenir=<string:devenir_jury>&assiduite=<bool>",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
|
)
|
||||||
|
assert r.status_code == 200
|
||||||
|
|
||||||
|
r = requests.get(
|
||||||
|
SCODOC_URL
|
||||||
|
+ "/ScoDoc/api/jury/set_decision/nip?etudid=<int:etudid>&formsemestre_id=<int:formesemestre_id>"
|
||||||
|
"&jury=<string:decision_jury>&devenir=<string:devenir_jury>&assiduite=<bool>",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
|
)
|
||||||
|
assert r.status_code == 200
|
||||||
|
|
||||||
|
r = requests.get(
|
||||||
|
SCODOC_URL
|
||||||
|
+ "/ScoDoc/api/jury/set_decision/ine?etudid=<int:etudid>&formsemestre_id=<int:formesemestre_id>"
|
||||||
|
"&jury=<string:decision_jury>&devenir=<string:devenir_jury>&assiduite=<bool>",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
|
)
|
||||||
|
assert r.status_code == 200
|
||||||
|
|
||||||
|
|
||||||
|
# annule_decision_jury
|
||||||
|
def test_annule_decision_jury():
|
||||||
|
r = requests.get(
|
||||||
|
SCODOC_URL
|
||||||
|
+ "/ScoDoc/api/jury/etudid/<int:etudid>/formsemestre/<int:formsemestre_id>/annule_decision",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
|
)
|
||||||
|
assert r.status_code == 200
|
||||||
|
|
||||||
|
r = requests.get(
|
||||||
|
SCODOC_URL
|
||||||
|
+ "/ScoDoc/api/jury/nip/<int:nip>/formsemestre/<int:formsemestre_id>/annule_decision",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
|
)
|
||||||
|
assert r.status_code == 200
|
||||||
|
|
||||||
|
r = requests.get(
|
||||||
|
SCODOC_URL
|
||||||
|
+ "/ScoDoc/api/jury/ine/<int:ine>/formsemestre/<int:formsemestre_id>/annule_decision",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
|
)
|
||||||
|
assert r.status_code == 200
|
@ -9,7 +9,7 @@ utilisation:
|
|||||||
pytest tests/api/test_api_logos.py
|
pytest tests/api/test_api_logos.py
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import pytest
|
from tests.api.setup_test_api import SCODOC_URL, CHECK_CERTIFICATE, HEADERS
|
||||||
|
|
||||||
from scodoc import app
|
from scodoc import app
|
||||||
from tests.unit.config_test_logos import (
|
from tests.unit.config_test_logos import (
|
||||||
|
59
tests/api/test_api_partitions.py
Normal file
59
tests/api/test_api_partitions.py
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
"""Test Logos
|
||||||
|
|
||||||
|
Utilisation :
|
||||||
|
créer les variables d'environnement: (indiquer les valeurs
|
||||||
|
pour le serveur ScoDoc que vous voulez interroger)
|
||||||
|
|
||||||
|
export SCODOC_URL="https://scodoc.xxx.net/"
|
||||||
|
export SCODOC_USER="xxx"
|
||||||
|
export SCODOC_PASSWD="xxx"
|
||||||
|
export CHECK_CERTIFICATE=0 # ou 1 si serveur de production avec certif SSL valide
|
||||||
|
|
||||||
|
(on peut aussi placer ces valeurs dans un fichier .env du répertoire tests/api).
|
||||||
|
|
||||||
|
Lancer :
|
||||||
|
pytest tests/api/test_api_partitions.py
|
||||||
|
"""
|
||||||
|
|
||||||
|
import requests
|
||||||
|
|
||||||
|
from tests.api.setup_test_api import SCODOC_URL, CHECK_CERTIFICATE, HEADERS
|
||||||
|
|
||||||
|
# partition
|
||||||
|
def test_partition():
|
||||||
|
r = requests.get(
|
||||||
|
SCODOC_URL + "/ScoDoc/api/partitions/1",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
|
)
|
||||||
|
assert r.status_code == 200
|
||||||
|
|
||||||
|
|
||||||
|
# etud_in_group
|
||||||
|
def test_etud_in_group():
|
||||||
|
r = requests.get(
|
||||||
|
SCODOC_URL + "/ScoDoc/api/partitions/groups/1",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
|
)
|
||||||
|
assert r.status_code == 200
|
||||||
|
r = requests.get(
|
||||||
|
SCODOC_URL + "/ScoDoc/api/partitions/groups/<int:group_id>/etat/<string:etat>",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
|
)
|
||||||
|
assert r.status_code == 200
|
||||||
|
|
||||||
|
|
||||||
|
# set_groups
|
||||||
|
def test_set_groups():
|
||||||
|
r = requests.get(
|
||||||
|
SCODOC_URL
|
||||||
|
+ "/ScoDoc/api/partitions/set_groups?partition_id=<int:partition_id>&groups_lists=<int:groups_lists>&"
|
||||||
|
"groups_to_create=<int:groups_to_create>&groups_to_delete=<int:groups_to_delete>",
|
||||||
|
headers=HEADERS,
|
||||||
|
verify=CHECK_CERTIFICATE,
|
||||||
|
)
|
||||||
|
assert r.status_code == 200
|
@ -13,6 +13,11 @@
|
|||||||
flask db upgrade
|
flask db upgrade
|
||||||
flask sco-db-init --erase
|
flask sco-db-init --erase
|
||||||
flask init-test-database
|
flask init-test-database
|
||||||
|
flask user-role -a Admin -d TAPI test
|
||||||
|
flask user-password test
|
||||||
|
flask create-role APIUserViewer
|
||||||
|
flask edit-role APIUserViewer -a APIView
|
||||||
|
flask user-role test -a APIUserViewer
|
||||||
|
|
||||||
3) relancer ScoDoc:
|
3) relancer ScoDoc:
|
||||||
flask run --host 0.0.0.0
|
flask run --host 0.0.0.0
|
||||||
@ -81,6 +86,10 @@ def create_fake_etud(dept):
|
|||||||
etud = models.Identite(civilite=civilite, nom=nom, prenom=prenom, dept_id=dept.id)
|
etud = models.Identite(civilite=civilite, nom=nom, prenom=prenom, dept_id=dept.id)
|
||||||
db.session.add(etud)
|
db.session.add(etud)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
etud.code_nip = etud.id
|
||||||
|
etud.code_ine = etud.id
|
||||||
|
db.session.add(etud)
|
||||||
|
db.session.commit()
|
||||||
adresse = models.Adresse(
|
adresse = models.Adresse(
|
||||||
etudid=etud.id, email=f"{etud.prenom}.{etud.nom}@example.com"
|
etudid=etud.id, email=f"{etud.prenom}.{etud.nom}@example.com"
|
||||||
)
|
)
|
||||||
@ -103,7 +112,7 @@ def create_formsemestre(formation, user, semestre_idx=1):
|
|||||||
semestre_id=semestre_idx,
|
semestre_id=semestre_idx,
|
||||||
titre="Semestre test",
|
titre="Semestre test",
|
||||||
date_debut=datetime.datetime(2021, 9, 1),
|
date_debut=datetime.datetime(2021, 9, 1),
|
||||||
date_fin=datetime.datetime(2022, 1, 31),
|
date_fin=datetime.datetime(2022, 8, 31),
|
||||||
modalite="FI",
|
modalite="FI",
|
||||||
formation=formation,
|
formation=formation,
|
||||||
)
|
)
|
||||||
@ -136,6 +145,7 @@ def inscrit_etudiants(etuds, formsemestre):
|
|||||||
|
|
||||||
|
|
||||||
def init_test_database():
|
def init_test_database():
|
||||||
|
|
||||||
dept = init_departement("TAPI")
|
dept = init_departement("TAPI")
|
||||||
user = create_user(dept)
|
user = create_user(dept)
|
||||||
etuds = create_etuds(dept)
|
etuds = create_etuds(dept)
|
||||||
|
Loading…
Reference in New Issue
Block a user