forked from ScoDoc/ScoDoc
Merge branch 'modif' of https://scodoc.org/git/iziram/ScoDoc into iziram-rev
This commit is contained in:
commit
43849007fb
@ -26,6 +26,7 @@ from flask_mail import Mail
|
||||
from flask_bootstrap import Bootstrap
|
||||
from flask_moment import Moment
|
||||
from flask_caching import Cache
|
||||
from jinja2 import select_autoescape
|
||||
import sqlalchemy
|
||||
|
||||
from app.scodoc.sco_exceptions import (
|
||||
@ -61,11 +62,11 @@ cache = Cache(
|
||||
|
||||
|
||||
def handle_sco_value_error(exc):
|
||||
return render_template("sco_value_error.html", exc=exc), 404
|
||||
return render_template("sco_value_error.j2", exc=exc), 404
|
||||
|
||||
|
||||
def handle_access_denied(exc):
|
||||
return render_template("error_access_denied.html", exc=exc), 403
|
||||
return render_template("error_access_denied.j2", exc=exc), 403
|
||||
|
||||
|
||||
def internal_server_error(exc):
|
||||
@ -75,7 +76,7 @@ def internal_server_error(exc):
|
||||
|
||||
return (
|
||||
render_template(
|
||||
"error_500.html",
|
||||
"error_500.j2",
|
||||
SCOVERSION=sco_version.SCOVERSION,
|
||||
date=datetime.datetime.now().isoformat(),
|
||||
exc=exc,
|
||||
@ -146,7 +147,7 @@ def render_raw_html(template_filename: str, **args) -> str:
|
||||
|
||||
def postgresql_server_error(e):
|
||||
"""Erreur de connection au serveur postgresql (voir notesdb.open_db_connection)"""
|
||||
return render_raw_html("error_503.html", SCOVERSION=sco_version.SCOVERSION), 503
|
||||
return render_raw_html("error_503.j2", SCOVERSION=sco_version.SCOVERSION), 503
|
||||
|
||||
|
||||
class LogRequestFormatter(logging.Formatter):
|
||||
@ -275,6 +276,9 @@ def create_app(config_class=DevConfig):
|
||||
from app.api import api_bp
|
||||
from app.api import api_web_bp
|
||||
|
||||
# Enable autoescaping of all templates, including .j2
|
||||
app.jinja_env.autoescape = select_autoescape(default_for_string=True, default=True)
|
||||
|
||||
# https://scodoc.fr/ScoDoc
|
||||
app.register_blueprint(scodoc_bp)
|
||||
# https://scodoc.fr/ScoDoc/RT/Scolarite/...
|
||||
|
@ -42,6 +42,7 @@ from app.api import (
|
||||
formations,
|
||||
formsemestres,
|
||||
jury,
|
||||
justificatif,
|
||||
logos,
|
||||
partitions,
|
||||
users,
|
||||
|
@ -6,23 +6,19 @@
|
||||
"""ScoDoc 9 API : Assiduités
|
||||
"""
|
||||
from datetime import datetime
|
||||
|
||||
from typing import List
|
||||
from flask import g, jsonify, request
|
||||
|
||||
from app import db
|
||||
|
||||
from app.api import api_bp as bp, api_web_bp
|
||||
from app.scodoc.sco_utils import json_error
|
||||
from app.decorators import scodoc, permission_required
|
||||
from app.scodoc.sco_permissions import Permission
|
||||
from flask_login import login_required
|
||||
|
||||
|
||||
from app.models import Identite, Assiduite, FormSemestre, ModuleImpl
|
||||
from app.scodoc.sco_exceptions import ScoValueError
|
||||
import app.scodoc.sco_utils as scu
|
||||
import app.scodoc.sco_assiduites as scass
|
||||
import app.scodoc.sco_utils as scu
|
||||
from app import db
|
||||
from app.api import api_bp as bp
|
||||
from app.api import api_web_bp
|
||||
from app.decorators import permission_required, scodoc
|
||||
from app.models import Assiduite, FormSemestre, Identite, ModuleImpl
|
||||
from app.scodoc.sco_exceptions import ScoValueError
|
||||
from app.scodoc.sco_permissions import Permission
|
||||
from app.scodoc.sco_utils import json_error
|
||||
|
||||
|
||||
@bp.route("/assiduite/<int:assiduite_id>")
|
||||
@ -47,12 +43,11 @@ def assiduite(assiduite_id: int = None):
|
||||
query = Assiduite.query.filter_by(id=assiduite_id)
|
||||
# if g.scodoc_dept:
|
||||
# query = query.join(Identite).filter_by(dept_id=g.scodoc_dept_id)
|
||||
assiduite_query = query.first_or_404()
|
||||
|
||||
assiduite = query.first_or_404()
|
||||
data = assiduite_query.to_dict()
|
||||
|
||||
data = assiduite.to_dict()
|
||||
|
||||
return jsonify(change_etat(data))
|
||||
return jsonify(_change_etat(data))
|
||||
|
||||
|
||||
@bp.route("/assiduites/<int:etudid>/count", defaults={"with_query": False})
|
||||
@ -104,15 +99,15 @@ def count_assiduites(etudid: int = None, with_query: bool = False):
|
||||
query = query.filter_by(dept_id=g.scodoc_dept_id)
|
||||
|
||||
etud: Identite = query.first_or_404(etudid)
|
||||
filter: dict[str, object] = {}
|
||||
filtered: dict[str, object] = {}
|
||||
metric: str = "all"
|
||||
|
||||
if with_query:
|
||||
metric, filter = count_manager(request)
|
||||
metric, filtered = _count_manager(request)
|
||||
|
||||
return jsonify(
|
||||
scass.get_assiduites_stats(
|
||||
assiduites=etud.assiduites, metric=metric, filter=filter
|
||||
assiduites=etud.assiduites, metric=metric, filtered=filtered
|
||||
)
|
||||
)
|
||||
|
||||
@ -162,15 +157,15 @@ def assiduites(etudid: int = None, with_query: bool = False):
|
||||
query = query.filter_by(dept_id=g.scodoc_dept_id)
|
||||
|
||||
etud: Identite = query.first_or_404(etudid)
|
||||
assiduites = etud.assiduites
|
||||
assiduites_query = etud.assiduites
|
||||
|
||||
if with_query:
|
||||
assiduites = filter_manager(request, assiduites)
|
||||
assiduites_query = _filter_manager(request, assiduites_query)
|
||||
|
||||
data_set: List[dict] = []
|
||||
for ass in assiduites.all():
|
||||
data_set: list[dict] = []
|
||||
for ass in assiduites_query.all():
|
||||
data = ass.to_dict()
|
||||
data_set.append(change_etat(data))
|
||||
data_set.append(_change_etat(data))
|
||||
|
||||
return jsonify(data_set)
|
||||
|
||||
@ -200,19 +195,15 @@ def assiduites_formsemestre(formsemestre_id: int, with_query: bool = False):
|
||||
if formsemestre is None:
|
||||
return json_error(404, "le paramètre 'formsemestre_id' n'existe pas")
|
||||
|
||||
etuds = formsemestre.etuds.all()
|
||||
etuds_id = [etud.id for etud in etuds]
|
||||
|
||||
assiduites = Assiduite.query.filter(Assiduite.etudid.in_(etuds_id))
|
||||
assiduites = scass.filter_by_formsemstre(assiduites, formsemestre)
|
||||
assiduites_query = scass.filter_by_formsemestre(Assiduite.query, formsemestre)
|
||||
|
||||
if with_query:
|
||||
assiduites = filter_manager(request, assiduites)
|
||||
assiduites_query = _filter_manager(request, assiduites_query)
|
||||
|
||||
data_set: List[dict] = []
|
||||
for ass in assiduites.all():
|
||||
data_set: list[dict] = []
|
||||
for ass in assiduites_query.all():
|
||||
data = ass.to_dict()
|
||||
data_set.append(change_etat(data))
|
||||
data_set.append(_change_etat(data))
|
||||
|
||||
return jsonify(data_set)
|
||||
|
||||
@ -249,14 +240,14 @@ def count_assiduites_formsemestre(
|
||||
etuds = formsemestre.etuds.all()
|
||||
etuds_id = [etud.id for etud in etuds]
|
||||
|
||||
assiduites = Assiduite.query.filter(Assiduite.etudid.in_(etuds_id))
|
||||
assiduites = scass.filter_by_formsemstre(assiduites, formsemestre)
|
||||
assiduites_query = Assiduite.query.filter(Assiduite.etudid.in_(etuds_id))
|
||||
assiduites_query = scass.filter_by_formsemestre(assiduites_query, formsemestre)
|
||||
metric: str = "all"
|
||||
filter: dict = {}
|
||||
filtered: dict = {}
|
||||
if with_query:
|
||||
metric, filter = count_manager(request)
|
||||
metric, filtered = _count_manager(request)
|
||||
|
||||
return jsonify(scass.get_assiduites_stats(assiduites, metric, filter))
|
||||
return jsonify(scass.get_assiduites_stats(assiduites_query, metric, filtered))
|
||||
|
||||
|
||||
@bp.route("/assiduite/<int:etudid>/create", methods=["POST"])
|
||||
@ -265,31 +256,38 @@ def count_assiduites_formsemestre(
|
||||
@login_required
|
||||
@permission_required(Permission.ScoView)
|
||||
# @permission_required(Permission.ScoAssiduiteChange)
|
||||
def create(etudid: int = None):
|
||||
def assiduite_create(etudid: int = None):
|
||||
"""
|
||||
Création d'une assiduité pour l'étudiant (etudid)
|
||||
La requête doit avoir un content type "application/json":
|
||||
{
|
||||
"date_debut": str,
|
||||
"date_fin": str,
|
||||
"etat": str,
|
||||
}
|
||||
ou
|
||||
{
|
||||
"date_debut": str,
|
||||
"date_fin": str,
|
||||
"etat": str,
|
||||
"moduleimpl_id": int,
|
||||
}
|
||||
|
||||
[
|
||||
{
|
||||
"date_debut": str,
|
||||
"date_fin": str,
|
||||
"etat": str,
|
||||
},
|
||||
{
|
||||
"date_debut": str,
|
||||
"date_fin": str,
|
||||
"etat": str,
|
||||
"moduleimpl_id": int,
|
||||
"desc":str,
|
||||
}
|
||||
...
|
||||
]
|
||||
|
||||
"""
|
||||
etud: Identite = Identite.query.filter_by(id=etudid).first_or_404()
|
||||
|
||||
create_list: list[object] = request.get_json(force=True)
|
||||
|
||||
if not isinstance(create_list, list):
|
||||
return json_error(404, "Le contenu envoyé n'est pas une liste")
|
||||
|
||||
errors: dict[int, str] = {}
|
||||
success: dict[int, object] = {}
|
||||
for i, data in enumerate(request.get_json(force=True)):
|
||||
code, obj = create_singular(data, etud)
|
||||
for i, data in enumerate(create_list):
|
||||
code, obj = _create_singular(data, etud)
|
||||
if code == 404:
|
||||
errors[i] = obj
|
||||
else:
|
||||
@ -298,21 +296,21 @@ def create(etudid: int = None):
|
||||
return jsonify({"errors": errors, "success": success})
|
||||
|
||||
|
||||
def create_singular(
|
||||
def _create_singular(
|
||||
data: dict,
|
||||
etud: Identite,
|
||||
) -> tuple[int, object]:
|
||||
errors: List[str] = []
|
||||
errors: list[str] = []
|
||||
|
||||
# -- vérifications de l'objet json --
|
||||
# cas 1 : ETAT
|
||||
etat = data.get("etat", None)
|
||||
if etat is None:
|
||||
errors.append("param 'etat': manquant")
|
||||
elif etat not in scu.ETATS_ASSIDUITE.keys():
|
||||
elif etat not in scu.ETATS_ASSIDUITE:
|
||||
errors.append("param 'etat': invalide")
|
||||
|
||||
data = change_etat(data, False)
|
||||
data = _change_etat(data, False)
|
||||
etat = data.get("etat", None)
|
||||
|
||||
# cas 2 : date_debut
|
||||
@ -329,7 +327,7 @@ def create_singular(
|
||||
errors.append("param 'date_fin': manquant")
|
||||
fin = scu.is_iso_formated(date_fin, convert=True)
|
||||
if fin is None:
|
||||
errors.append(f"param 'date_fin': format invalide")
|
||||
errors.append("param 'date_fin': format invalide")
|
||||
|
||||
# cas 4 : moduleimpl_id
|
||||
|
||||
@ -343,9 +341,9 @@ def create_singular(
|
||||
|
||||
# cas 5 : desc
|
||||
|
||||
desc:str = data.get("desc", None)
|
||||
desc: str = data.get("desc", None)
|
||||
|
||||
if errors != []:
|
||||
if errors:
|
||||
err: str = ", ".join(errors)
|
||||
return (404, err)
|
||||
|
||||
@ -358,6 +356,7 @@ def create_singular(
|
||||
etat=etat,
|
||||
etud=etud,
|
||||
moduleimpl=moduleimpl,
|
||||
description=desc,
|
||||
)
|
||||
|
||||
db.session.add(nouv_assiduite)
|
||||
@ -376,15 +375,27 @@ def create_singular(
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
# @permission_required(Permission.ScoAssiduiteChange)
|
||||
def delete():
|
||||
def assiduite_cdelete():
|
||||
"""
|
||||
Suppression d'une assiduité à partir de son id
|
||||
|
||||
Forme des données envoyées :
|
||||
|
||||
[
|
||||
<assiduite_id:int>,
|
||||
...
|
||||
]
|
||||
|
||||
|
||||
"""
|
||||
assiduites: list[int] = request.get_json(force=True)
|
||||
assiduites_list: list[int] = request.get_json(force=True)
|
||||
if not isinstance(assiduites_list, list):
|
||||
return json_error(404, "Le contenu envoyé n'est pas une liste")
|
||||
|
||||
output = {"errors": {}, "success": {}}
|
||||
|
||||
for i, ass in enumerate(assiduites):
|
||||
code, msg = delete_singular(ass, db)
|
||||
for i, ass in enumerate(assiduites_list):
|
||||
code, msg = _delete_singular(ass, db)
|
||||
if code == 404:
|
||||
output["errors"][f"{i}"] = msg
|
||||
else:
|
||||
@ -393,11 +404,11 @@ def delete():
|
||||
return jsonify(output)
|
||||
|
||||
|
||||
def delete_singular(assiduite_id: int, db):
|
||||
assiduite: Assiduite = Assiduite.query.filter_by(id=assiduite_id).first()
|
||||
if assiduite is None:
|
||||
def _delete_singular(assiduite_id: int, database):
|
||||
assiduite_unique: Assiduite = Assiduite.query.filter_by(id=assiduite_id).first()
|
||||
if assiduite_unique is None:
|
||||
return (404, "Assiduite non existante")
|
||||
db.session.delete(assiduite)
|
||||
database.session.delete(assiduite_unique)
|
||||
return (200, "OK")
|
||||
|
||||
|
||||
@ -407,28 +418,31 @@ def delete_singular(assiduite_id: int, db):
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
# @permission_required(Permission.ScoAssiduiteChange)
|
||||
def edit(assiduite_id: int):
|
||||
def assiduite_cedit(assiduite_id: int):
|
||||
"""
|
||||
Edition d'une assiduité à partir de son id
|
||||
La requête doit avoir un content type "application/json":
|
||||
{
|
||||
"etat": str,
|
||||
"moduleimpl_id": int
|
||||
"etat"?: str,
|
||||
"moduleimpl_id"?: int
|
||||
"desc"?: str
|
||||
}
|
||||
"""
|
||||
assiduite: Assiduite = Assiduite.query.filter_by(id=assiduite_id).first_or_404()
|
||||
errors: List[str] = []
|
||||
assiduite_unique: Assiduite = Assiduite.query.filter_by(
|
||||
id=assiduite_id
|
||||
).first_or_404()
|
||||
errors: list[str] = []
|
||||
data = request.get_json(force=True)
|
||||
|
||||
# Vérifications de data
|
||||
|
||||
# Cas 1 : Etat
|
||||
if data.get("etat") is not None:
|
||||
data = change_etat(data, False)
|
||||
data = _change_etat(data, False)
|
||||
if data.get("etat") is None:
|
||||
errors.append("param 'etat': invalide")
|
||||
else:
|
||||
assiduite.etat = data.get("etat")
|
||||
assiduite_unique.etat = data.get("etat")
|
||||
|
||||
# Cas 2 : Moduleimpl_id
|
||||
moduleimpl_id = data.get("moduleimpl_id", False)
|
||||
@ -441,24 +455,30 @@ def edit(assiduite_id: int):
|
||||
errors.append("param 'moduleimpl_id': invalide")
|
||||
else:
|
||||
if not moduleimpl.est_inscrit(
|
||||
Identite.query.filter_by(id=assiduite.etudid).first()
|
||||
Identite.query.filter_by(id=assiduite_unique.etudid).first()
|
||||
):
|
||||
errors.append("param 'moduleimpl_id': etud non inscrit")
|
||||
else:
|
||||
assiduite.moduleimpl_id = moduleimpl_id
|
||||
assiduite_unique.moduleimpl_id = moduleimpl_id
|
||||
else:
|
||||
assiduite.moduleimpl_id = moduleimpl_id
|
||||
if errors != []:
|
||||
assiduite_unique.moduleimpl_id = moduleimpl_id
|
||||
|
||||
# Cas 3 : desc
|
||||
desc = data.get("desc", False)
|
||||
if desc is not False:
|
||||
assiduite_unique.desc = desc
|
||||
|
||||
if errors:
|
||||
err: str = ", ".join(errors)
|
||||
return json_error(404, err)
|
||||
|
||||
db.session.add(assiduite)
|
||||
db.session.add(assiduite_unique)
|
||||
db.session.commit()
|
||||
return jsonify({"OK": True})
|
||||
|
||||
|
||||
# -- Utils --
|
||||
def change_etat(data: dict, from_int: bool = True):
|
||||
def _change_etat(data: dict, from_int: bool = True):
|
||||
"""change dans un json la valeur du champs état"""
|
||||
if from_int:
|
||||
data["etat"] = scu.ETAT_ASSIDUITE_NAME.get(data["etat"])
|
||||
@ -467,104 +487,108 @@ def change_etat(data: dict, from_int: bool = True):
|
||||
return data
|
||||
|
||||
|
||||
def count_manager(request) -> tuple[str, dict]:
|
||||
def _count_manager(requested) -> tuple[str, dict]:
|
||||
"""
|
||||
Retourne la/les métriques à utiliser ainsi que le filtre donnés en query de la requête
|
||||
"""
|
||||
filter: dict = {}
|
||||
filtered: dict = {}
|
||||
# cas 1 : etat assiduite
|
||||
etat = request.args.get("etat")
|
||||
etat = requested.args.get("etat")
|
||||
if etat is not None:
|
||||
filter["etat"] = etat
|
||||
filtered["etat"] = etat
|
||||
|
||||
# cas 2 : date de début
|
||||
deb = request.args.get("date_debut")
|
||||
deb = requested.args.get("date_debut")
|
||||
deb: datetime = scu.is_iso_formated(deb, True)
|
||||
if deb is not None:
|
||||
filter["date_debut"] = deb
|
||||
filtered["date_debut"] = deb
|
||||
|
||||
# cas 3 : date de fin
|
||||
fin = request.args.get("date_fin")
|
||||
fin = requested.args.get("date_fin")
|
||||
fin = scu.is_iso_formated(fin, True)
|
||||
|
||||
if fin is not None:
|
||||
filter["date_fin"] = fin
|
||||
filtered["date_fin"] = fin
|
||||
|
||||
# cas 4 : moduleimpl_id
|
||||
module = request.args.get("moduleimpl_id", False)
|
||||
module = requested.args.get("moduleimpl_id", False)
|
||||
try:
|
||||
if module is False:
|
||||
raise Exception
|
||||
raise ValueError
|
||||
if module != "":
|
||||
module = int(module)
|
||||
else:
|
||||
module = None
|
||||
except Exception:
|
||||
except ValueError:
|
||||
module = False
|
||||
|
||||
if module is not False:
|
||||
filter["moduleimpl_id"] = module
|
||||
filtered["moduleimpl_id"] = module
|
||||
|
||||
# cas 5 : formsemestre_id
|
||||
formsemestre_id = request.args.get("formsemestre_id")
|
||||
formsemestre_id = requested.args.get("formsemestre_id")
|
||||
|
||||
if formsemestre_id is not None:
|
||||
formsemestre: FormSemestre = None
|
||||
formsemestre_id = int(formsemestre_id)
|
||||
formsemestre = FormSemestre.query.filter_by(id=formsemestre_id).first()
|
||||
filter["formsemestre"] = formsemestre
|
||||
filtered["formsemestre"] = formsemestre
|
||||
|
||||
# cas 6 : type
|
||||
metric = request.args.get("metric", "all")
|
||||
metric = requested.args.get("metric", "all")
|
||||
|
||||
return (metric, filter)
|
||||
return (metric, filtered)
|
||||
|
||||
|
||||
def filter_manager(request, assiduites):
|
||||
def _filter_manager(requested, assiduites_query):
|
||||
"""
|
||||
Retourne les assiduites entrées filtrées en fonction de la request
|
||||
"""
|
||||
# cas 1 : etat assiduite
|
||||
etat = request.args.get("etat")
|
||||
etat = requested.args.get("etat")
|
||||
if etat is not None:
|
||||
assiduites = scass.filter_by_etat(assiduites, etat)
|
||||
assiduites_query = scass.filter_assiduites_by_etat(assiduites_query, etat)
|
||||
|
||||
# cas 2 : date de début
|
||||
deb = request.args.get("date_debut")
|
||||
deb = requested.args.get("date_debut")
|
||||
deb: datetime = scu.is_iso_formated(deb, True)
|
||||
if deb is not None:
|
||||
|
||||
assiduites = scass.filter_by_date(assiduites, deb, sup=True)
|
||||
assiduites_query = scass.filter_assiduites_by_date(
|
||||
assiduites_query, deb, sup=True
|
||||
)
|
||||
|
||||
# cas 3 : date de fin
|
||||
fin = request.args.get("date_fin")
|
||||
fin = requested.args.get("date_fin")
|
||||
fin = scu.is_iso_formated(fin, True)
|
||||
|
||||
if fin is not None:
|
||||
assiduites = scass.filter_by_date(assiduites, fin, sup=False)
|
||||
assiduites_query = scass.filter_assiduites_by_date(
|
||||
assiduites_query, fin, sup=False
|
||||
)
|
||||
|
||||
# cas 4 : moduleimpl_id
|
||||
module = request.args.get("moduleimpl_id", False)
|
||||
module = requested.args.get("moduleimpl_id", False)
|
||||
try:
|
||||
if module is False:
|
||||
raise Exception
|
||||
raise ValueError
|
||||
if module != "":
|
||||
module = int(module)
|
||||
else:
|
||||
module = None
|
||||
except Exception:
|
||||
except ValueError:
|
||||
module = False
|
||||
|
||||
if module is not False:
|
||||
assiduites = scass.filter_by_module_impl(assiduites, module)
|
||||
assiduites_query = scass.filter_by_module_impl(assiduites_query, module)
|
||||
|
||||
# cas 5 : formsemestre_id
|
||||
formsemestre_id = request.args.get("formsemestre_id")
|
||||
formsemestre_id = requested.args.get("formsemestre_id")
|
||||
|
||||
if formsemestre_id is not None:
|
||||
formsemestre: FormSemestre = None
|
||||
formsemestre_id = int(formsemestre_id)
|
||||
formsemestre = FormSemestre.query.filter_by(id=formsemestre_id).first()
|
||||
assiduites = scass.filter_by_formsemstre(assiduites, formsemestre)
|
||||
assiduites_query = scass.filter_by_formsemestre(assiduites_query, formsemestre)
|
||||
|
||||
return assiduites
|
||||
return assiduites_query
|
||||
|
536
app/api/justificatif.py
Normal file
536
app/api/justificatif.py
Normal file
@ -0,0 +1,536 @@
|
||||
##############################################################################
|
||||
# ScoDoc
|
||||
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
||||
# See LICENSE
|
||||
##############################################################################
|
||||
"""ScoDoc 9 API : Assiduités
|
||||
"""
|
||||
import os
|
||||
from datetime import datetime
|
||||
|
||||
import app.scodoc.sco_assiduites as scass
|
||||
import app.scodoc.sco_utils as scu
|
||||
from app import db
|
||||
|
||||
from app.api import api_bp as bp
|
||||
from app.api import api_web_bp
|
||||
from app.scodoc.sco_exceptions import ScoValueError
|
||||
from app.decorators import permission_required, scodoc
|
||||
from app.models import Identite, Justificatif
|
||||
from app.scodoc.sco_archives_justificatifs import JustificatifArchiver
|
||||
from app.scodoc.sco_permissions import Permission
|
||||
from flask import g, jsonify, request
|
||||
from flask_login import login_required
|
||||
from app.scodoc.sco_utils import json_error
|
||||
|
||||
|
||||
# @bp.route("/justificatif/remove")
|
||||
# @api_web_bp.route("/justificatif/remove")
|
||||
# @scodoc
|
||||
# def justremove():
|
||||
# """ """
|
||||
# archiver: JustificatifArchiver = JustificatifArchiver()
|
||||
|
||||
# archiver.delete_justificatif(etudid=1, archive_id="2023-02-01-10-29-20")
|
||||
# return jsonify("done")
|
||||
|
||||
# Partie Modèle
|
||||
# TODO: justificatif
|
||||
@bp.route("/justificatif/<int:justif_id>")
|
||||
@api_web_bp.route("/assiduite/<int:justif_id>")
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
def justificatif(justif_id: int = None):
|
||||
"""Retourne un objet justificatif à partir de son id
|
||||
|
||||
Exemple de résultat:
|
||||
{
|
||||
"justif_id": 1,
|
||||
"etudid": 2,
|
||||
"date_debut": "2022-10-31T08:00+01:00",
|
||||
"date_fin": "2022-10-31T10:00+01:00",
|
||||
"etat": "valide",
|
||||
"fichier": "archive_id",
|
||||
"raison": "une raison",
|
||||
"entry_date": "2022-10-31T08:00+01:00",
|
||||
}
|
||||
"""
|
||||
|
||||
query = Justificatif.query.filter_by(id=justif_id)
|
||||
if g.scodoc_dept:
|
||||
query = query.join(Identite).filter_by(dept_id=g.scodoc_dept_id)
|
||||
justificatif_unique = query.first_or_404()
|
||||
|
||||
data = justificatif_unique.to_dict()
|
||||
|
||||
return jsonify(_change_etat(data))
|
||||
|
||||
|
||||
# TODO: justificatifs[-query]
|
||||
@bp.route("/justificatifs/<int:etudid>", defaults={"with_query": False})
|
||||
@bp.route("/justificatifs/<int:etudid>/query", defaults={"with_query": True})
|
||||
@api_web_bp.route("/justificatifs/<int:etudid>", defaults={"with_query": False})
|
||||
@api_web_bp.route("/justificatifs/<int:etudid>/query", defaults={"with_query": True})
|
||||
@login_required
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
def justificatifs(etudid: int = None, with_query: bool = False):
|
||||
"""
|
||||
Retourne toutes les assiduités d'un étudiant
|
||||
chemin : /justificatifs/<int:etudid>
|
||||
|
||||
Un filtrage peut être donné avec une query
|
||||
chemin : /justificatifs/<int:etudid>/query?
|
||||
|
||||
Les différents filtres :
|
||||
Etat (etat du justificatif -> validé, non validé, modifé, en attente):
|
||||
query?etat=[- liste des états séparé par une virgule -]
|
||||
ex: .../query?etat=validé,modifié
|
||||
Date debut
|
||||
(date de début du justificatif, sont affichés les justificatifs
|
||||
dont la date de début est supérieur ou égale à la valeur donnée):
|
||||
query?date_debut=[- date au format iso -]
|
||||
ex: query?date_debut=2022-11-03T08:00+01:00
|
||||
Date fin
|
||||
(date de fin du justificatif, sont affichés les justificatifs
|
||||
dont la date de fin est inférieure ou égale à la valeur donnée):
|
||||
query?date_fin=[- date au format iso -]
|
||||
ex: query?date_fin=2022-11-03T10:00+01:00
|
||||
"""
|
||||
|
||||
query = Identite.query.filter_by(id=etudid)
|
||||
if g.scodoc_dept:
|
||||
query = query.filter_by(dept_id=g.scodoc_dept_id)
|
||||
|
||||
etud: Identite = query.first_or_404(etudid)
|
||||
justificatifs_query = etud.justificatifs
|
||||
|
||||
if with_query:
|
||||
justificatifs_query = _filter_manager(request, justificatifs_query)
|
||||
|
||||
data_set: list[dict] = []
|
||||
for just in justificatifs_query.all():
|
||||
data = just.to_dict()
|
||||
data_set.append(_change_etat(data))
|
||||
|
||||
return jsonify(data_set)
|
||||
|
||||
|
||||
# TODO: justificatif-create
|
||||
@bp.route("/justificatif/<int:etudid>/create", methods=["POST"])
|
||||
@api_web_bp.route("/justificatif/<int:etudid>/create", methods=["POST"])
|
||||
@scodoc
|
||||
@login_required
|
||||
@permission_required(Permission.ScoView)
|
||||
# @permission_required(Permission.ScoAssiduiteChange)
|
||||
def justif_create(etudid: int = None):
|
||||
"""
|
||||
Création d'un justificatif pour l'étudiant (etudid)
|
||||
La requête doit avoir un content type "application/json":
|
||||
[
|
||||
{
|
||||
"date_debut": str,
|
||||
"date_fin": str,
|
||||
"etat": str,
|
||||
},
|
||||
{
|
||||
"date_debut": str,
|
||||
"date_fin": str,
|
||||
"etat": str,
|
||||
"raison":str,
|
||||
}
|
||||
...
|
||||
]
|
||||
|
||||
"""
|
||||
etud: Identite = Identite.query.filter_by(id=etudid).first_or_404()
|
||||
|
||||
create_list: list[object] = request.get_json(force=True)
|
||||
|
||||
if not isinstance(create_list, list):
|
||||
return json_error(404, "Le contenu envoyé n'est pas une liste")
|
||||
|
||||
errors: dict[int, str] = {}
|
||||
success: dict[int, object] = {}
|
||||
for i, data in enumerate(create_list):
|
||||
code, obj = _create_singular(data, etud)
|
||||
if code == 404:
|
||||
errors[i] = obj
|
||||
else:
|
||||
success[i] = obj
|
||||
|
||||
return jsonify({"errors": errors, "success": success})
|
||||
|
||||
|
||||
def _create_singular(
|
||||
data: dict,
|
||||
etud: Identite,
|
||||
) -> tuple[int, object]:
|
||||
errors: list[str] = []
|
||||
|
||||
# -- vérifications de l'objet json --
|
||||
# cas 1 : ETAT
|
||||
etat = data.get("etat", None)
|
||||
if etat is None:
|
||||
errors.append("param 'etat': manquant")
|
||||
elif etat not in scu.ETATS_JUSTIFICATIF:
|
||||
errors.append("param 'etat': invalide")
|
||||
|
||||
data = _change_etat(data, False)
|
||||
etat = data.get("etat", None)
|
||||
|
||||
# cas 2 : date_debut
|
||||
date_debut = data.get("date_debut", None)
|
||||
if date_debut is None:
|
||||
errors.append("param 'date_debut': manquant")
|
||||
deb = scu.is_iso_formated(date_debut, convert=True)
|
||||
if deb is None:
|
||||
errors.append("param 'date_debut': format invalide")
|
||||
|
||||
# cas 3 : date_fin
|
||||
date_fin = data.get("date_fin", None)
|
||||
if date_fin is None:
|
||||
errors.append("param 'date_fin': manquant")
|
||||
fin = scu.is_iso_formated(date_fin, convert=True)
|
||||
if fin is None:
|
||||
errors.append("param 'date_fin': format invalide")
|
||||
|
||||
# cas 4 : raison
|
||||
|
||||
raison: str = data.get("raison", None)
|
||||
|
||||
if errors:
|
||||
err: str = ", ".join(errors)
|
||||
return (404, err)
|
||||
|
||||
# TOUT EST OK
|
||||
|
||||
try:
|
||||
nouv_justificatif: Justificatif = Justificatif.create_justificatif(
|
||||
date_debut=deb,
|
||||
date_fin=fin,
|
||||
etat=etat,
|
||||
etud=etud,
|
||||
raison=raison,
|
||||
)
|
||||
|
||||
db.session.add(nouv_justificatif)
|
||||
db.session.commit()
|
||||
return (200, {"justif_id": nouv_justificatif.id})
|
||||
except ScoValueError as excp:
|
||||
return (
|
||||
404,
|
||||
excp.args[0],
|
||||
)
|
||||
|
||||
|
||||
# TODO: justificatif-edit
|
||||
@bp.route("/justificatif/<int:justif_id>/edit", methods=["POST"])
|
||||
@api_web_bp.route("/justificatif/<int:justif_id>/edit", methods=["POST"])
|
||||
@login_required
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
# @permission_required(Permission.ScoAssiduiteChange)
|
||||
def justif_edit(justif_id: int):
|
||||
"""
|
||||
Edition d'un justificatif à partir de son id
|
||||
La requête doit avoir un content type "application/json":
|
||||
{
|
||||
"etat"?: str,
|
||||
"raison"?: str
|
||||
}
|
||||
"""
|
||||
justificatif_unique: Justificatif = Justificatif.query.filter_by(
|
||||
id=justif_id
|
||||
).first_or_404()
|
||||
errors: list[str] = []
|
||||
data = request.get_json(force=True)
|
||||
|
||||
# Vérifications de data
|
||||
|
||||
# Cas 1 : Etat
|
||||
if data.get("etat") is not None:
|
||||
data = _change_etat(data, False)
|
||||
if data.get("etat") is None:
|
||||
errors.append("param 'etat': invalide")
|
||||
else:
|
||||
justificatif_unique.etat = data.get("etat")
|
||||
|
||||
# Cas 2 : raison
|
||||
raison = data.get("raison", False)
|
||||
if raison is not False:
|
||||
justificatif_unique.raison = raison
|
||||
|
||||
if errors:
|
||||
err: str = ", ".join(errors)
|
||||
return json_error(404, err)
|
||||
|
||||
db.session.add(justificatif_unique)
|
||||
db.session.commit()
|
||||
return jsonify({"OK": True})
|
||||
|
||||
|
||||
# TODO: justificatif-delete
|
||||
@bp.route("/justificatif/delete", methods=["POST"])
|
||||
@api_web_bp.route("/justificatif/delete", methods=["POST"])
|
||||
@login_required
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
# @permission_required(Permission.ScoAssiduiteChange)
|
||||
def justif_delete():
|
||||
"""
|
||||
Suppression d'un justificatif à partir de son id
|
||||
|
||||
Forme des données envoyées :
|
||||
|
||||
[
|
||||
<justif_id:int>,
|
||||
...
|
||||
]
|
||||
|
||||
|
||||
"""
|
||||
justificatifs_list: list[int] = request.get_json(force=True)
|
||||
if not isinstance(justificatifs_list, list):
|
||||
return json_error(404, "Le contenu envoyé n'est pas une liste")
|
||||
|
||||
output = {"errors": {}, "success": {}}
|
||||
|
||||
for i, ass in enumerate(justificatifs_list):
|
||||
code, msg = _delete_singular(ass, db)
|
||||
if code == 404:
|
||||
output["errors"][f"{i}"] = msg
|
||||
else:
|
||||
output["success"][f"{i}"] = {"OK": True}
|
||||
db.session.commit()
|
||||
return jsonify(output)
|
||||
|
||||
|
||||
def _delete_singular(justif_id: int, database):
|
||||
justificatif_unique: Justificatif = Justificatif.query.filter_by(
|
||||
id=justif_id
|
||||
).first()
|
||||
if justificatif_unique is None:
|
||||
return (404, "Justificatif non existant")
|
||||
database.session.delete(justificatif_unique)
|
||||
return (200, "OK")
|
||||
|
||||
|
||||
# Partie archivage
|
||||
# TODO: justificatif-import
|
||||
@bp.route("/justificatif/import/<int:justif_id>", methods=["POST"])
|
||||
@api_web_bp.route("/justificatif/import/<int:justif_id>", methods=["POST"])
|
||||
@scodoc
|
||||
@login_required
|
||||
@permission_required(Permission.ScoView)
|
||||
# @permission_required(Permission.ScoAssiduiteChange)
|
||||
def justif_import(justif_id: int = None):
|
||||
"""
|
||||
Importation d'un fichier (création d'archive)
|
||||
"""
|
||||
if len(request.files) == 0:
|
||||
return json_error(404, "Il n'y a pas de fichier joint")
|
||||
|
||||
file = list(request.files.values())[0]
|
||||
if file.filename == "":
|
||||
return json_error(404, "Il n'y a pas de fichier joint")
|
||||
|
||||
query = Justificatif.query.filter_by(id=justif_id)
|
||||
if g.scodoc_dept:
|
||||
query = query.join(Identite).filter_by(dept_id=g.scodoc_dept_id)
|
||||
|
||||
justificatif_unique: Justificatif = query.first_or_404()
|
||||
|
||||
archive_name: str = justificatif_unique.fichier
|
||||
|
||||
archiver: JustificatifArchiver = JustificatifArchiver()
|
||||
try:
|
||||
archive_name: str = archiver.save_justificatif(
|
||||
etudid=justificatif_unique.etudid,
|
||||
filename=file.filename,
|
||||
data=file.stream.read(),
|
||||
archive_name=archive_name,
|
||||
)
|
||||
|
||||
justificatif_unique.fichier = archive_name
|
||||
|
||||
db.session.add(justificatif_unique)
|
||||
db.session.commit()
|
||||
|
||||
return jsonify({"response": "imported"})
|
||||
except ScoValueError as err:
|
||||
return json_error(404, err.args[1])
|
||||
|
||||
|
||||
# TODO: justificatif-export
|
||||
@bp.route("/justificatif/export/<int:justif_id>/<filename>", methods=["GET"])
|
||||
@api_web_bp.route("/justificatif/export/<int:justif_id>/<filename>", methods=["GET"])
|
||||
@scodoc
|
||||
@login_required
|
||||
@permission_required(Permission.ScoView)
|
||||
# @permission_required(Permission.ScoAssiduiteChange)
|
||||
def justif_export(justif_id: int = None, filename: str = None):
|
||||
"""
|
||||
Retourne un fichier d'une archive d'un justificatif
|
||||
"""
|
||||
|
||||
query = Justificatif.query.filter_by(id=justif_id)
|
||||
if g.scodoc_dept:
|
||||
query = query.join(Identite).filter_by(dept_id=g.scodoc_dept_id)
|
||||
|
||||
justificatif_unique: Justificatif = query.first_or_404()
|
||||
|
||||
archive_name: str = justificatif_unique.fichier
|
||||
if archive_name is None:
|
||||
return json_error(404, "le justificatif ne possède pas de fichier")
|
||||
|
||||
archiver: JustificatifArchiver = JustificatifArchiver()
|
||||
|
||||
try:
|
||||
return archiver.get_justificatif_file(
|
||||
archive_name, justificatif_unique.etudid, filename
|
||||
)
|
||||
except ScoValueError as err:
|
||||
return json_error(404, err.args[1])
|
||||
|
||||
|
||||
# TODO: justificatif-remove
|
||||
@bp.route("/justificatif/remove/<int:justif_id>", methods=["POST"])
|
||||
@api_web_bp.route("/justificatif/remove/<int:justif_id>", methods=["POST"])
|
||||
@scodoc
|
||||
@login_required
|
||||
@permission_required(Permission.ScoView)
|
||||
# @permission_required(Permission.ScoAssiduiteChange)
|
||||
def justif_remove(justif_id: int = None):
|
||||
"""
|
||||
Supression d'un fichier ou d'une archive
|
||||
|
||||
{
|
||||
"remove": <"all"/"list">
|
||||
|
||||
"filenames"?: [
|
||||
<filename:str>,
|
||||
...
|
||||
]
|
||||
}
|
||||
"""
|
||||
|
||||
data: dict = request.get_json(force=True)
|
||||
|
||||
query = Justificatif.query.filter_by(id=justif_id)
|
||||
if g.scodoc_dept:
|
||||
query = query.join(Identite).filter_by(dept_id=g.scodoc_dept_id)
|
||||
|
||||
justificatif_unique: Justificatif = query.first_or_404()
|
||||
|
||||
archive_name: str = justificatif_unique.fichier
|
||||
if archive_name is None:
|
||||
return json_error(404, "le justificatif ne possède pas de fichier")
|
||||
|
||||
remove: str = data.get("remove")
|
||||
if remove is None or remove not in ("all", "list"):
|
||||
return json_error(404, "param 'remove': Valeur invalide")
|
||||
archiver: JustificatifArchiver = JustificatifArchiver()
|
||||
etudid: int = justificatif_unique.etudid
|
||||
try:
|
||||
if remove == "all":
|
||||
archiver.delete_justificatif(etudid=etudid, archive_name=archive_name)
|
||||
justificatif_unique.fichier = None
|
||||
db.session.add(justificatif_unique)
|
||||
db.session.commit()
|
||||
|
||||
else:
|
||||
for fname in data.get("filenames", []):
|
||||
archiver.delete_justificatif(
|
||||
etudid=etudid,
|
||||
archive_name=archive_name,
|
||||
filename=fname,
|
||||
)
|
||||
|
||||
if len(archiver.list_justificatifs(archive_name, etudid)) == 0:
|
||||
archiver.delete_justificatif(etudid, archive_name)
|
||||
justificatif_unique.fichier = None
|
||||
db.session.add(justificatif_unique)
|
||||
db.session.commit()
|
||||
|
||||
except ScoValueError as err:
|
||||
return json_error(404, err.args[1])
|
||||
|
||||
return jsonify({"response": "removed"})
|
||||
|
||||
|
||||
# TODO: justificatif-list
|
||||
@bp.route("/justificatif/list/<int:justif_id>", methods=["GET"])
|
||||
@api_web_bp.route("/justificatif/list/<int:justif_id>", methods=["GET"])
|
||||
@scodoc
|
||||
@login_required
|
||||
@permission_required(Permission.ScoView)
|
||||
# @permission_required(Permission.ScoAssiduiteChange)
|
||||
def justif_list(justif_id: int = None):
|
||||
"""
|
||||
Liste les fichiers du justificatif
|
||||
"""
|
||||
|
||||
query = Justificatif.query.filter_by(id=justif_id)
|
||||
if g.scodoc_dept:
|
||||
query = query.join(Identite).filter_by(dept_id=g.scodoc_dept_id)
|
||||
|
||||
justificatif_unique: Justificatif = query.first_or_404()
|
||||
|
||||
archive_name: str = justificatif_unique.fichier
|
||||
|
||||
filenames: list[str] = []
|
||||
|
||||
archiver: JustificatifArchiver = JustificatifArchiver()
|
||||
if archive_name is not None:
|
||||
filenames = archiver.list_justificatifs(
|
||||
archive_name, justificatif_unique.etudid
|
||||
)
|
||||
|
||||
return jsonify(filenames)
|
||||
|
||||
|
||||
# Partie justification
|
||||
# TODO: justificatif-justified
|
||||
|
||||
|
||||
# -- Utils --
|
||||
def _change_etat(data: dict, from_int: bool = True):
|
||||
"""change dans un json la valeur du champs état"""
|
||||
if from_int:
|
||||
data["etat"] = scu.ETAT_JUSTIFICATIF_NAME.get(data["etat"])
|
||||
else:
|
||||
data["etat"] = scu.ETATS_JUSTIFICATIF.get(data["etat"])
|
||||
return data
|
||||
|
||||
|
||||
def _filter_manager(requested, justificatifs_query):
|
||||
"""
|
||||
Retourne les justificatifs entrés filtrés en fonction de la request
|
||||
"""
|
||||
# cas 1 : etat justificatif
|
||||
etat = requested.args.get("etat")
|
||||
if etat is not None:
|
||||
justificatifs_query = scass.filter_justificatifs_by_etat(
|
||||
justificatifs_query, etat
|
||||
)
|
||||
|
||||
# cas 2 : date de début
|
||||
deb = requested.args.get("date_debut")
|
||||
deb: datetime = scu.is_iso_formated(deb, True)
|
||||
if deb is not None:
|
||||
|
||||
justificatifs_query = scass.filter_justificatifs_by_date(
|
||||
justificatifs_query, deb, sup=True
|
||||
)
|
||||
|
||||
# cas 3 : date de fin
|
||||
fin = requested.args.get("date_fin")
|
||||
fin = scu.is_iso_formated(fin, True)
|
||||
|
||||
if fin is not None:
|
||||
justificatifs_query = scass.filter_justificatifs_by_date(
|
||||
justificatifs_query, fin, sup=False
|
||||
)
|
||||
|
||||
return justificatifs_query
|
@ -11,5 +11,5 @@ def send_password_reset_email(user):
|
||||
sender=current_app.config["SCODOC_MAIL_FROM"],
|
||||
recipients=[user.email],
|
||||
text_body=render_template("email/reset_password.txt", user=user, token=token),
|
||||
html_body=render_template("email/reset_password.html", user=user, token=token),
|
||||
html_body=render_template("email/reset_password.j2", user=user, token=token),
|
||||
)
|
||||
|
@ -42,7 +42,7 @@ def login():
|
||||
return form.redirect("scodoc.index")
|
||||
message = request.args.get("message", "")
|
||||
return render_template(
|
||||
"auth/login.html", title=_("Sign In"), form=form, message=message
|
||||
"auth/login.j2", title=_("Sign In"), form=form, message=message
|
||||
)
|
||||
|
||||
|
||||
@ -65,9 +65,7 @@ def create_user():
|
||||
db.session.commit()
|
||||
flash(f"Utilisateur {user.user_name} créé")
|
||||
return redirect(url_for("scodoc.index"))
|
||||
return render_template(
|
||||
"auth/register.html", title="Création utilisateur", form=form
|
||||
)
|
||||
return render_template("auth/register.j2", title="Création utilisateur", form=form)
|
||||
|
||||
|
||||
@bp.route("/reset_password_request", methods=["GET", "POST"])
|
||||
@ -98,7 +96,7 @@ def reset_password_request():
|
||||
)
|
||||
return redirect(url_for("auth.login"))
|
||||
return render_template(
|
||||
"auth/reset_password_request.html", title=_("Reset Password"), form=form
|
||||
"auth/reset_password_request.j2", title=_("Reset Password"), form=form
|
||||
)
|
||||
|
||||
|
||||
@ -116,7 +114,7 @@ def reset_password(token):
|
||||
db.session.commit()
|
||||
flash(_("Votre mot de passe a été changé."))
|
||||
return redirect(url_for("auth.login"))
|
||||
return render_template("auth/reset_password.html", form=form, user=user)
|
||||
return render_template("auth/reset_password.j2", form=form, user=user)
|
||||
|
||||
|
||||
@bp.route("/reset_standard_roles_permissions", methods=["GET", "POST"])
|
||||
|
@ -841,6 +841,7 @@ class DecisionsProposeesAnnee(DecisionsProposees):
|
||||
et autorisations d'inscription émises.
|
||||
Efface même si étudiant DEM ou DEF.
|
||||
Si à cheval, n'efface que pour le semestre d'origine du deca.
|
||||
(commite la session.)
|
||||
"""
|
||||
if only_one_sem or self.a_cheval:
|
||||
# N'efface que les autorisations venant de ce semestre,
|
||||
|
@ -500,7 +500,7 @@ def jury_but_semestriel(
|
||||
H.append("</div>")
|
||||
H.append(
|
||||
render_template(
|
||||
"but/documentation_codes_jury.html",
|
||||
"but/documentation_codes_jury.j2",
|
||||
nom_univ=f"""Export {sco_preferences.get_preference("InstituteName")
|
||||
or sco_preferences.get_preference("UnivName")
|
||||
or "Apogée"}""",
|
||||
|
@ -1358,6 +1358,44 @@ class BonusIUTvannes(BonusSportAdditif):
|
||||
classic_use_bonus_ues = False # seulement sur moy gen.
|
||||
|
||||
|
||||
class BonusValenciennes(BonusDirect):
|
||||
"""Article 7 des RCC de l’IUT de Valenciennes
|
||||
|
||||
<p>
|
||||
Une bonification maximale de 0.25 point (1/4 de point) peut être ajoutée
|
||||
à la moyenne de chaque Unité d’Enseignement pour :
|
||||
</p>
|
||||
<ul>
|
||||
<li>l'engagement citoyen ;</li>
|
||||
<li>la participation à un module de sport.</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
Une bonification accordée par la commission des sports de l’UPHF peut être attribuée
|
||||
aux sportifs de haut niveau. Cette bonification est appliquée à l’ensemble des
|
||||
Unités d’Enseignement. Ce bonus est :
|
||||
</p>
|
||||
<ul>
|
||||
<li> 0.5 pour la catégorie <em>or</em> (sportif inscrit sur liste ministérielle
|
||||
jeunesse et sport) ;
|
||||
</li>
|
||||
<li> 0.45 pour la catégorie <em>argent</em> (sportif en club professionnel) ;
|
||||
</li>
|
||||
<li> 0.40 pour le <em>bronze</em> (sportif de niveau départemental, régional ou national).
|
||||
</li>
|
||||
</ul>
|
||||
<p>Le cumul de bonifications est possible mais ne peut excéder 0.5 point (un demi-point).
|
||||
</p>
|
||||
<p><em>Dans ScoDoc, saisir directement la valeur désirée du bonus
|
||||
dans une évaluation notée sur 20.</em>
|
||||
</p>
|
||||
"""
|
||||
|
||||
name = "bonus_valenciennes"
|
||||
displayed_name = "IUT de Valenciennes"
|
||||
bonus_max = 0.5
|
||||
|
||||
|
||||
class BonusVilleAvray(BonusSportAdditif):
|
||||
"""Bonus modules optionnels (sport, culture), règle IUT Ville d'Avray.
|
||||
|
||||
|
@ -33,7 +33,10 @@ import pandas as pd
|
||||
from app import db
|
||||
from app import models
|
||||
from app.models import (
|
||||
DispenseUE,
|
||||
FormSemestre,
|
||||
FormSemestreInscription,
|
||||
Identite,
|
||||
Module,
|
||||
ModuleImpl,
|
||||
ModuleUECoef,
|
||||
@ -215,6 +218,31 @@ def notes_sem_load_cube(formsemestre: FormSemestre) -> tuple:
|
||||
)
|
||||
|
||||
|
||||
def load_dispense_ues(
|
||||
formsemestre: FormSemestre, etudids: pd.Index, ues: list[UniteEns]
|
||||
) -> set[tuple[int, int]]:
|
||||
"""Construit l'ensemble des
|
||||
etudids = modimpl_inscr_df.index, # les etudids
|
||||
ue_ids : modimpl_coefs_df.index, # les UE du formsemestre sans les UE bonus sport
|
||||
|
||||
Résultat: set de (etudid, ue_id).
|
||||
"""
|
||||
dispense_ues = set()
|
||||
ue_sem_by_code = {ue.ue_code: ue for ue in ues}
|
||||
# Prend toutes les dispenses obtenues par des étudiants de ce formsemestre,
|
||||
# puis filtre sur inscrits et code d'UE UE
|
||||
for dispense_ue in DispenseUE.query.join(
|
||||
Identite, FormSemestreInscription
|
||||
).filter_by(formsemestre_id=formsemestre.id):
|
||||
if dispense_ue.etudid in etudids:
|
||||
# UE dans le semestre avec même code ?
|
||||
ue = ue_sem_by_code.get(dispense_ue.ue.ue_code)
|
||||
if ue is not None:
|
||||
dispense_ues.add((dispense_ue.etudid, ue.id))
|
||||
|
||||
return dispense_ues
|
||||
|
||||
|
||||
def compute_ue_moys_apc(
|
||||
sem_cube: np.array,
|
||||
etuds: list,
|
||||
|
@ -72,7 +72,7 @@ class ResultatsSemestreBUT(NotesTableCompat):
|
||||
modimpl.module.ue.type != UE_SPORT
|
||||
for modimpl in self.formsemestre.modimpls_sorted
|
||||
]
|
||||
self.dispense_ues = DispenseUE.load_formsemestre_dispense_ues_set(
|
||||
self.dispense_ues = moy_ue.load_dispense_ues(
|
||||
self.formsemestre, self.modimpl_inscr_df.index, self.ues
|
||||
)
|
||||
self.etud_moy_ue = moy_ue.compute_ue_moys_apc(
|
||||
|
@ -89,7 +89,7 @@ def index():
|
||||
visible=True, association=True, siret_provisoire=True
|
||||
)
|
||||
return render_template(
|
||||
"entreprises/entreprises.html",
|
||||
"entreprises/entreprises.j2",
|
||||
title="Entreprises",
|
||||
entreprises=entreprises,
|
||||
logs=logs,
|
||||
@ -109,7 +109,7 @@ def logs():
|
||||
EntrepriseHistorique.date.desc()
|
||||
).paginate(page=page, per_page=20)
|
||||
return render_template(
|
||||
"entreprises/logs.html",
|
||||
"entreprises/logs.j2",
|
||||
title="Logs",
|
||||
logs=logs,
|
||||
)
|
||||
@ -134,7 +134,7 @@ def correspondants():
|
||||
.all()
|
||||
)
|
||||
return render_template(
|
||||
"entreprises/correspondants.html",
|
||||
"entreprises/correspondants.j2",
|
||||
title="Correspondants",
|
||||
correspondants=correspondants,
|
||||
logs=logs,
|
||||
@ -149,7 +149,7 @@ def validation():
|
||||
"""
|
||||
entreprises = Entreprise.query.filter_by(visible=False).all()
|
||||
return render_template(
|
||||
"entreprises/entreprises_validation.html",
|
||||
"entreprises/entreprises_validation.j2",
|
||||
title="Validation entreprises",
|
||||
entreprises=entreprises,
|
||||
)
|
||||
@ -167,7 +167,7 @@ def fiche_entreprise_validation(entreprise_id):
|
||||
description=f"fiche entreprise (validation) {entreprise_id} inconnue"
|
||||
)
|
||||
return render_template(
|
||||
"entreprises/fiche_entreprise_validation.html",
|
||||
"entreprises/fiche_entreprise_validation.j2",
|
||||
title="Validation fiche entreprise",
|
||||
entreprise=entreprise,
|
||||
)
|
||||
@ -205,7 +205,7 @@ def validate_entreprise(entreprise_id):
|
||||
flash("L'entreprise a été validé et ajouté à la liste.")
|
||||
return redirect(url_for("entreprises.validation"))
|
||||
return render_template(
|
||||
"entreprises/form_validate_confirmation.html",
|
||||
"entreprises/form_validate_confirmation.j2",
|
||||
title="Validation entreprise",
|
||||
form=form,
|
||||
)
|
||||
@ -242,7 +242,7 @@ def delete_validation_entreprise(entreprise_id):
|
||||
flash("L'entreprise a été supprimé de la liste des entreprise à valider.")
|
||||
return redirect(url_for("entreprises.validation"))
|
||||
return render_template(
|
||||
"entreprises/form_confirmation.html",
|
||||
"entreprises/form_confirmation.j2",
|
||||
title="Supression entreprise",
|
||||
form=form,
|
||||
info_message="Cliquez sur le bouton Supprimer pour confirmer votre supression",
|
||||
@ -282,7 +282,7 @@ def offres_recues():
|
||||
files.append(file)
|
||||
offres_recues_with_files.append([envoi_offre, offre, files, correspondant])
|
||||
return render_template(
|
||||
"entreprises/offres_recues.html",
|
||||
"entreprises/offres_recues.j2",
|
||||
title="Offres reçues",
|
||||
offres_recues=offres_recues_with_files,
|
||||
)
|
||||
@ -321,7 +321,7 @@ def preferences():
|
||||
form.mail_entreprise.data = EntreprisePreferences.get_email_notifications()
|
||||
form.check_siret.data = int(EntreprisePreferences.get_check_siret())
|
||||
return render_template(
|
||||
"entreprises/preferences.html",
|
||||
"entreprises/preferences.j2",
|
||||
title="Préférences",
|
||||
form=form,
|
||||
)
|
||||
@ -357,7 +357,7 @@ def add_entreprise():
|
||||
db.session.rollback()
|
||||
flash("Une erreur est survenue veuillez réessayer.")
|
||||
return render_template(
|
||||
"entreprises/form_ajout_entreprise.html",
|
||||
"entreprises/form_ajout_entreprise.j2",
|
||||
title="Ajout entreprise avec correspondant",
|
||||
form=form,
|
||||
)
|
||||
@ -408,7 +408,7 @@ def add_entreprise():
|
||||
flash("L'entreprise a été ajouté à la liste pour la validation.")
|
||||
return redirect(url_for("entreprises.index"))
|
||||
return render_template(
|
||||
"entreprises/form_ajout_entreprise.html",
|
||||
"entreprises/form_ajout_entreprise.j2",
|
||||
title="Ajout entreprise avec correspondant",
|
||||
form=form,
|
||||
)
|
||||
@ -446,7 +446,7 @@ def fiche_entreprise(entreprise_id):
|
||||
.all()
|
||||
)
|
||||
return render_template(
|
||||
"entreprises/fiche_entreprise.html",
|
||||
"entreprises/fiche_entreprise.j2",
|
||||
title="Fiche entreprise",
|
||||
entreprise=entreprise,
|
||||
offres=offres_with_files,
|
||||
@ -472,7 +472,7 @@ def logs_entreprise(entreprise_id):
|
||||
.paginate(page=page, per_page=20)
|
||||
)
|
||||
return render_template(
|
||||
"entreprises/logs_entreprise.html",
|
||||
"entreprises/logs_entreprise.j2",
|
||||
title="Logs",
|
||||
logs=logs,
|
||||
entreprise=entreprise,
|
||||
@ -490,7 +490,7 @@ def offres_expirees(entreprise_id):
|
||||
).first_or_404(description=f"fiche entreprise {entreprise_id} inconnue")
|
||||
offres_with_files = are.get_offres_expirees_with_files(entreprise.offres)
|
||||
return render_template(
|
||||
"entreprises/offres_expirees.html",
|
||||
"entreprises/offres_expirees.j2",
|
||||
title="Offres expirées",
|
||||
entreprise=entreprise,
|
||||
offres_expirees=offres_with_files,
|
||||
@ -574,7 +574,7 @@ def edit_entreprise(entreprise_id):
|
||||
form.pays.data = entreprise.pays
|
||||
form.association.data = entreprise.association
|
||||
return render_template(
|
||||
"entreprises/form_modification_entreprise.html",
|
||||
"entreprises/form_modification_entreprise.j2",
|
||||
title="Modification entreprise",
|
||||
form=form,
|
||||
)
|
||||
@ -610,7 +610,7 @@ def fiche_entreprise_desactiver(entreprise_id):
|
||||
url_for("entreprises.fiche_entreprise", entreprise_id=entreprise.id)
|
||||
)
|
||||
return render_template(
|
||||
"entreprises/form_confirmation.html",
|
||||
"entreprises/form_confirmation.j2",
|
||||
title="Désactiver entreprise",
|
||||
form=form,
|
||||
info_message="Cliquez sur le bouton Modifier pour confirmer la désactivation",
|
||||
@ -646,7 +646,7 @@ def fiche_entreprise_activer(entreprise_id):
|
||||
url_for("entreprises.fiche_entreprise", entreprise_id=entreprise.id)
|
||||
)
|
||||
return render_template(
|
||||
"entreprises/form_confirmation.html",
|
||||
"entreprises/form_confirmation.j2",
|
||||
title="Activer entreprise",
|
||||
form=form,
|
||||
info_message="Cliquez sur le bouton Modifier pour confirmer l'activaction",
|
||||
@ -692,7 +692,7 @@ def add_taxe_apprentissage(entreprise_id):
|
||||
url_for("entreprises.fiche_entreprise", entreprise_id=entreprise.id)
|
||||
)
|
||||
return render_template(
|
||||
"entreprises/form.html",
|
||||
"entreprises/form.j2",
|
||||
title="Ajout taxe apprentissage",
|
||||
form=form,
|
||||
)
|
||||
@ -735,7 +735,7 @@ def edit_taxe_apprentissage(entreprise_id, taxe_id):
|
||||
form.montant.data = taxe.montant
|
||||
form.notes.data = taxe.notes
|
||||
return render_template(
|
||||
"entreprises/form.html",
|
||||
"entreprises/form.j2",
|
||||
title="Modification taxe apprentissage",
|
||||
form=form,
|
||||
)
|
||||
@ -775,7 +775,7 @@ def delete_taxe_apprentissage(entreprise_id, taxe_id):
|
||||
url_for("entreprises.fiche_entreprise", entreprise_id=taxe.entreprise_id)
|
||||
)
|
||||
return render_template(
|
||||
"entreprises/form_confirmation.html",
|
||||
"entreprises/form_confirmation.j2",
|
||||
title="Supprimer taxe apprentissage",
|
||||
form=form,
|
||||
info_message="Cliquez sur le bouton Supprimer pour confirmer votre supression",
|
||||
@ -845,7 +845,7 @@ def add_offre(entreprise_id):
|
||||
url_for("entreprises.fiche_entreprise", entreprise_id=entreprise.id)
|
||||
)
|
||||
return render_template(
|
||||
"entreprises/form.html",
|
||||
"entreprises/form.j2",
|
||||
title="Ajout offre",
|
||||
form=form,
|
||||
)
|
||||
@ -921,7 +921,7 @@ def edit_offre(entreprise_id, offre_id):
|
||||
form.expiration_date.data = offre.expiration_date
|
||||
form.depts.data = offre_depts_list
|
||||
return render_template(
|
||||
"entreprises/form.html",
|
||||
"entreprises/form.j2",
|
||||
title="Modification offre",
|
||||
form=form,
|
||||
)
|
||||
@ -971,7 +971,7 @@ def delete_offre(entreprise_id, offre_id):
|
||||
url_for("entreprises.fiche_entreprise", entreprise_id=offre.entreprise_id)
|
||||
)
|
||||
return render_template(
|
||||
"entreprises/form_confirmation.html",
|
||||
"entreprises/form_confirmation.j2",
|
||||
title="Supression offre",
|
||||
form=form,
|
||||
info_message="Cliquez sur le bouton Supprimer pour confirmer votre supression",
|
||||
@ -1047,7 +1047,7 @@ def add_site(entreprise_id):
|
||||
url_for("entreprises.fiche_entreprise", entreprise_id=entreprise.id)
|
||||
)
|
||||
return render_template(
|
||||
"entreprises/form.html",
|
||||
"entreprises/form.j2",
|
||||
title="Ajout site",
|
||||
form=form,
|
||||
)
|
||||
@ -1098,7 +1098,7 @@ def edit_site(entreprise_id, site_id):
|
||||
form.ville.data = site.ville
|
||||
form.pays.data = site.pays
|
||||
return render_template(
|
||||
"entreprises/form.html",
|
||||
"entreprises/form.j2",
|
||||
title="Modification site",
|
||||
form=form,
|
||||
)
|
||||
@ -1154,7 +1154,7 @@ def add_correspondant(entreprise_id, site_id):
|
||||
url_for("entreprises.fiche_entreprise", entreprise_id=site.entreprise_id)
|
||||
)
|
||||
return render_template(
|
||||
"entreprises/form_ajout_correspondants.html",
|
||||
"entreprises/form_ajout_correspondants.j2",
|
||||
title="Ajout correspondant",
|
||||
form=form,
|
||||
)
|
||||
@ -1234,7 +1234,7 @@ def edit_correspondant(entreprise_id, site_id, correspondant_id):
|
||||
form.origine.data = correspondant.origine
|
||||
form.notes.data = correspondant.notes
|
||||
return render_template(
|
||||
"entreprises/form.html",
|
||||
"entreprises/form.j2",
|
||||
title="Modification correspondant",
|
||||
form=form,
|
||||
)
|
||||
@ -1290,7 +1290,7 @@ def delete_correspondant(entreprise_id, site_id, correspondant_id):
|
||||
)
|
||||
)
|
||||
return render_template(
|
||||
"entreprises/form_confirmation.html",
|
||||
"entreprises/form_confirmation.j2",
|
||||
title="Supression correspondant",
|
||||
form=form,
|
||||
info_message="Cliquez sur le bouton Supprimer pour confirmer votre supression",
|
||||
@ -1308,7 +1308,7 @@ def contacts(entreprise_id):
|
||||
).first_or_404(description=f"entreprise {entreprise_id} inconnue")
|
||||
contacts = EntrepriseContact.query.filter_by(entreprise=entreprise.id).all()
|
||||
return render_template(
|
||||
"entreprises/contacts.html",
|
||||
"entreprises/contacts.j2",
|
||||
title="Liste des contacts",
|
||||
contacts=contacts,
|
||||
entreprise=entreprise,
|
||||
@ -1365,7 +1365,7 @@ def add_contact(entreprise_id):
|
||||
db.session.commit()
|
||||
return redirect(url_for("entreprises.contacts", entreprise_id=entreprise.id))
|
||||
return render_template(
|
||||
"entreprises/form.html",
|
||||
"entreprises/form.j2",
|
||||
title="Ajout contact",
|
||||
form=form,
|
||||
)
|
||||
@ -1421,7 +1421,7 @@ def edit_contact(entreprise_id, contact_id):
|
||||
)
|
||||
form.notes.data = contact.notes
|
||||
return render_template(
|
||||
"entreprises/form.html",
|
||||
"entreprises/form.j2",
|
||||
title="Modification contact",
|
||||
form=form,
|
||||
)
|
||||
@ -1459,7 +1459,7 @@ def delete_contact(entreprise_id, contact_id):
|
||||
url_for("entreprises.contacts", entreprise_id=contact.entreprise)
|
||||
)
|
||||
return render_template(
|
||||
"entreprises/form_confirmation.html",
|
||||
"entreprises/form_confirmation.j2",
|
||||
title="Supression contact",
|
||||
form=form,
|
||||
info_message="Cliquez sur le bouton Supprimer pour confirmer votre supression",
|
||||
@ -1525,7 +1525,7 @@ def add_stage_apprentissage(entreprise_id):
|
||||
url_for("entreprises.fiche_entreprise", entreprise_id=entreprise.id)
|
||||
)
|
||||
return render_template(
|
||||
"entreprises/form_ajout_stage_apprentissage.html",
|
||||
"entreprises/form_ajout_stage_apprentissage.j2",
|
||||
title="Ajout stage / apprentissage",
|
||||
form=form,
|
||||
)
|
||||
@ -1599,7 +1599,7 @@ def edit_stage_apprentissage(entreprise_id, stage_apprentissage_id):
|
||||
form.date_fin.data = stage_apprentissage.date_fin
|
||||
form.notes.data = stage_apprentissage.notes
|
||||
return render_template(
|
||||
"entreprises/form_ajout_stage_apprentissage.html",
|
||||
"entreprises/form_ajout_stage_apprentissage.j2",
|
||||
title="Modification stage / apprentissage",
|
||||
form=form,
|
||||
)
|
||||
@ -1640,7 +1640,7 @@ def delete_stage_apprentissage(entreprise_id, stage_apprentissage_id):
|
||||
)
|
||||
)
|
||||
return render_template(
|
||||
"entreprises/form_confirmation.html",
|
||||
"entreprises/form_confirmation.j2",
|
||||
title="Supression stage/apprentissage",
|
||||
form=form,
|
||||
info_message="Cliquez sur le bouton Supprimer pour confirmer votre supression",
|
||||
@ -1690,7 +1690,7 @@ def envoyer_offre(entreprise_id, offre_id):
|
||||
url_for("entreprises.fiche_entreprise", entreprise_id=offre.entreprise_id)
|
||||
)
|
||||
return render_template(
|
||||
"entreprises/form_envoi_offre.html",
|
||||
"entreprises/form_envoi_offre.j2",
|
||||
title="Envoyer une offre",
|
||||
form=form,
|
||||
)
|
||||
@ -1816,7 +1816,7 @@ def import_donnees():
|
||||
db.session.rollback()
|
||||
flash("Une erreur est survenue veuillez réessayer.")
|
||||
return render_template(
|
||||
"entreprises/import_donnees.html",
|
||||
"entreprises/import_donnees.j2",
|
||||
title="Importation données",
|
||||
form=form,
|
||||
)
|
||||
@ -1845,7 +1845,7 @@ def import_donnees():
|
||||
db.session.commit()
|
||||
flash(f"Importation réussie")
|
||||
return render_template(
|
||||
"entreprises/import_donnees.html",
|
||||
"entreprises/import_donnees.j2",
|
||||
title="Importation données",
|
||||
form=form,
|
||||
entreprises_import=entreprises_import,
|
||||
@ -1853,7 +1853,7 @@ def import_donnees():
|
||||
correspondants_import=correspondants,
|
||||
)
|
||||
return render_template(
|
||||
"entreprises/import_donnees.html", title="Importation données", form=form
|
||||
"entreprises/import_donnees.j2", title="Importation données", form=form
|
||||
)
|
||||
|
||||
|
||||
@ -1927,7 +1927,7 @@ def add_offre_file(entreprise_id, offre_id):
|
||||
url_for("entreprises.fiche_entreprise", entreprise_id=offre.entreprise_id)
|
||||
)
|
||||
return render_template(
|
||||
"entreprises/form.html",
|
||||
"entreprises/form.j2",
|
||||
title="Ajout fichier à une offre",
|
||||
form=form,
|
||||
)
|
||||
@ -1969,7 +1969,7 @@ def delete_offre_file(entreprise_id, offre_id, filedir):
|
||||
)
|
||||
)
|
||||
return render_template(
|
||||
"entreprises/form_confirmation.html",
|
||||
"entreprises/form_confirmation.j2",
|
||||
title="Suppression fichier d'une offre",
|
||||
form=form,
|
||||
info_message="Cliquez sur le bouton Supprimer pour confirmer votre supression",
|
||||
@ -1981,4 +1981,4 @@ def not_found_error_handler(e):
|
||||
"""
|
||||
Renvoie une page d'erreur pour l'erreur 404
|
||||
"""
|
||||
return render_template("entreprises/error.html", title="Erreur", e=e)
|
||||
return render_template("entreprises/error.j2", title="Erreur", e=e)
|
||||
|
@ -171,7 +171,7 @@ class AddLogoForm(FlaskForm):
|
||||
|
||||
|
||||
class LogoForm(FlaskForm):
|
||||
"""Embed both presentation of a logo (cf. template file configuration.html)
|
||||
"""Embed both presentation of a logo (cf. template file configuration.j2)
|
||||
and all its data and UI action (change, delete)"""
|
||||
|
||||
dept_key = HiddenField()
|
||||
@ -434,7 +434,7 @@ def config_logos():
|
||||
scu.flash_errors(form)
|
||||
|
||||
return render_template(
|
||||
"config_logos.html",
|
||||
"config_logos.j2",
|
||||
scodoc_dept=None,
|
||||
title="Configuration ScoDoc",
|
||||
form=form,
|
||||
|
@ -133,7 +133,7 @@ def configuration():
|
||||
return redirect(url_for("scodoc.index"))
|
||||
|
||||
return render_template(
|
||||
"configuration.html",
|
||||
"configuration.j2",
|
||||
form_bonus=form_bonus,
|
||||
form_scodoc=form_scodoc,
|
||||
scu=scu,
|
||||
|
@ -1,13 +1,19 @@
|
||||
# -*- coding: UTF-8 -*
|
||||
"""Gestion de l'assiduité (assiduités + justificatifs)
|
||||
"""
|
||||
from app import db
|
||||
from app.models import ModuleImpl, ModuleImplInscription
|
||||
from app.models.etudiants import Identite
|
||||
from app.scodoc.sco_utils import EtatAssiduite, localize_datetime, is_period_overlapping
|
||||
from app.scodoc.sco_exceptions import ScoValueError
|
||||
from datetime import datetime
|
||||
|
||||
from app import db
|
||||
from app.models import ModuleImpl
|
||||
from app.models.etudiants import Identite
|
||||
from app.scodoc.sco_exceptions import ScoValueError
|
||||
from app.scodoc.sco_utils import (
|
||||
EtatAssiduite,
|
||||
EtatJustificatif,
|
||||
is_period_overlapping,
|
||||
localize_datetime,
|
||||
)
|
||||
|
||||
|
||||
class Assiduite(db.Model):
|
||||
"""
|
||||
@ -43,6 +49,8 @@ class Assiduite(db.Model):
|
||||
|
||||
desc = db.Column(db.Text)
|
||||
|
||||
entry_date = db.Column(db.DateTime(timezone=True), server_default=db.func.now())
|
||||
|
||||
def to_dict(self) -> dict:
|
||||
data = {
|
||||
"assiduite_id": self.assiduite_id,
|
||||
@ -52,6 +60,7 @@ class Assiduite(db.Model):
|
||||
"date_fin": self.date_fin,
|
||||
"etat": self.etat,
|
||||
"desc": self.desc,
|
||||
"entry_date": self.entry_date,
|
||||
}
|
||||
return data
|
||||
|
||||
@ -119,7 +128,8 @@ class Justificatif(db.Model):
|
||||
|
||||
__tablename__ = "justificatifs"
|
||||
|
||||
justif_id = db.Column(db.Integer, primary_key=True)
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
justif_id = db.synonym("id")
|
||||
|
||||
date_debut = db.Column(
|
||||
db.DateTime(timezone=True), server_default=db.func.now(), nullable=False
|
||||
@ -136,26 +146,63 @@ class Justificatif(db.Model):
|
||||
)
|
||||
etat = db.Column(
|
||||
db.Integer,
|
||||
nullable=False,
|
||||
)
|
||||
|
||||
entry_date = db.Column(db.DateTime(timezone=True), server_default=db.func.now())
|
||||
|
||||
raison = db.Column(db.Text())
|
||||
|
||||
"""
|
||||
Les justificatifs sont enregistrés dans
|
||||
<archivedir>/justificatifs/<dept_id>/<etudid>/<nom_fichier.extension>
|
||||
|
||||
d'après sco_archives.py#JustificatifArchiver
|
||||
"""
|
||||
# Archive_id -> sco_archives_justificatifs.py
|
||||
fichier = db.Column(db.Text())
|
||||
|
||||
def to_dict(self) -> dict:
|
||||
data = {
|
||||
"justif_id": self.assiduite_id,
|
||||
"justif_id": self.justif_id,
|
||||
"etudid": self.etudid,
|
||||
"date_debut": self.date_debut,
|
||||
"date_fin": self.date_fin,
|
||||
"etat": self.etat,
|
||||
"raison": self.raison,
|
||||
"fichier": self.fichier,
|
||||
"entry_date": self.entry_date,
|
||||
}
|
||||
return data
|
||||
|
||||
@classmethod
|
||||
def create_justificatif(
|
||||
cls,
|
||||
etud: Identite,
|
||||
date_debut: datetime,
|
||||
date_fin: datetime,
|
||||
etat: EtatJustificatif,
|
||||
raison: str = None,
|
||||
) -> object or int:
|
||||
"""Créer un nouveau justificatif pour l'étudiant"""
|
||||
# Vérification de non duplication des périodes
|
||||
justificatifs: list[Justificatif] = etud.justificatifs.all()
|
||||
|
||||
date_debut = localize_datetime(date_debut)
|
||||
date_fin = localize_datetime(date_fin)
|
||||
justificatifs = [
|
||||
just
|
||||
for just in justificatifs
|
||||
if is_period_overlapping(
|
||||
(date_debut, date_fin),
|
||||
(just.date_debut, just.date_fin),
|
||||
)
|
||||
]
|
||||
if len(justificatifs) != 0:
|
||||
raise ScoValueError(
|
||||
"Duplication des justificatifs (la période rentrée rentre en conflit avec un justificatif enregistré)"
|
||||
)
|
||||
|
||||
nouv_assiduite = Justificatif(
|
||||
date_debut=date_debut,
|
||||
date_fin=date_fin,
|
||||
etat=etat,
|
||||
etudiant=etud,
|
||||
raison=raison,
|
||||
)
|
||||
|
||||
return nouv_assiduite
|
||||
|
@ -36,6 +36,7 @@ class Formation(db.Model):
|
||||
titre = db.Column(db.Text(), nullable=False)
|
||||
titre_officiel = db.Column(db.Text(), nullable=False)
|
||||
version = db.Column(db.Integer, default=1, server_default="1")
|
||||
commentaire = db.Column(db.Text())
|
||||
formation_code = db.Column(
|
||||
db.String(SHORT_STR_LEN),
|
||||
server_default=db.text("notes_newid_fcod()"),
|
||||
@ -63,7 +64,7 @@ class Formation(db.Model):
|
||||
return f"""Formation {self.titre} ({self.acronyme}) [version {self.version}] code {self.formation_code}"""
|
||||
|
||||
def to_dict(self, with_refcomp_attrs=False):
|
||||
""" "as a dict.
|
||||
"""As a dict.
|
||||
Si with_refcomp_attrs, ajoute attributs permettant de retrouver le ref. de comp.
|
||||
"""
|
||||
e = dict(self.__dict__)
|
||||
|
@ -256,23 +256,12 @@ class UniteEns(db.Model):
|
||||
|
||||
class DispenseUE(db.Model):
|
||||
"""Dispense d'UE
|
||||
Utilisé en APC (BUT) pour indiquer les étudiants redoublants avec une UE capitalisée
|
||||
Utilisé en PCC (BUT) pour indiquer les étudiants redoublants avec une UE capitalisée
|
||||
qu'ils ne refont pas.
|
||||
La dispense d'UE n'est PAS une validation:
|
||||
- elle n'est pas affectée par les décisions de jury (pas effacée)
|
||||
- elle est associée à un formsemestre
|
||||
- elle ne permet pas la délivrance d'ECTS ou du diplôme.
|
||||
|
||||
On utilise cette dispense et non une "inscription" par souci d'efficacité:
|
||||
en général, la grande majorité des étudiants suivront toutes les UEs de leur parcours,
|
||||
la dispense étant une exception.
|
||||
"""
|
||||
|
||||
__table_args__ = (db.UniqueConstraint("formsemestre_id", "ue_id", "etudid"),)
|
||||
__table_args__ = (db.UniqueConstraint("ue_id", "etudid"),)
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
formsemestre_id = formsemestre_id = db.Column(
|
||||
db.Integer, db.ForeignKey("notes_formsemestre.id"), index=True, nullable=True
|
||||
)
|
||||
ue_id = db.Column(
|
||||
db.Integer,
|
||||
db.ForeignKey(UniteEns.id, ondelete="CASCADE"),
|
||||
@ -291,25 +280,3 @@ class DispenseUE(db.Model):
|
||||
def __repr__(self) -> str:
|
||||
return f"""<{self.__class__.__name__} {self.id} etud={
|
||||
repr(self.etud)} ue={repr(self.ue)}>"""
|
||||
|
||||
@classmethod
|
||||
def load_formsemestre_dispense_ues_set(
|
||||
cls, formsemestre: "FormSemestre", etudids: pd.Index, ues: list[UniteEns]
|
||||
) -> set[tuple[int, int]]:
|
||||
"""Construit l'ensemble des
|
||||
etudids = modimpl_inscr_df.index, # les etudids
|
||||
ue_ids : modimpl_coefs_df.index, # les UE du formsemestre sans les UE bonus sport
|
||||
|
||||
Résultat: set de (etudid, ue_id).
|
||||
"""
|
||||
# Prend toutes les dispenses obtenues par des étudiants de ce formsemestre,
|
||||
# puis filtre sur inscrits et ues
|
||||
ue_ids = {ue.id for ue in ues}
|
||||
dispense_ues = {
|
||||
(dispense_ue.etudid, dispense_ue.ue_id)
|
||||
for dispense_ue in DispenseUE.query.filter_by(
|
||||
formsemestre_id=formsemestre.id
|
||||
)
|
||||
if dispense_ue.etudid in etudids and dispense_ue.ue_id in ue_ids
|
||||
}
|
||||
return dispense_ues
|
||||
|
@ -274,7 +274,7 @@ def sco_header(
|
||||
H.append("""<div id="gtrcontent">""")
|
||||
# En attendant le replacement complet de cette fonction,
|
||||
# inclusion ici des messages flask
|
||||
H.append(render_template("flashed_messages.html"))
|
||||
H.append(render_template("flashed_messages.j2"))
|
||||
#
|
||||
# Barre menu semestre:
|
||||
H.append(formsemestre_page_title(formsemestre_id))
|
||||
|
@ -166,6 +166,6 @@ def sidebar(etudid: int = None):
|
||||
def sidebar_dept():
|
||||
"""Partie supérieure de la marge de gauche"""
|
||||
return render_template(
|
||||
"sidebar_dept.html",
|
||||
"sidebar_dept.j2",
|
||||
prefs=sco_preferences.SemPreferences(),
|
||||
)
|
||||
|
@ -43,6 +43,7 @@ Pour chaque étudiant commun:
|
||||
comparer les résultats
|
||||
|
||||
"""
|
||||
from flask import g, url_for
|
||||
|
||||
from app import log
|
||||
from app.scodoc import sco_apogee_csv
|
||||
@ -72,11 +73,11 @@ def apo_compare_csv_form():
|
||||
"""
|
||||
<div class="apo_compare_csv_form_but">
|
||||
Fichier Apogée A:
|
||||
<input type="file" size="30" name="A_file"/>
|
||||
<input type="file" size="30" name="file_a"/>
|
||||
</div>
|
||||
<div class="apo_compare_csv_form_but">
|
||||
Fichier Apogée B:
|
||||
<input type="file" size="30" name="B_file"/>
|
||||
<input type="file" size="30" name="file_b"/>
|
||||
</div>
|
||||
<input type="checkbox" name="autodetect" checked/>autodétecter encodage</input>
|
||||
<div class="apo_compare_csv_form_submit">
|
||||
@ -88,17 +89,36 @@ def apo_compare_csv_form():
|
||||
return "\n".join(H)
|
||||
|
||||
|
||||
def apo_compare_csv(A_file, B_file, autodetect=True):
|
||||
def apo_compare_csv(file_a, file_b, autodetect=True):
|
||||
"""Page comparing 2 Apogee CSV files"""
|
||||
A = _load_apo_data(A_file, autodetect=autodetect)
|
||||
B = _load_apo_data(B_file, autodetect=autodetect)
|
||||
|
||||
try:
|
||||
apo_data_a = _load_apo_data(file_a, autodetect=autodetect)
|
||||
apo_data_b = _load_apo_data(file_b, autodetect=autodetect)
|
||||
except (UnicodeDecodeError, UnicodeEncodeError) as exc:
|
||||
dest_url = url_for("notes.semset_page", scodoc_dept=g.scodoc_dept)
|
||||
if autodetect:
|
||||
raise ScoValueError(
|
||||
"""
|
||||
Erreur: l'encodage de l'un des fichiers est mal détecté.
|
||||
Essayez sans auto-détection, ou vérifiez le codage et le contenu
|
||||
des fichiers.
|
||||
""",
|
||||
dest_url=dest_url,
|
||||
) from exc
|
||||
else:
|
||||
raise ScoValueError(
|
||||
f"""
|
||||
Erreur: l'encodage de l'un des fichiers est incorrect.
|
||||
Vérifiez qu'il est bien en {sco_apogee_csv.APO_INPUT_ENCODING}
|
||||
""",
|
||||
dest_url=dest_url,
|
||||
) from exc
|
||||
H = [
|
||||
html_sco_header.sco_header(page_title="Comparaison de fichiers Apogée"),
|
||||
"<h2>Comparaison de fichiers Apogée</h2>",
|
||||
_help_txt,
|
||||
'<div class="apo_compare_csv">',
|
||||
_apo_compare_csv(A, B),
|
||||
_apo_compare_csv(apo_data_a, apo_data_b),
|
||||
"</div>",
|
||||
"""<p><a href="apo_compare_csv_form" class="stdlink">Autre comparaison</a></p>""",
|
||||
html_sco_header.sco_footer(),
|
||||
@ -112,9 +132,9 @@ def _load_apo_data(csvfile, autodetect=True):
|
||||
if autodetect:
|
||||
data_b, message = sco_apogee_csv.fix_data_encoding(data_b)
|
||||
if message:
|
||||
log("apo_compare_csv: %s" % message)
|
||||
log(f"apo_compare_csv: {message}")
|
||||
if not data_b:
|
||||
raise ScoValueError("apo_compare_csv: no data")
|
||||
raise ScoValueError("fichier vide ? (apo_compare_csv: no data)")
|
||||
data = data_b.decode(sco_apogee_csv.APO_INPUT_ENCODING)
|
||||
apo_data = sco_apogee_csv.ApoData(data, orig_filename=csvfile.filename)
|
||||
return apo_data
|
||||
|
@ -155,28 +155,25 @@ def fix_data_encoding(
|
||||
text: bytes,
|
||||
default_source_encoding=APO_INPUT_ENCODING,
|
||||
dest_encoding=APO_INPUT_ENCODING,
|
||||
) -> bytes:
|
||||
) -> tuple[bytes, str]:
|
||||
"""Try to ensure that text is using dest_encoding
|
||||
returns converted text, and a message describing the conversion.
|
||||
|
||||
Raises UnicodeEncodeError en cas de problème, en général liée à
|
||||
une auto-détection errornée.
|
||||
"""
|
||||
message = ""
|
||||
detected_encoding = guess_data_encoding(text)
|
||||
if not detected_encoding:
|
||||
if default_source_encoding != dest_encoding:
|
||||
message = "converting from %s to %s" % (
|
||||
default_source_encoding,
|
||||
dest_encoding,
|
||||
)
|
||||
text = text.decode(default_source_encoding).encode(
|
||||
dest_encoding
|
||||
) # XXX #py3 #sco8 à tester
|
||||
message = f"converting from {default_source_encoding} to {dest_encoding}"
|
||||
text = text.decode(default_source_encoding).encode(dest_encoding)
|
||||
else:
|
||||
if detected_encoding != dest_encoding:
|
||||
message = "converting from detected %s to %s" % (
|
||||
detected_encoding,
|
||||
dest_encoding,
|
||||
message = (
|
||||
f"converting from detected {default_source_encoding} to {dest_encoding}"
|
||||
)
|
||||
text = text.decode(detected_encoding).encode(dest_encoding) # XXX
|
||||
text = text.decode(detected_encoding).encode(dest_encoding)
|
||||
return text, message
|
||||
|
||||
|
||||
|
@ -373,7 +373,7 @@ def etudarchive_import_files(
|
||||
filename_title="fichier_a_charger",
|
||||
)
|
||||
return render_template(
|
||||
"scolar/photos_import_files.html",
|
||||
"scolar/photos_import_files.j2",
|
||||
page_title="Téléchargement de fichiers associés aux étudiants",
|
||||
ignored_zipfiles=ignored_zipfiles,
|
||||
unmatched_files=unmatched_files,
|
||||
|
112
app/scodoc/sco_archives_justificatifs.py
Normal file
112
app/scodoc/sco_archives_justificatifs.py
Normal file
@ -0,0 +1,112 @@
|
||||
from app.scodoc.sco_archives import BaseArchiver
|
||||
from app.scodoc.sco_exceptions import ScoValueError
|
||||
from app.models import Identite, Departement
|
||||
from flask import g
|
||||
import os
|
||||
|
||||
|
||||
class JustificatifArchiver(BaseArchiver):
|
||||
"""
|
||||
|
||||
TOTALK:
|
||||
- oid -> etudid
|
||||
- archive_id -> date de création de l'archive (une archive par dépot de document)
|
||||
|
||||
justificatif
|
||||
└── <dept_id>
|
||||
└── <etudid/oid>
|
||||
└── <archive_id>
|
||||
├── [_description.txt]
|
||||
└── [<filename.ext>]
|
||||
|
||||
|
||||
TODO:
|
||||
- Faire fonction suppression fichier unique dans archive
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
BaseArchiver.__init__(self, archive_type="justificatifs")
|
||||
|
||||
def save_justificatif(
|
||||
self,
|
||||
etudid: int,
|
||||
filename: str,
|
||||
data: bytes or str,
|
||||
archive_name: str = None,
|
||||
description: str = "",
|
||||
) -> str:
|
||||
"""
|
||||
Ajoute un fichier dans une archive "justificatif" pour l'etudid donné
|
||||
Retourne l'archive_name utilisé
|
||||
"""
|
||||
self._set_dept(etudid)
|
||||
if archive_name is None:
|
||||
archive_id: str = self.create_obj_archive(
|
||||
oid=etudid, description=description
|
||||
)
|
||||
else:
|
||||
archive_id: str = self.get_id_from_name(etudid, archive_name)
|
||||
|
||||
self.store(archive_id, filename, data)
|
||||
|
||||
return self.get_archive_name(archive_id)
|
||||
|
||||
def delete_justificatif(self, etudid: int, archive_name: str, filename: str = None):
|
||||
"""
|
||||
Supprime une archive ou un fichier particulier de l'archivage de l'étudiant donné
|
||||
"""
|
||||
self._set_dept(etudid)
|
||||
if str(etudid) not in self.list_oids():
|
||||
raise ValueError(f"Aucune archive pour etudid[{etudid}]")
|
||||
|
||||
archive_id = self.get_id_from_name(etudid, archive_name)
|
||||
|
||||
if filename is not None:
|
||||
if filename not in self.list_archive(archive_id):
|
||||
raise ValueError(
|
||||
f"filename {filename} inconnu dans l'archive archive_id[{archive_id}] -> etudid[{etudid}]"
|
||||
)
|
||||
|
||||
path: str = os.path.join(self.get_obj_dir(etudid), archive_id, filename)
|
||||
|
||||
if os.path.isfile(path):
|
||||
os.remove(path)
|
||||
|
||||
else:
|
||||
self.delete_archive(
|
||||
os.path.join(
|
||||
self.get_obj_dir(etudid),
|
||||
archive_id,
|
||||
)
|
||||
)
|
||||
|
||||
def list_justificatifs(self, archive_name: str, etudid: int) -> list[str]:
|
||||
"""
|
||||
Retourne la liste des noms de fichiers dans l'archive donnée
|
||||
"""
|
||||
self._set_dept(etudid)
|
||||
filenames: list[str] = []
|
||||
archive_id = self.get_id_from_name(etudid, archive_name)
|
||||
|
||||
filenames = self.list_archive(archive_id)
|
||||
return filenames
|
||||
|
||||
def get_justificatif_file(self, archive_name: str, etudid: int, filename: str):
|
||||
"""
|
||||
Retourne une réponse de téléchargement de fichier si le fichier existe
|
||||
"""
|
||||
self._set_dept(etudid)
|
||||
archive_id: str = self.get_id_from_name(etudid, archive_name)
|
||||
if filename in self.list_archive(archive_id):
|
||||
return self.get_archived_file(etudid, archive_name, filename)
|
||||
raise ScoValueError(
|
||||
f"Fichier {filename} introuvable dans l'archive {archive_name}"
|
||||
)
|
||||
|
||||
def _set_dept(self, etudid: int):
|
||||
if g.scodoc_dept is None or g.scodoc_dept_id is None:
|
||||
etud: Identite = Identite.query.filter_by(id=etudid).first()
|
||||
dept: Departement = Departement.query.filter_by(id=etud.dept_id).first()
|
||||
|
||||
g.scodoc_dept = dept.acronym
|
||||
g.scodoc_dept_id = dept.id
|
@ -1,27 +1,33 @@
|
||||
from app.models.etudiants import Identite
|
||||
from app.models.formsemestre import FormSemestre
|
||||
from app.models.assiduites import Assiduite
|
||||
from datetime import date, datetime, time, timedelta
|
||||
|
||||
import app.scodoc.sco_utils as scu
|
||||
from datetime import datetime, date, time, timedelta
|
||||
from app.models.assiduites import Assiduite, Justificatif
|
||||
from app.models.etudiants import Identite
|
||||
from app.models.formsemestre import FormSemestre, FormSemestreInscription
|
||||
|
||||
# TOTALK: Réfléchir sur le fractionnement d'une assiduite prolongée
|
||||
|
||||
|
||||
def get_assiduites_stats(
|
||||
assiduites: Assiduite, metric: str = "all", filter: dict[str, object] = {}
|
||||
assiduites: Assiduite, metric: str = "all", filtered: dict[str, object] = None
|
||||
) -> Assiduite:
|
||||
if filter != {}:
|
||||
for key in filter:
|
||||
|
||||
if filtered is not None:
|
||||
for key in filtered:
|
||||
if key == "etat":
|
||||
assiduites = filter_by_etat(assiduites, filter[key])
|
||||
assiduites = filter_assiduites_by_etat(assiduites, filtered[key])
|
||||
elif key == "date_fin":
|
||||
assiduites = filter_by_date(assiduites, filter[key], sup=False)
|
||||
assiduites = filter_assiduites_by_date(
|
||||
assiduites, filtered[key], sup=False
|
||||
)
|
||||
elif key == "date_debut":
|
||||
assiduites = filter_by_date(assiduites, filter[key], sup=True)
|
||||
assiduites = filter_assiduites_by_date(
|
||||
assiduites, filtered[key], sup=True
|
||||
)
|
||||
elif key == "moduleimpl_id":
|
||||
assiduites = filter_by_module_impl(assiduites, filter[key])
|
||||
assiduites = filter_by_module_impl(assiduites, filtered[key])
|
||||
elif key == "formsemestre":
|
||||
assiduites = filter_by_formsemstre(assiduites, filter[key])
|
||||
assiduites = filter_by_formsemestre(assiduites, filtered[key])
|
||||
|
||||
count: dict = get_count(assiduites)
|
||||
|
||||
@ -29,10 +35,10 @@ def get_assiduites_stats(
|
||||
|
||||
output: dict = {}
|
||||
|
||||
for key in count:
|
||||
for key, val in count.items():
|
||||
if key in metrics:
|
||||
output[key] = count[key]
|
||||
return output if output != {} else count
|
||||
output[key] = val
|
||||
return output if output else count
|
||||
|
||||
|
||||
def get_count(assiduites: Assiduite) -> dict[str, int or float]:
|
||||
@ -48,9 +54,11 @@ def get_count(assiduites: Assiduite) -> dict[str, int or float]:
|
||||
current_day: date = None
|
||||
current_time: str = None
|
||||
|
||||
MIDNIGHT: time = time(hour=0)
|
||||
NOON: time = time(hour=12)
|
||||
time_check = lambda d: (MIDNIGHT <= d.time() <= NOON)
|
||||
midnight: time = time(hour=0)
|
||||
noon: time = time(hour=12)
|
||||
|
||||
def time_check(dtime):
|
||||
return midnight <= dtime.time() <= noon
|
||||
|
||||
for ass in all_assiduites:
|
||||
delta: timedelta = ass.date_fin - ass.date_debut
|
||||
@ -72,7 +80,7 @@ def get_count(assiduites: Assiduite) -> dict[str, int or float]:
|
||||
return output
|
||||
|
||||
|
||||
def filter_by_etat(assiduites: Assiduite, etat: str) -> Assiduite:
|
||||
def filter_assiduites_by_etat(assiduites: Assiduite, etat: str) -> Assiduite:
|
||||
"""
|
||||
Filtrage d'une collection d'assiduites en fonction de leur état
|
||||
"""
|
||||
@ -81,8 +89,8 @@ def filter_by_etat(assiduites: Assiduite, etat: str) -> Assiduite:
|
||||
return assiduites.filter(Assiduite.etat.in_(etats))
|
||||
|
||||
|
||||
def filter_by_date(
|
||||
assiduites: Assiduite, date: datetime, sup: bool = True
|
||||
def filter_assiduites_by_date(
|
||||
assiduites: Assiduite, date_: datetime, sup: bool = True
|
||||
) -> Assiduite:
|
||||
"""
|
||||
Filtrage d'une collection d'assiduites en fonction d'une date
|
||||
@ -91,15 +99,47 @@ def filter_by_date(
|
||||
Sup == False -> les assiduites doivent finir avant 'date'
|
||||
"""
|
||||
|
||||
if date.tzinfo is None:
|
||||
if date_.tzinfo is None:
|
||||
first_assiduite: Assiduite = assiduites.first()
|
||||
if first_assiduite is not None:
|
||||
date: datetime = date.replace(tzinfo=first_assiduite.date_debut.tzinfo)
|
||||
date_: datetime = date_.replace(tzinfo=first_assiduite.date_debut.tzinfo)
|
||||
|
||||
if sup:
|
||||
return assiduites.filter(Assiduite.date_debut >= date)
|
||||
else:
|
||||
return assiduites.filter(Assiduite.date_fin <= date)
|
||||
return assiduites.filter(Assiduite.date_debut >= date_)
|
||||
|
||||
return assiduites.filter(Assiduite.date_fin <= date_)
|
||||
|
||||
|
||||
def filter_justificatifs_by_etat(
|
||||
justificatifs: Justificatif, etat: str
|
||||
) -> Justificatif:
|
||||
"""
|
||||
Filtrage d'une collection de justificatifs en fonction de leur état
|
||||
"""
|
||||
etats: list[str] = list(etat.split(","))
|
||||
etats = [scu.ETATS_JUSTIFICATIF.get(e, -1) for e in etats]
|
||||
return justificatifs.filter(Justificatif.etat.in_(etats))
|
||||
|
||||
|
||||
def filter_justificatifs_by_date(
|
||||
justificatifs: Justificatif, date_: datetime, sup: bool = True
|
||||
) -> Assiduite:
|
||||
"""
|
||||
Filtrage d'une collection d'assiduites en fonction d'une date
|
||||
|
||||
Sup == True -> les assiduites doivent débuter après 'date'\n
|
||||
Sup == False -> les assiduites doivent finir avant 'date'
|
||||
"""
|
||||
|
||||
if date_.tzinfo is None:
|
||||
first_justificatif: Justificatif = justificatifs.first()
|
||||
if first_justificatif is not None:
|
||||
date_: datetime = date_.replace(tzinfo=first_justificatif.date_debut.tzinfo)
|
||||
|
||||
if sup:
|
||||
return justificatifs.filter(Justificatif.date_debut >= date_)
|
||||
|
||||
return justificatifs.filter(Justificatif.date_fin <= date_)
|
||||
|
||||
|
||||
def filter_by_module_impl(
|
||||
@ -111,18 +151,24 @@ def filter_by_module_impl(
|
||||
return assiduites.filter(Assiduite.moduleimpl_id == module_impl_id)
|
||||
|
||||
|
||||
def filter_by_formsemstre(assiduites: Assiduite, formsemestre: FormSemestre):
|
||||
def filter_by_formsemestre(assiduites_query: Assiduite, formsemestre: FormSemestre):
|
||||
"""
|
||||
Filtrage d'une collection d'assiduites en fonction d'un formsemestre
|
||||
"""
|
||||
|
||||
if formsemestre is None:
|
||||
return assiduites.filter(False)
|
||||
return assiduites_query.filter(False)
|
||||
|
||||
assiduites = assiduites.filter(
|
||||
Identite.query.filter_by(id=Assiduite.etudid).first()
|
||||
in formsemestre.etuds.all()
|
||||
assiduites_query = (
|
||||
assiduites_query.join(Identite, Assiduite.etudid == Identite.id)
|
||||
.join(
|
||||
FormSemestreInscription,
|
||||
Identite.id == FormSemestreInscription.etudid,
|
||||
)
|
||||
.filter(FormSemestreInscription.formsemestre_id == formsemestre.id)
|
||||
)
|
||||
|
||||
assiduites = assiduites.filter(Assiduite.date_debut >= formsemestre.date_debut)
|
||||
return assiduites.filter(Assiduite.date_fin <= formsemestre.date_fin)
|
||||
assiduites_query = assiduites_query.filter(
|
||||
Assiduite.date_debut >= formsemestre.date_debut
|
||||
)
|
||||
return assiduites_query.filter(Assiduite.date_fin <= formsemestre.date_fin)
|
||||
|
@ -926,7 +926,7 @@ def formsemestre_bulletinetud(
|
||||
_formsemestre_bulletinetud_header_html(etud, formsemestre, format, version),
|
||||
bulletin,
|
||||
render_template(
|
||||
"bul_foot.html",
|
||||
"bul_foot.j2",
|
||||
appreciations=None, # déjà affichées
|
||||
css_class="bul_classic_foot",
|
||||
etud=etud,
|
||||
@ -1259,7 +1259,7 @@ def _formsemestre_bulletinetud_header_html(
|
||||
cssstyles=["css/radar_bulletin.css"],
|
||||
),
|
||||
render_template(
|
||||
"bul_head.html",
|
||||
"bul_head.j2",
|
||||
etud=etud,
|
||||
format=format,
|
||||
formsemestre=formsemestre,
|
||||
|
@ -234,6 +234,16 @@ def formation_edit(formation_id=None, create=False):
|
||||
"explanation": "optionel: code utilisé pour échanger avec d'autres logiciels et identifiant la filière ou spécialité (exemple: ASUR). N'est utilisé que s'il n'y a pas de numéro de semestre.",
|
||||
},
|
||||
),
|
||||
(
|
||||
"commentaire",
|
||||
{
|
||||
"input_type": "textarea",
|
||||
"rows": 3,
|
||||
"cols": 77,
|
||||
"title": "Commentaire",
|
||||
"explanation": "commentaire libre.",
|
||||
},
|
||||
),
|
||||
),
|
||||
initvalues=initvalues,
|
||||
submitlabel=submitlabel,
|
||||
|
@ -385,7 +385,7 @@ def module_edit(
|
||||
),
|
||||
f"""<h2>{title}</h2>""",
|
||||
render_template(
|
||||
"scodoc/help/modules.html",
|
||||
"scodoc/help/modules.j2",
|
||||
is_apc=is_apc,
|
||||
semestre_id=semestre_id,
|
||||
formsemestres=FormSemestre.query.filter(
|
||||
@ -396,6 +396,7 @@ def module_edit(
|
||||
.all()
|
||||
if not create
|
||||
else None,
|
||||
create=create,
|
||||
),
|
||||
]
|
||||
if not unlocked:
|
||||
@ -655,7 +656,8 @@ def module_edit(
|
||||
(
|
||||
"numero",
|
||||
{
|
||||
"size": 2,
|
||||
"title": "Numéro",
|
||||
"size": 4,
|
||||
"explanation": "numéro (1, 2, 3, 4, ...) pour ordre d'affichage",
|
||||
"type": "int",
|
||||
"default": default_num,
|
||||
|
@ -591,19 +591,45 @@ def view_apo_csv_store(semset_id="", csvfile=None, data: bytes = "", autodetect=
|
||||
if not semset_id:
|
||||
raise ValueError("invalid null semset_id")
|
||||
semset = sco_semset.SemSet(semset_id=semset_id)
|
||||
if csvfile:
|
||||
data = csvfile.read() # bytes
|
||||
try:
|
||||
if csvfile:
|
||||
data = csvfile.read() # bytes
|
||||
if autodetect:
|
||||
# check encoding (although documentation states that users SHOULD upload LATIN1)
|
||||
|
||||
data, message = sco_apogee_csv.fix_data_encoding(data)
|
||||
if message:
|
||||
log(f"view_apo_csv_store: {message}")
|
||||
else:
|
||||
log("view_apo_csv_store: autodetection of encoding disabled by user")
|
||||
if not data:
|
||||
raise ScoValueError("view_apo_csv_store: no data")
|
||||
# data est du bytes, encodé en APO_INPUT_ENCODING
|
||||
data_str = data.decode(APO_INPUT_ENCODING)
|
||||
except (UnicodeDecodeError, UnicodeEncodeError) as exc:
|
||||
dest_url = url_for(
|
||||
"notes.apo_semset_maq_status",
|
||||
scodoc_dept=g.scodoc_dept,
|
||||
semset_id=semset_id,
|
||||
)
|
||||
if autodetect:
|
||||
# check encoding (although documentation states that users SHOULD upload LATIN1)
|
||||
data, message = sco_apogee_csv.fix_data_encoding(data)
|
||||
if message:
|
||||
log("view_apo_csv_store: %s" % message)
|
||||
raise ScoValueError(
|
||||
f"""
|
||||
Erreur: l'encodage du fichier est mal détecté.
|
||||
Essayez sans auto-détection, ou vérifiez le codage et le contenu
|
||||
du fichier (qui doit être en {sco_apogee_csv.APO_INPUT_ENCODING}).
|
||||
""",
|
||||
dest_url=dest_url,
|
||||
) from exc
|
||||
else:
|
||||
log("view_apo_csv_store: autodetection of encoding disabled by user")
|
||||
if not data:
|
||||
raise ScoValueError("view_apo_csv_store: no data")
|
||||
# data est du bytes, encodé en APO_INPUT_ENCODING
|
||||
data_str = data.decode(APO_INPUT_ENCODING)
|
||||
raise ScoValueError(
|
||||
f"""
|
||||
Erreur: l'encodage du fichier est incorrect.
|
||||
Vérifiez qu'il est bien en {sco_apogee_csv.APO_INPUT_ENCODING}
|
||||
""",
|
||||
dest_url=dest_url,
|
||||
) from exc
|
||||
|
||||
# check si etape maquette appartient bien au semset
|
||||
apo_data = sco_apogee_csv.ApoData(
|
||||
data_str, periode=semset["sem_id"]
|
||||
|
@ -36,7 +36,7 @@ from flask_login import current_user
|
||||
|
||||
from app import db, log
|
||||
|
||||
from app.models import Evaluation, ModuleImpl, ScolarNews
|
||||
from app.models import ModuleImpl, ScolarNews
|
||||
from app.models.evaluations import evaluation_enrich_dict, check_evaluation_args
|
||||
import app.scodoc.sco_utils as scu
|
||||
import app.scodoc.notesdb as ndb
|
||||
|
@ -345,7 +345,7 @@ def evaluation_create_form(
|
||||
+ "\n".join(H)
|
||||
+ "\n"
|
||||
+ tf[1]
|
||||
+ render_template("scodoc/help/evaluations.html", is_apc=is_apc)
|
||||
+ render_template("scodoc/help/evaluations.j2", is_apc=is_apc)
|
||||
+ html_sco_header.sco_footer()
|
||||
)
|
||||
elif tf[0] == -1:
|
||||
|
@ -75,6 +75,7 @@ _formationEditor = ndb.EditableTable(
|
||||
"type_parcours",
|
||||
"code_specialite",
|
||||
"referentiel_competence_id",
|
||||
"commentaire",
|
||||
),
|
||||
filter_dept=True,
|
||||
sortkey="acronyme",
|
||||
@ -118,6 +119,7 @@ def formation_export(
|
||||
formation: Formation = Formation.query.get_or_404(formation_id)
|
||||
f_dict = formation.to_dict(with_refcomp_attrs=True)
|
||||
if not export_ids:
|
||||
del f_dict["id"]
|
||||
del f_dict["formation_id"]
|
||||
del f_dict["dept_id"]
|
||||
ues = formation.ues
|
||||
|
@ -541,7 +541,7 @@ def formsemestre_page_title(formsemestre_id=None):
|
||||
formsemestre = FormSemestre.query.get_or_404(formsemestre_id)
|
||||
|
||||
h = render_template(
|
||||
"formsemestre_page_title.html",
|
||||
"formsemestre_page_title.j2",
|
||||
formsemestre=formsemestre,
|
||||
scu=scu,
|
||||
sem_menu_bar=formsemestre_status_menubar(formsemestre),
|
||||
|
@ -46,7 +46,7 @@ def affect_groups(partition_id):
|
||||
raise AccessDenied("vous n'avez pas la permission de modifier les groupes")
|
||||
partition.formsemestre.setup_parcours_groups()
|
||||
return render_template(
|
||||
"scolar/affect_groups.html",
|
||||
"scolar/affect_groups.j2",
|
||||
sco_header=html_sco_header.sco_header(
|
||||
page_title="Affectation aux groupes",
|
||||
javascripts=["js/groupmgr.js"],
|
||||
|
@ -400,9 +400,7 @@ def moduleimpl_inscriptions_stats(formsemestre_id):
|
||||
# Etudiants "dispensés" d'une UE (capitalisée)
|
||||
ues_cap_info = get_etuds_with_capitalized_ue(formsemestre_id)
|
||||
if ues_cap_info:
|
||||
H.append(
|
||||
'<h3>Étudiants avec UEs capitalisées (ADM):</h3><ul class="ue_inscr_list">'
|
||||
)
|
||||
H.append('<h3>Étudiants avec UEs capitalisées:</h3><ul class="ue_inscr_list">')
|
||||
ues = [
|
||||
sco_edit_ue.ue_list({"ue_id": ue_id})[0] for ue_id in ues_cap_info.keys()
|
||||
]
|
||||
@ -470,9 +468,8 @@ def moduleimpl_inscriptions_stats(formsemestre_id):
|
||||
if can_change:
|
||||
H.append(
|
||||
f"""<div><a class="stdlink" href="{
|
||||
url_for("notes.etud_inscrit_ue",
|
||||
scodoc_dept=g.scodoc_dept, etudid=etud["etudid"],
|
||||
formsemestre_id=formsemestre_id, ue_id=ue["ue_id"])
|
||||
url_for("notes.etud_inscrit_ue", scodoc_dept=g.scodoc_dept, etudid=etud["etudid"],
|
||||
formsemestre_id=formsemestre_id, ue_id=ue["ue_id"])
|
||||
}">inscrire à {"" if is_apc else "tous les modules de"} cette UE</a></div>
|
||||
"""
|
||||
)
|
||||
|
@ -215,7 +215,7 @@ def placement_eval_selectetuds(evaluation_id):
|
||||
html_sco_header.sco_header(),
|
||||
sco_evaluations.evaluation_describe(evaluation_id=evaluation_id),
|
||||
"<h3>Placement et émargement des étudiants</h3>",
|
||||
render_template("scodoc/forms/placement.html", form=form),
|
||||
render_template("scodoc/forms/placement.j2", form=form),
|
||||
]
|
||||
footer = html_sco_header.sco_footer()
|
||||
return "\n".join(htmls) + "<p>" + footer
|
||||
|
@ -166,9 +166,15 @@ def formsemestre_recapcomplet(
|
||||
H.append("<p>")
|
||||
if mode_jury:
|
||||
H.append(
|
||||
f"""<a class="stdlink" href="{url_for('notes.formsemestre_validation_auto',
|
||||
f"""<p><a class="stdlink" href="{url_for('notes.formsemestre_validation_auto',
|
||||
scodoc_dept=g.scodoc_dept, formsemestre_id=formsemestre_id)
|
||||
}">Calcul automatique des décisions du jury</a></p>"""
|
||||
}">Calcul automatique des décisions du jury</a>
|
||||
</p><a class="stdlink" href="{url_for('notes.formsemestre_jury_but_erase',
|
||||
scodoc_dept=g.scodoc_dept, formsemestre_id=formsemestre_id, only_one_sem=1)
|
||||
}">Effacer <em>toutes</em> les décisions de jury du semestre</a>
|
||||
<p>
|
||||
</p>
|
||||
"""
|
||||
)
|
||||
else:
|
||||
H.append(
|
||||
|
@ -554,7 +554,7 @@ def photos_import_files_form(group_ids=()):
|
||||
back_url=back_url,
|
||||
)
|
||||
return render_template(
|
||||
"scolar/photos_import_files.html",
|
||||
"scolar/photos_import_files.j2",
|
||||
page_title="Téléchargement des photos des étudiants",
|
||||
ignored_zipfiles=ignored_zipfiles,
|
||||
unmatched_files=unmatched_files,
|
||||
|
@ -128,6 +128,13 @@ ETAT_JUSTIFICATIF_NAME = {
|
||||
EtatJustificatif.MODIFIE: "modifié",
|
||||
}
|
||||
|
||||
ETATS_JUSTIFICATIF = {
|
||||
"validé": EtatJustificatif.VALIDE,
|
||||
"non vaidé": EtatJustificatif.NON_VALIDE,
|
||||
"en attente": EtatJustificatif.ATTENTE,
|
||||
"modifié": EtatJustificatif.MODIFIE,
|
||||
}
|
||||
|
||||
|
||||
def is_iso_formated(date: str, convert=False) -> bool or datetime.datetime or None:
|
||||
"""
|
||||
|
@ -4,6 +4,7 @@
|
||||
:root {
|
||||
--sco-content-min-width: 600px;
|
||||
--sco-content-max-width: 1024px;
|
||||
--sco-color-explication: rgb(10, 58, 140);
|
||||
}
|
||||
|
||||
html,
|
||||
@ -325,9 +326,9 @@ div.logo-logo img {
|
||||
box-sizing: content-box;
|
||||
margin-top: 10px;
|
||||
/* -10px */
|
||||
width: 80px;
|
||||
width: 130px;
|
||||
/* adapter suivant image */
|
||||
padding-right: 5px;
|
||||
/* padding-right: 5px; */
|
||||
}
|
||||
|
||||
div.sidebar-bottom {
|
||||
@ -2115,6 +2116,11 @@ div.formation_descr span.fd_n {
|
||||
margin-left: 6em;
|
||||
}
|
||||
|
||||
span.explication {
|
||||
font-style: italic;
|
||||
color: var(--sco-color-explication);
|
||||
}
|
||||
|
||||
div.formation_ue_list {
|
||||
border: 1px solid black;
|
||||
margin-top: 5px;
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 69 KiB |
@ -14,6 +14,8 @@ $(function () {
|
||||
const url = new URL(document.URL);
|
||||
const formsemestre_id = url.searchParams.get("formsemestre_id");
|
||||
const order_info_key = JSON.stringify([url.pathname, formsemestre_id]);
|
||||
const etudids_key = JSON.stringify(["etudids", url.origin, formsemestre_id]);
|
||||
const noms_key = JSON.stringify(["noms", url.origin, formsemestre_id]);
|
||||
let order_info;
|
||||
if (formsemestre_id) {
|
||||
const x = localStorage.getItem(order_info_key);
|
||||
@ -157,83 +159,89 @@ $(function () {
|
||||
}
|
||||
});
|
||||
}
|
||||
let table = $('table.table_recap').DataTable(
|
||||
{
|
||||
paging: false,
|
||||
searching: true,
|
||||
info: false,
|
||||
autoWidth: false,
|
||||
fixedHeader: {
|
||||
header: true,
|
||||
footer: false
|
||||
},
|
||||
orderCellsTop: true, // cellules ligne 1 pour tri
|
||||
aaSorting: [], // Prevent initial sorting
|
||||
colReorder: true,
|
||||
stateSave: true, // enregistre état de la table (tris, ...)
|
||||
"columnDefs": [
|
||||
{
|
||||
// cache les codes, le détail de l'identité, les groupes, les colonnes admission et les vides
|
||||
targets: hidden_colums,
|
||||
visible: false,
|
||||
try {
|
||||
let table = $('table.table_recap').DataTable(
|
||||
{
|
||||
paging: false,
|
||||
searching: true,
|
||||
info: false,
|
||||
autoWidth: false,
|
||||
fixedHeader: {
|
||||
header: true,
|
||||
footer: false
|
||||
},
|
||||
{
|
||||
// Elimine les 0 à gauche pour les exports excel et les "copy"
|
||||
targets: ["col_mod", "col_moy_gen", "col_ue", "col_res", "col_sae", "evaluation", "col_rcue"],
|
||||
render: function (data, type, row) {
|
||||
return type === 'export' ? data.replace(/0(\d\..*)/, '$1') : data;
|
||||
orderCellsTop: true, // cellules ligne 1 pour tri
|
||||
aaSorting: [], // Prevent initial sorting
|
||||
colReorder: true,
|
||||
stateSave: true, // enregistre état de la table (tris, ...)
|
||||
"columnDefs": [
|
||||
{
|
||||
// cache les codes, le détail de l'identité, les groupes, les colonnes admission et les vides
|
||||
targets: hidden_colums,
|
||||
visible: false,
|
||||
},
|
||||
{
|
||||
// Elimine les 0 à gauche pour les exports excel et les "copy"
|
||||
targets: ["col_mod", "col_moy_gen", "col_ue", "col_res", "col_sae", "evaluation", "col_rcue"],
|
||||
render: function (data, type, row) {
|
||||
return type === 'export' ? data.replace(/0(\d\..*)/, '$1') : data;
|
||||
}
|
||||
},
|
||||
{
|
||||
// Elimine les décorations (fleches bonus/malus) pour les exports
|
||||
targets: ["col_ue_bonus", "col_malus"],
|
||||
render: function (data, type, row) {
|
||||
return type === 'export' ? data.replace(/.*(\d\d\.\d\d)/, '$1').replace(/0(\d\..*)/, '$1') : data;
|
||||
}
|
||||
},
|
||||
],
|
||||
dom: 'Bfrtip',
|
||||
buttons: [
|
||||
{
|
||||
extend: 'copyHtml5',
|
||||
text: 'Copier',
|
||||
exportOptions: { orthogonal: 'export' }
|
||||
},
|
||||
{
|
||||
extend: 'excelHtml5',
|
||||
// footer: true, // ne fonctionne pas ?
|
||||
exportOptions: { orthogonal: 'export' },
|
||||
title: document.querySelector('table.table_recap').dataset.filename
|
||||
},
|
||||
{
|
||||
extend: 'collection',
|
||||
text: 'Colonnes affichées',
|
||||
autoClose: true,
|
||||
buttons: buttons,
|
||||
},
|
||||
],
|
||||
"drawCallback": function (settings) {
|
||||
// permet de conserver l'ordre de tri des colonnes
|
||||
let order_info = JSON.stringify($('table.table_recap').DataTable().order());
|
||||
if (formsemestre_id) {
|
||||
localStorage.setItem(order_info_key, order_info);
|
||||
}
|
||||
let etudids = [];
|
||||
document.querySelectorAll("td.identite_court").forEach(e => {
|
||||
etudids.push(e.dataset.etudid);
|
||||
});
|
||||
let noms = [];
|
||||
document.querySelectorAll("td.identite_court").forEach(e => {
|
||||
noms.push(e.dataset.nomprenom);
|
||||
});
|
||||
localStorage.setItem(etudids_key, JSON.stringify(etudids));
|
||||
localStorage.setItem(noms_key, JSON.stringify(noms));
|
||||
},
|
||||
{
|
||||
// Elimine les décorations (fleches bonus/malus) pour les exports
|
||||
targets: ["col_ue_bonus", "col_malus"],
|
||||
render: function (data, type, row) {
|
||||
return type === 'export' ? data.replace(/.*(\d\d\.\d\d)/, '$1').replace(/0(\d\..*)/, '$1') : data;
|
||||
}
|
||||
},
|
||||
],
|
||||
dom: 'Bfrtip',
|
||||
buttons: [
|
||||
{
|
||||
extend: 'copyHtml5',
|
||||
text: 'Copier',
|
||||
exportOptions: { orthogonal: 'export' }
|
||||
},
|
||||
{
|
||||
extend: 'excelHtml5',
|
||||
// footer: true, // ne fonctionne pas ?
|
||||
exportOptions: { orthogonal: 'export' },
|
||||
title: document.querySelector('table.table_recap').dataset.filename
|
||||
},
|
||||
{
|
||||
extend: 'collection',
|
||||
text: 'Colonnes affichées',
|
||||
autoClose: true,
|
||||
buttons: buttons,
|
||||
},
|
||||
],
|
||||
"drawCallback": function (settings) {
|
||||
// permet de conserver l'ordre de tri des colonnes
|
||||
let order_info = JSON.stringify($('table.table_recap').DataTable().order());
|
||||
if (formsemestre_id) {
|
||||
localStorage.setItem(order_info_key, order_info);
|
||||
}
|
||||
let etudids = [];
|
||||
document.querySelectorAll("td.identite_court").forEach(e => {
|
||||
etudids.push(e.dataset.etudid);
|
||||
});
|
||||
let noms = [];
|
||||
document.querySelectorAll("td.identite_court").forEach(e => {
|
||||
noms.push(e.dataset.nomprenom);
|
||||
});
|
||||
const etudids_key = JSON.stringify(["etudids", url.origin, formsemestre_id]);
|
||||
localStorage.setItem(etudids_key, JSON.stringify(etudids));
|
||||
const noms_key = JSON.stringify(["noms", url.origin, formsemestre_id]);
|
||||
localStorage.setItem(noms_key, JSON.stringify(noms));
|
||||
},
|
||||
"order": order_info,
|
||||
}
|
||||
);
|
||||
"order": order_info,
|
||||
}
|
||||
);
|
||||
} catch (error) {
|
||||
// l'erreur peut etre causee par un ancien storage:
|
||||
localStorage.removeItem(etudids_key);
|
||||
localStorage.removeItem(noms_key);
|
||||
localStorage.removeItem(order_info_key);
|
||||
location.reload();
|
||||
}
|
||||
update_buttons_labels(table);
|
||||
});
|
||||
$('table.table_recap tbody').on('click', 'tr', function () {
|
||||
|
@ -1,18 +1,18 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends 'base.html' %}
|
||||
{% extends 'base.j2' %}
|
||||
{% import 'bootstrap/wtf.html' as wtf %}
|
||||
|
||||
{% block app_content %}
|
||||
|
||||
<h2>Système de gestion scolarité</h2>
|
||||
|
||||
<p>© Emmanuel Viennet 2021</p>
|
||||
<p>© Emmanuel Viennet 2023</p>
|
||||
|
||||
<p>Version {{ version }}</p>
|
||||
|
||||
<p>ScoDoc est un logiciel libre écrit en
|
||||
<a href="http://www.python.org" target="_blank" rel="noopener noreferrer">Python</a>.
|
||||
Information et documentation sur <a href="https://scodoc.org" target="_blank">scodoc.org</a>.
|
||||
<a href="http://www.python.org" target="_blank" rel="noopener noreferrer">Python</a>.
|
||||
Information et documentation sur <a href="https://scodoc.org" target="_blank">scodoc.org</a>.
|
||||
</p>
|
||||
|
||||
<h2>Dernières évolutions</h2>
|
@ -1,14 +1,14 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends "base.html" %}
|
||||
{% extends "base.j2" %}
|
||||
{% import 'bootstrap/wtf.html' as wtf %}
|
||||
|
||||
{% macro render_field(field, auth_name=None) %}
|
||||
<tr style="">
|
||||
{% if auth_name %}
|
||||
<td class="wtf-field"> {{ field.label }}<span style="font-weight:700;"> ({{ auth_name }}):</span></td>
|
||||
{% if auth_name %}
|
||||
<td class="wtf-field"> {{ field.label }}<span style="font-weight:700;"> ({{ auth_name }}):</span></td>
|
||||
{% else %}
|
||||
<td class="wtf-field">{{ field.label }}</td>
|
||||
{% endif %}
|
||||
<td class="wtf-field">{{ field.label }}</td>
|
||||
{% endif %}
|
||||
<td class="wtf-field">{{ field(**kwargs)|safe }}
|
||||
{% if field.errors %}
|
||||
<ul class=errors>
|
||||
@ -23,19 +23,20 @@
|
||||
|
||||
{% block app_content %}
|
||||
<h1>Modification du compte ScoDoc <tt>{{form.user_name.data}}</tt></h1>
|
||||
<div class="help">
|
||||
<div class="help">
|
||||
<p>Identifiez-vous avec votre mot de passe actuel</p>
|
||||
</div>
|
||||
<form method=post>
|
||||
{{ form.user_name }}
|
||||
{{ form.csrf_token }}
|
||||
<table class="tf"><tbody>
|
||||
</div>
|
||||
<form method=post>
|
||||
{{ form.user_name }}
|
||||
{{ form.csrf_token }}
|
||||
<table class="tf">
|
||||
<tbody>
|
||||
{{ render_field(form.old_password, size=14, auth_name=auth_username,
|
||||
style="padding:1px; margin-left: 1em; margin-top: 4px;") }}
|
||||
<tr>
|
||||
<td colspan=""2">
|
||||
<p>Vous pouvez changer le mot de passe et/ou l'adresse email.</p>
|
||||
<p>Les champs laissés vides ne seront pas modifiés.</p>
|
||||
<td colspan="" 2">
|
||||
<p>Vous pouvez changer le mot de passe et/ou l'adresse email.</p>
|
||||
<p>Les champs laissés vides ne seront pas modifiés.</p>
|
||||
</td>
|
||||
</tr>
|
||||
{{ render_field(form.new_password, size=14,
|
||||
@ -44,8 +45,9 @@
|
||||
style="padding:1px; margin-left: 1em; margin-top: 4px;") }}
|
||||
{{ render_field(form.email, size=40,
|
||||
style="padding:1px; margin-top: 12px;margin-bottom: 16px; margin-left: 1em;") }}
|
||||
</tbody></table>
|
||||
<input type="submit" value="Valider">
|
||||
<input type="submit" name="cancel" value="Annuler" style="margin-left: 1em;>
|
||||
</tbody>
|
||||
</table>
|
||||
<input type="submit" value="Valider">
|
||||
<input type="submit" name="cancel" value="Annuler" style="margin-left: 1em;>
|
||||
</form>
|
||||
{% endblock %}
|
@ -1,5 +1,5 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends 'base.html' %}
|
||||
{% extends 'base.j2' %}
|
||||
{% import 'bootstrap/wtf.html' as wtf %}
|
||||
|
||||
{% block app_content %}
|
@ -1,5 +1,5 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends "base.html" %}
|
||||
{% extends "base.j2" %}
|
||||
{% import 'bootstrap/wtf.html' as wtf %}
|
||||
|
||||
{% block app_content %}
|
@ -1,5 +1,5 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends "base.html" %}
|
||||
{% extends "base.j2" %}
|
||||
{% import 'bootstrap/wtf.html' as wtf %}
|
||||
|
||||
{% block app_content %}
|
@ -1,5 +1,5 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends "base.html" %}
|
||||
{% extends "base.j2" %}
|
||||
{% import 'bootstrap/wtf.html' as wtf %}
|
||||
|
||||
{% block app_content %}
|
@ -1,5 +1,5 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends "base.html" %}
|
||||
{% extends "base.j2" %}
|
||||
{% import 'bootstrap/wtf.html' as wtf %}
|
||||
|
||||
{% block app_content %}
|
@ -1,5 +1,5 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends "base.html" %}
|
||||
{% extends "base.j2" %}
|
||||
{% import 'bootstrap/wtf.html' as wtf %}
|
||||
|
||||
{% block app_content %}
|
||||
@ -19,8 +19,8 @@
|
||||
<p>
|
||||
<ul>
|
||||
{% if (
|
||||
current_user.is_administrator()
|
||||
or current_user.has_permission(Permission.ScoUsersAdmin, user.dept)
|
||||
current_user.is_administrator()
|
||||
or current_user.has_permission(Permission.ScoUsersAdmin, user.dept)
|
||||
) %}
|
||||
<li><a class="stdlink" href="{{
|
||||
url_for( 'users.form_change_password',
|
||||
@ -36,14 +36,14 @@
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if (
|
||||
current_user.is_administrator()
|
||||
or current_user.has_permission(Permission.ScoUsersAdmin, user.dept)
|
||||
current_user.is_administrator()
|
||||
or current_user.has_permission(Permission.ScoUsersAdmin, user.dept)
|
||||
) %}
|
||||
<li><a class="stdlink" href="{{
|
||||
<li><a class="stdlink" href="{{
|
||||
url_for('users.toggle_active_user', scodoc_dept=g.scodoc_dept,
|
||||
user_name=user.user_name)
|
||||
}}">{{"désactiver" if user.active else "activer"}} ce compte</a>
|
||||
</li>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
|
@ -28,17 +28,19 @@
|
||||
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
|
||||
|
||||
<ul class="nav navbar-nav">
|
||||
{% if current_user.is_administrator() %}
|
||||
{% if current_user.is_administrator() %}
|
||||
<li><a href="{{ url_for('scodoc.configuration') }}">Configuration</a></li>
|
||||
{% endif %}
|
||||
{% if g.scodoc_dept %}
|
||||
{% endif %}
|
||||
{% if g.scodoc_dept %}
|
||||
<li><a href="{{
|
||||
url_for('scolar.index_html', scodoc_dept=g.scodoc_dept)
|
||||
}}">Dept. {{ g.scodoc_dept }}</a></li>
|
||||
{% endif %}
|
||||
{% if not current_user.is_anonymous and current_user.has_permission(current_user.Permission.RelationsEntreprisesView, None) and scu and scu.is_entreprises_enabled() %}
|
||||
{% endif %}
|
||||
{% if not current_user.is_anonymous and
|
||||
current_user.has_permission(current_user.Permission.RelationsEntreprisesView, None) and scu and
|
||||
scu.is_entreprises_enabled() %}
|
||||
<li><a href="{{ url_for('entreprises.index') }}">Entreprises</a></li>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</ul>
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
{% if current_user.is_anonymous %}
|
||||
@ -62,9 +64,9 @@
|
||||
{% block content %}
|
||||
<div class="container">
|
||||
{% with messages = get_flashed_messages(with_categories=true) %}
|
||||
{% for category, message in messages %}
|
||||
<div class="alert alert-info alert-{{ category }}" role="alert">{{ message }}</div>
|
||||
{% endfor %}
|
||||
{% for category, message in messages %}
|
||||
<div class="alert alert-info alert-{{ category }}" role="alert">{{ message }}</div>
|
||||
{% endfor %}
|
||||
{% endwith %}
|
||||
|
||||
{# application content needs to be provided in the app_content block #}
|
@ -1,5 +1,5 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends "sco_page.html" %}
|
||||
{% extends "sco_page.j2" %}
|
||||
|
||||
{% block styles %}
|
||||
{{super()}}
|
||||
@ -7,12 +7,12 @@
|
||||
|
||||
{% block app_content %}
|
||||
|
||||
{% include 'bul_head.html' %}
|
||||
{% include 'bul_head.j2' %}
|
||||
|
||||
<releve-but></releve-but>
|
||||
<script src="{{sco.scu.STATIC_DIR}}/js/releve-but.js"></script>
|
||||
|
||||
{% include 'bul_foot.html' %}
|
||||
{% include 'bul_foot.j2' %}
|
||||
|
||||
<script>
|
||||
let dataSrc = "{{bul_url|safe}}";
|
@ -1,5 +1,5 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends "sco_page.html" %}
|
||||
{% extends "sco_page.j2" %}
|
||||
{% import 'bootstrap/wtf.html' as wtf %}
|
||||
|
||||
{% block styles %}
|
@ -1,5 +1,5 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends "base.html" %}
|
||||
{% extends "base.j2" %}
|
||||
{% import 'bootstrap/wtf.html' as wtf %}
|
||||
|
||||
{% block app_content %}
|
||||
@ -15,11 +15,11 @@
|
||||
Référentiel actuellement associé:
|
||||
{% if formation.referentiel_competence is not none %}
|
||||
<b>{{ formation.referentiel_competence.specialite_long }}</b>
|
||||
<a href="{{
|
||||
<a href="{{
|
||||
url_for('notes.refcomp_desassoc_formation', scodoc_dept=g.scodoc_dept, formation_id=formation.id)
|
||||
}}" class="stdlink">supprimer</a>
|
||||
{% else %}
|
||||
<b>aucun</b>
|
||||
<b>aucun</b>
|
||||
{% endif %}
|
||||
<div class="row" style="margin-top: 20px;">
|
||||
<div class="col-md-4">
|
@ -1,30 +0,0 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends "base.html" %}
|
||||
{% import 'bootstrap/wtf.html' as wtf %}
|
||||
|
||||
{% block app_content %}
|
||||
<h1>Charger un référentiel de compétences</h1>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-5">
|
||||
{{ wtf.quick_form(form) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-5">
|
||||
<ul>
|
||||
<li>
|
||||
<a href="{{ url_for('notes.refcomp_table', scodoc_dept=g.scodoc_dept, ) }}">
|
||||
Liste des référentiels de compétences chargés</a>
|
||||
</li>
|
||||
{% if formation is not none %}
|
||||
<li>
|
||||
<a href="{{ url_for('notes.refcomp_assoc_formation', scodoc_dept=g.scodoc_dept, formation_id=formation.id) }}">
|
||||
Association à la formation {{ formation.acronyme }}</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
31
app/templates/but/refcomp_load.j2
Normal file
31
app/templates/but/refcomp_load.j2
Normal file
@ -0,0 +1,31 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends "base.j2" %}
|
||||
{% import 'bootstrap/wtf.html' as wtf %}
|
||||
|
||||
{% block app_content %}
|
||||
<h1>Charger un référentiel de compétences</h1>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-5">
|
||||
{{ wtf.quick_form(form) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-5">
|
||||
<ul>
|
||||
<li>
|
||||
<a href="{{ url_for('notes.refcomp_table', scodoc_dept=g.scodoc_dept, ) }}">
|
||||
Liste des référentiels de compétences chargés</a>
|
||||
</li>
|
||||
{% if formation is not none %}
|
||||
<li>
|
||||
<a
|
||||
href="{{ url_for('notes.refcomp_assoc_formation', scodoc_dept=g.scodoc_dept, formation_id=formation.id) }}">
|
||||
Association à la formation {{ formation.acronyme }}</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
@ -1,5 +1,5 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends "sco_page.html" %}
|
||||
{% extends "sco_page.j2" %}
|
||||
{% block styles %}
|
||||
{{super()}}
|
||||
{% endblock %}
|
@ -1,5 +1,5 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends "sco_page.html" %}
|
||||
{% extends "sco_page.j2" %}
|
||||
{% import 'bootstrap/wtf.html' as wtf %}
|
||||
|
||||
{% block app_content %}
|
@ -1,4 +1,4 @@
|
||||
{% extends "base.html" %}
|
||||
{% extends "base.j2" %}
|
||||
{% import 'bootstrap/wtf.html' as wtf %}
|
||||
|
||||
{% block app_content %}
|
@ -1,132 +0,0 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends 'base.html' %}
|
||||
{% import 'bootstrap/wtf.html' as wtf %}
|
||||
|
||||
{% macro render_field(field, with_label=True) %}
|
||||
<div>
|
||||
{% if with_label %}
|
||||
<span class="wtf-field">{{ field.label }} :</span>
|
||||
{% endif %}
|
||||
<span class="wtf-field">{{ field(**kwargs)|safe }}
|
||||
{% if field.errors %}
|
||||
<ul class=errors>
|
||||
{% for error in field.errors %}
|
||||
<li>{{ error }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
</span>
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro render_add_logo(add_logo_form) %}
|
||||
<details {{ add_logo_form.opened() }}>
|
||||
<summary>
|
||||
<h3>Ajouter un logo</h3>
|
||||
</summary>
|
||||
<div>
|
||||
{{ render_field(add_logo_form.name) }}
|
||||
{{ render_field(add_logo_form.upload) }}
|
||||
{{ render_field(add_logo_form.do_insert, False, onSubmit="submit_form") }}
|
||||
</div>
|
||||
</details>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro render_logo(dept_form, logo_form) %}
|
||||
<details {{ logo_form.opened() }}>
|
||||
{{ logo_form.hidden_tag() }}
|
||||
<summary>
|
||||
{% if logo_form.titre %}
|
||||
<h3 class="titre_logo">{{ logo_form.titre }}</h3>
|
||||
{% if logo_form.description %}
|
||||
<div class="sco_help">{{ logo_form.description }}</div>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<h3 class="titre_logo">Logo personalisé: {{ logo_form.logo_id.data }}</h3>
|
||||
{% if logo_form.description %}
|
||||
<div class="sco_help">{{ logo_form.description }}</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</summary>
|
||||
<div class="content">
|
||||
<div class="image_logo">
|
||||
<img src="{{ logo_form.logo.get_url_small() }}" alt="pas de logo chargé" />
|
||||
</div>
|
||||
<div class="infos_logo">
|
||||
<h4>{{ logo_form.logo.logoname }} (Format: {{ logo_form.logo.suffix }})</h4>
|
||||
Taille: {{ logo_form.logo.size }} px
|
||||
{% if logo_form.logo.mm %} / {{ logo_form.logo.mm }} mm {% endif %}<br />
|
||||
Aspect ratio: {{ logo_form.logo.aspect_ratio }}<br />
|
||||
Usage: <span style="font-family: system-ui">{{ logo_form.logo.get_usage() }}</span>
|
||||
</div>
|
||||
<div class="actions_logo">
|
||||
<div class="action_label">Modifier l'image</div>
|
||||
<div class="action_button">
|
||||
<span class="wtf-field">{{ render_field(logo_form.upload, False, onchange="submit_form()") }}</span>
|
||||
</div>
|
||||
{% if logo_form.can_delete %}
|
||||
<div class="action_label">Renommer</div>
|
||||
<div class="action_button">
|
||||
{{ render_field(logo_form.new_name, False) }}
|
||||
{{ render_field(logo_form.do_rename, False, onSubmit="submit_form()") }}
|
||||
</div>
|
||||
<div class="action_label">Supprimer l'image</div>
|
||||
<div class="action_button">
|
||||
{{ render_field(logo_form.do_delete, False, onSubmit="submit_form()") }}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</details>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro render_logos(dept_form) %}
|
||||
{% for logo_entry in dept_form.logos.entries %}
|
||||
{% set logo_form = logo_entry.form %}
|
||||
{{ render_logo(dept_form, logo_form) }}
|
||||
{% else %}
|
||||
<p class="logo-titre_logo">
|
||||
<h3 class="titre_logo">Aucun logo défini en propre à ce département</h3>
|
||||
</p>
|
||||
{% endfor %}
|
||||
{% endmacro %}
|
||||
|
||||
{% block app_content %}
|
||||
|
||||
<script src="/ScoDoc/static/jQuery/jquery.js"></script>
|
||||
<script src="/ScoDoc/static/js/config_logos.js"></script>
|
||||
|
||||
<form id="config_logos_form" class="sco-form" action="" method="post" enctype="multipart/form-data" novalidate>
|
||||
{{ form.hidden_tag() }}
|
||||
|
||||
<div class="configuration_logo">
|
||||
<h1>Bibliothèque de logos</h1>
|
||||
{% for dept_entry in form.depts.entries %}
|
||||
{% set dept_form = dept_entry.form %}
|
||||
{{ dept_entry.form.hidden_tag() }}
|
||||
<details {{ dept_form.opened() }}>
|
||||
<summary>
|
||||
<span class="entete_dept">
|
||||
{% if dept_entry.form.is_local() %}
|
||||
<h2>Département {{ dept_form.dept_name.data }}</h2>
|
||||
<h3 class="effectifs">{{ dept_form.count() }}</h3>
|
||||
<div class="sco_help">Les paramètres donnés sont spécifiques à ce département.<br />
|
||||
Les logos du département se substituent aux logos de même nom définis globalement:</div>
|
||||
{% else %}
|
||||
<h2>Logos généraux</h2>
|
||||
<h3 class="effectifs">{{ dept_form.count() }}</h3>
|
||||
<div class="sco_help">Les images de cette section sont utilisé pour tous les départements,
|
||||
mais peuvent être redéfinies localement au niveau de chaque département
|
||||
(il suffit de définir un logo local de même nom)</div>
|
||||
{% endif %}
|
||||
</span>
|
||||
</summary>
|
||||
<div>
|
||||
{{ render_logos(dept_form) }}
|
||||
{{ render_add_logo(dept_form.add_logo.form) }}
|
||||
</div>
|
||||
</details>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
132
app/templates/config_logos.j2
Normal file
132
app/templates/config_logos.j2
Normal file
@ -0,0 +1,132 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends 'base.j2' %}
|
||||
{% import 'bootstrap/wtf.html' as wtf %}
|
||||
|
||||
{% macro render_field(field, with_label=True) %}
|
||||
<div>
|
||||
{% if with_label %}
|
||||
<span class="wtf-field">{{ field.label }} :</span>
|
||||
{% endif %}
|
||||
<span class="wtf-field">{{ field(**kwargs)|safe }}
|
||||
{% if field.errors %}
|
||||
<ul class=errors>
|
||||
{% for error in field.errors %}
|
||||
<li>{{ error }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
</span>
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro render_add_logo(add_logo_form) %}
|
||||
<details {{ add_logo_form.opened() }}>
|
||||
<summary>
|
||||
<h3>Ajouter un logo</h3>
|
||||
</summary>
|
||||
<div>
|
||||
{{ render_field(add_logo_form.name) }}
|
||||
{{ render_field(add_logo_form.upload) }}
|
||||
{{ render_field(add_logo_form.do_insert, False, onSubmit="submit_form") }}
|
||||
</div>
|
||||
</details>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro render_logo(dept_form, logo_form) %}
|
||||
<details {{ logo_form.opened() }}>
|
||||
{{ logo_form.hidden_tag() }}
|
||||
<summary>
|
||||
{% if logo_form.titre %}
|
||||
<h3 class="titre_logo">{{ logo_form.titre }}</h3>
|
||||
{% if logo_form.description %}
|
||||
<div class="sco_help">{{ logo_form.description }}</div>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<h3 class="titre_logo">Logo personalisé: {{ logo_form.logo_id.data }}</h3>
|
||||
{% if logo_form.description %}
|
||||
<div class="sco_help">{{ logo_form.description }}</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</summary>
|
||||
<div class="content">
|
||||
<div class="image_logo">
|
||||
<img src="{{ logo_form.logo.get_url_small() }}" alt="pas de logo chargé" />
|
||||
</div>
|
||||
<div class="infos_logo">
|
||||
<h4>{{ logo_form.logo.logoname }} (Format: {{ logo_form.logo.suffix }})</h4>
|
||||
Taille: {{ logo_form.logo.size }} px
|
||||
{% if logo_form.logo.mm %} / {{ logo_form.logo.mm }} mm {% endif %}<br />
|
||||
Aspect ratio: {{ logo_form.logo.aspect_ratio }}<br />
|
||||
Usage: <span style="font-family: system-ui">{{ logo_form.logo.get_usage() }}</span>
|
||||
</div>
|
||||
<div class="actions_logo">
|
||||
<div class="action_label">Modifier l'image</div>
|
||||
<div class="action_button">
|
||||
<span class="wtf-field">{{ render_field(logo_form.upload, False, onchange="submit_form()") }}</span>
|
||||
</div>
|
||||
{% if logo_form.can_delete %}
|
||||
<div class="action_label">Renommer</div>
|
||||
<div class="action_button">
|
||||
{{ render_field(logo_form.new_name, False) }}
|
||||
{{ render_field(logo_form.do_rename, False, onSubmit="submit_form()") }}
|
||||
</div>
|
||||
<div class="action_label">Supprimer l'image</div>
|
||||
<div class="action_button">
|
||||
{{ render_field(logo_form.do_delete, False, onSubmit="submit_form()") }}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</details>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro render_logos(dept_form) %}
|
||||
{% for logo_entry in dept_form.logos.entries %}
|
||||
{% set logo_form = logo_entry.form %}
|
||||
{{ render_logo(dept_form, logo_form) }}
|
||||
{% else %}
|
||||
<p class="logo-titre_logo">
|
||||
<h3 class="titre_logo">Aucun logo défini en propre à ce département</h3>
|
||||
</p>
|
||||
{% endfor %}
|
||||
{% endmacro %}
|
||||
|
||||
{% block app_content %}
|
||||
|
||||
<script src="/ScoDoc/static/jQuery/jquery.js"></script>
|
||||
<script src="/ScoDoc/static/js/config_logos.js"></script>
|
||||
|
||||
<form id="config_logos_form" class="sco-form" action="" method="post" enctype="multipart/form-data" novalidate>
|
||||
{{ form.hidden_tag() }}
|
||||
|
||||
<div class="configuration_logo">
|
||||
<h1>Bibliothèque de logos</h1>
|
||||
{% for dept_entry in form.depts.entries %}
|
||||
{% set dept_form = dept_entry.form %}
|
||||
{{ dept_entry.form.hidden_tag() }}
|
||||
<details {{ dept_form.opened() }}>
|
||||
<summary>
|
||||
<span class="entete_dept">
|
||||
{% if dept_entry.form.is_local() %}
|
||||
<h2>Département {{ dept_form.dept_name.data }}</h2>
|
||||
<h3 class="effectifs">{{ dept_form.count() }}</h3>
|
||||
<div class="sco_help">Les paramètres donnés sont spécifiques à ce département.<br />
|
||||
Les logos du département se substituent aux logos de même nom définis globalement:</div>
|
||||
{% else %}
|
||||
<h2>Logos généraux</h2>
|
||||
<h3 class="effectifs">{{ dept_form.count() }}</h3>
|
||||
<div class="sco_help">Les images de cette section sont utilisé pour tous les départements,
|
||||
mais peuvent être redéfinies localement au niveau de chaque département
|
||||
(il suffit de définir un logo local de même nom)</div>
|
||||
{% endif %}
|
||||
</span>
|
||||
</summary>
|
||||
<div>
|
||||
{{ render_logos(dept_form) }}
|
||||
{{ render_add_logo(dept_form.add_logo.form) }}
|
||||
</div>
|
||||
</details>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
@ -1,12 +1,12 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends 'base.html' %}
|
||||
{% extends 'base.j2' %}
|
||||
{% import 'bootstrap/wtf.html' as wtf %}
|
||||
|
||||
{% macro render_field(field, with_label=True) %}
|
||||
<div>
|
||||
{% if with_label %}
|
||||
<span class="wtf-field">{{ field.label }} :</span>
|
||||
{% endif %}
|
||||
{% if with_label %}
|
||||
<span class="wtf-field">{{ field.label }} :</span>
|
||||
{% endif %}
|
||||
<span class="wtf-field">{{ field(**kwargs)|safe }}
|
||||
{% if field.errors %}
|
||||
<ul class=errors>
|
||||
@ -22,10 +22,10 @@
|
||||
{% block app_content %}
|
||||
|
||||
<h1>Configuration générale</h1>
|
||||
<div class="sco_help greenboldtext">Les paramètres donnés ici s'appliquent à tout ScoDoc (tous les départements).</div>
|
||||
<div class="sco_help greenboldtext">Les paramètres donnés ici s'appliquent à tout ScoDoc (tous les départements).</div>
|
||||
|
||||
<section>
|
||||
<h2>Calcul des "bonus" définis par l'établissement</h2>
|
||||
<h2>Calcul des "bonus" définis par l'établissement</h2>
|
||||
<form id="configuration_form" class="sco-form" action="" method="post" enctype="multipart/form-data" novalidate>
|
||||
{{ form_bonus.hidden_tag() }}
|
||||
<div class="row">
|
||||
@ -39,35 +39,36 @@
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2>Gestion des images: logos, signatures, ...</h2>
|
||||
<h2>Gestion des images: logos, signatures, ...</h2>
|
||||
<div class="sco_help">Ces images peuvent être intégrées dans les documents
|
||||
générés par ScoDoc: bulletins, PV, etc.
|
||||
générés par ScoDoc: bulletins, PV, etc.
|
||||
</div>
|
||||
<p><a class="stdlink" href="{{url_for('scodoc.configure_logos')}}">configuration des images et logos</a>
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2>Exports Apogée</h2>
|
||||
<p><a class="stdlink" href="{{url_for('scodoc.config_codes_decisions')}}">configuration des codes de décision</a></p>
|
||||
<h2>Exports Apogée</h2>
|
||||
<p><a class="stdlink" href="{{url_for('scodoc.config_codes_decisions')}}">configuration des codes de décision</a>
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<h2>Utilisateurs</h2>
|
||||
<section>
|
||||
<p><a class="stdlink" href="{{url_for('auth.reset_standard_roles_permissions')}}">remettre
|
||||
les permissions des rôles standards à leurs valeurs par défaut</a> (efface les modifications apportées)
|
||||
les permissions des rôles standards à leurs valeurs par défaut</a> (efface les modifications apportées)
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<h2>ScoDoc</h2>
|
||||
<form id="configuration_form_scodoc" class="sco-form" action="" method="post" enctype="multipart/form-data" novalidate>
|
||||
{{ form_scodoc.hidden_tag() }}
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
{{ wtf.quick_form(form_scodoc) }}
|
||||
</div>
|
||||
<form id="configuration_form_scodoc" class="sco-form" action="" method="post" enctype="multipart/form-data" novalidate>
|
||||
{{ form_scodoc.hidden_tag() }}
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
{{ wtf.quick_form(form_scodoc) }}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
@ -75,20 +76,19 @@
|
||||
|
||||
<script>
|
||||
|
||||
function update_bonus_description() {
|
||||
var query = "/ScoDoc/get_bonus_description/" + $("#configuration_form select")[0].value;
|
||||
$.get(query, '', function (data) {
|
||||
$("#bonus_description").html(data);
|
||||
});
|
||||
}
|
||||
function update_bonus_description() {
|
||||
var query = "/ScoDoc/get_bonus_description/" + $("#configuration_form select")[0].value;
|
||||
$.get(query, '', function (data) {
|
||||
$("#bonus_description").html(data);
|
||||
});
|
||||
}
|
||||
|
||||
$(function () {
|
||||
$("#configuration_form select").change(function () {
|
||||
update_bonus_description();
|
||||
});
|
||||
|
||||
$(function()
|
||||
{
|
||||
$("#configuration_form select").change(function(){
|
||||
update_bonus_description();
|
||||
});
|
||||
|
||||
update_bonus_description();
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
@ -1,5 +1,4 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends 'base.html' %}
|
||||
{% extends 'base.j2' %}
|
||||
{% import 'bootstrap/wtf.html' as wtf %}
|
||||
|
||||
{% block app_content %}
|
||||
@ -7,7 +6,7 @@
|
||||
<h2>{{ title }}</h2>
|
||||
|
||||
<div style="margin-top: 16px;">
|
||||
{{ explanation }}
|
||||
{{ explanation|safe }}
|
||||
</div>
|
||||
<div style="margin-top: 16px;">
|
||||
<form method="post">
|
@ -1,5 +1,5 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends "base.html" %}
|
||||
{% extends "base.j2" %}
|
||||
{% import 'bootstrap/wtf.html' as wtf %}
|
||||
|
||||
{% block app_content %}
|
@ -1,47 +0,0 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends "sco_page.html" %}
|
||||
{% block styles %}
|
||||
{{super()}}
|
||||
{% endblock %}
|
||||
|
||||
{% block app_content %}
|
||||
<h2>Opérations dans le département {{g.scodoc_dept}}</h2>
|
||||
|
||||
<table id="dept_news" class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Date</th>
|
||||
<th>Type</th>
|
||||
<th>Auteur</th>
|
||||
<th>Détail</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block scripts %}
|
||||
{{super()}}
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
$('#dept_news').DataTable({
|
||||
ajax: '{{url_for("scolar.dept_news_json", scodoc_dept=g.scodoc_dept)}}',
|
||||
serverSide: true,
|
||||
columns: [
|
||||
{
|
||||
data: {
|
||||
_: "date.display",
|
||||
sort: "date.timestamp"
|
||||
}
|
||||
},
|
||||
{data: 'type', searchable: false},
|
||||
{data: 'authenticated_user', orderable: false, searchable: true},
|
||||
{data: 'text', orderable: false, searchable: true}
|
||||
],
|
||||
"order": [[ 0, "desc" ]]
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
47
app/templates/dept_news.j2
Normal file
47
app/templates/dept_news.j2
Normal file
@ -0,0 +1,47 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends "sco_page.j2" %}
|
||||
{% block styles %}
|
||||
{{super()}}
|
||||
{% endblock %}
|
||||
|
||||
{% block app_content %}
|
||||
<h2>Opérations dans le département {{g.scodoc_dept}}</h2>
|
||||
|
||||
<table id="dept_news" class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Date</th>
|
||||
<th>Type</th>
|
||||
<th>Auteur</th>
|
||||
<th>Détail</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block scripts %}
|
||||
{{super()}}
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
$('#dept_news').DataTable({
|
||||
ajax: '{{url_for("scolar.dept_news_json", scodoc_dept=g.scodoc_dept)}}',
|
||||
serverSide: true,
|
||||
columns: [
|
||||
{
|
||||
data: {
|
||||
_: "date.display",
|
||||
sort: "date.timestamp"
|
||||
}
|
||||
},
|
||||
{ data: 'type', searchable: false },
|
||||
{ data: 'authenticated_user', orderable: false, searchable: true },
|
||||
{ data: 'text', orderable: false, searchable: true }
|
||||
],
|
||||
"order": [[0, "desc"]]
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
@ -1,104 +0,0 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block styles %}
|
||||
{{super()}}
|
||||
<script src="/ScoDoc/static/jQuery/jquery-1.12.4.min.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/ScoDoc/static/DataTables/datatables.min.css">
|
||||
<script type="text/javascript" charset="utf8" src="/ScoDoc/static/DataTables/datatables.min.js"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block app_content %}
|
||||
<div class="container">
|
||||
<ul class="breadcrumbs">
|
||||
<li class="breadcrumbs_item">
|
||||
<a href="{{ url_for('entreprises.index') }}" class="breadcrumbs_link">Entreprises</a>
|
||||
</li>
|
||||
<li class="breadcrumbs_item">
|
||||
<a href="{{ url_for('entreprises.fiche_entreprise', entreprise_id=entreprise.id) }}" class="breadcrumbs_link">Fiche entreprise</a>
|
||||
</li>
|
||||
<li class="breadcrumbs_item">
|
||||
<a href="" class="breadcrumbs_link breadcrumbs_link-active">Contacts</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="container" style="margin-bottom: 10px;">
|
||||
<h1>Liste des contacts</h1>
|
||||
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %}
|
||||
<a class="btn btn-primary" style="margin-bottom:10px;" href="{{ url_for('entreprises.add_contact', entreprise_id=entreprise.id) }}">Ajouter contact</a>
|
||||
{% endif %}
|
||||
<table id="table-contacts">
|
||||
<thead>
|
||||
<tr>
|
||||
<td data-priority="">Date</td>
|
||||
<td data-priority="">Utilisateur</td>
|
||||
<td data-priority="">Notes</td>
|
||||
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %}
|
||||
<td data-priority="">Action</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for contact in contacts %}
|
||||
<tr>
|
||||
<td>{{ contact.date.strftime('%d/%m/%Y %Hh%M') }}</td>
|
||||
<td>{{ contact.user|get_nomcomplet_by_id }}</td>
|
||||
<td>{{ contact.notes }}</td>
|
||||
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %}
|
||||
<td>
|
||||
<div class="btn-group">
|
||||
<a class="btn btn-default dropdown-toggle" data-toggle="dropdown" href="#">Action
|
||||
<span class="caret"></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu pull-left">
|
||||
<li><a href="{{ url_for('entreprises.edit_contact', entreprise_id=entreprise.id, contact_id=contact.id) }}">Modifier</a></li>
|
||||
<li><a href="{{ url_for('entreprises.delete_contact', entreprise_id=entreprise.id, contact_id=contact.id) }}" style="color:red">Supprimer</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td>Date</td>
|
||||
<td>Utilisateur</td>
|
||||
<td>Notes</td>
|
||||
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %}
|
||||
<td>Action</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
let table = new DataTable('#table-contacts',
|
||||
{
|
||||
"autoWidth": false,
|
||||
"responsive": {
|
||||
"details": true
|
||||
},
|
||||
"pageLength": 10,
|
||||
"language": {
|
||||
"emptyTable": "Aucune donnée disponible dans le tableau",
|
||||
"info": "Affichage de _START_ à _END_ sur _TOTAL_ entrées",
|
||||
"infoEmpty": "Affichage de 0 à 0 sur 0 entrées",
|
||||
"infoFiltered": "(filtrées depuis un total de _MAX_ entrées)",
|
||||
"lengthMenu": "Afficher _MENU_ entrées",
|
||||
"loadingRecords": "Chargement...",
|
||||
"processing": "Traitement...",
|
||||
"search": "Rechercher:",
|
||||
"zeroRecords": "Aucune entrée correspondante trouvée",
|
||||
"paginate": {
|
||||
"next": "Suivante",
|
||||
"previous": "Précédente"
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
109
app/templates/entreprises/contacts.j2
Normal file
109
app/templates/entreprises/contacts.j2
Normal file
@ -0,0 +1,109 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends 'base.j2' %}
|
||||
|
||||
{% block styles %}
|
||||
{{super()}}
|
||||
<script src="/ScoDoc/static/jQuery/jquery-1.12.4.min.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/ScoDoc/static/DataTables/datatables.min.css">
|
||||
<script type="text/javascript" charset="utf8" src="/ScoDoc/static/DataTables/datatables.min.js"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block app_content %}
|
||||
<div class="container">
|
||||
<ul class="breadcrumbs">
|
||||
<li class="breadcrumbs_item">
|
||||
<a href="{{ url_for('entreprises.index') }}" class="breadcrumbs_link">Entreprises</a>
|
||||
</li>
|
||||
<li class="breadcrumbs_item">
|
||||
<a href="{{ url_for('entreprises.fiche_entreprise', entreprise_id=entreprise.id) }}"
|
||||
class="breadcrumbs_link">Fiche entreprise</a>
|
||||
</li>
|
||||
<li class="breadcrumbs_item">
|
||||
<a href="" class="breadcrumbs_link breadcrumbs_link-active">Contacts</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="container" style="margin-bottom: 10px;">
|
||||
<h1>Liste des contacts</h1>
|
||||
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %}
|
||||
<a class="btn btn-primary" style="margin-bottom:10px;"
|
||||
href="{{ url_for('entreprises.add_contact', entreprise_id=entreprise.id) }}">Ajouter contact</a>
|
||||
{% endif %}
|
||||
<table id="table-contacts">
|
||||
<thead>
|
||||
<tr>
|
||||
<td data-priority="">Date</td>
|
||||
<td data-priority="">Utilisateur</td>
|
||||
<td data-priority="">Notes</td>
|
||||
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %}
|
||||
<td data-priority="">Action</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for contact in contacts %}
|
||||
<tr>
|
||||
<td>{{ contact.date.strftime('%d/%m/%Y %Hh%M') }}</td>
|
||||
<td>{{ contact.user|get_nomcomplet_by_id }}</td>
|
||||
<td>{{ contact.notes }}</td>
|
||||
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %}
|
||||
<td>
|
||||
<div class="btn-group">
|
||||
<a class="btn btn-default dropdown-toggle" data-toggle="dropdown" href="#">Action
|
||||
<span class="caret"></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu pull-left">
|
||||
<li><a
|
||||
href="{{ url_for('entreprises.edit_contact', entreprise_id=entreprise.id, contact_id=contact.id) }}">Modifier</a>
|
||||
</li>
|
||||
<li><a href="{{ url_for('entreprises.delete_contact', entreprise_id=entreprise.id, contact_id=contact.id) }}"
|
||||
style="color:red">Supprimer</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td>Date</td>
|
||||
<td>Utilisateur</td>
|
||||
<td>Notes</td>
|
||||
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %}
|
||||
<td>Action</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
let table = new DataTable('#table-contacts',
|
||||
{
|
||||
"autoWidth": false,
|
||||
"responsive": {
|
||||
"details": true
|
||||
},
|
||||
"pageLength": 10,
|
||||
"language": {
|
||||
"emptyTable": "Aucune donnée disponible dans le tableau",
|
||||
"info": "Affichage de _START_ à _END_ sur _TOTAL_ entrées",
|
||||
"infoEmpty": "Affichage de 0 à 0 sur 0 entrées",
|
||||
"infoFiltered": "(filtrées depuis un total de _MAX_ entrées)",
|
||||
"lengthMenu": "Afficher _MENU_ entrées",
|
||||
"loadingRecords": "Chargement...",
|
||||
"processing": "Traitement...",
|
||||
"search": "Rechercher:",
|
||||
"zeroRecords": "Aucune entrée correspondante trouvée",
|
||||
"paginate": {
|
||||
"next": "Suivante",
|
||||
"previous": "Précédente"
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
@ -1,93 +0,0 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block styles %}
|
||||
{{super()}}
|
||||
<script src="/ScoDoc/static/jQuery/jquery-1.12.4.min.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/ScoDoc/static/DataTables/datatables.min.css">
|
||||
<script type="text/javascript" charset="utf8" src="/ScoDoc/static/DataTables/datatables.min.js"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block app_content %}
|
||||
{% include 'entreprises/nav.html' %}
|
||||
|
||||
{% if logs %}
|
||||
<div class="container">
|
||||
<h3>Dernières opérations <a href="{{ url_for('entreprises.logs') }}">Voir tout</a></h3>
|
||||
<ul>
|
||||
{% for log in logs %}
|
||||
<li><span style="margin-right: 10px;">{{ log.date.strftime('%d %b %Hh%M') }}</span><span>{{ log.text|safe }} par {{ log.authenticated_user|get_nomcomplet_by_username }}</span></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="container" style="margin-bottom: 10px;">
|
||||
<h1>Liste des correspondants</h1>
|
||||
<table id="table-correspondants">
|
||||
<thead>
|
||||
<tr>
|
||||
<td data-priority="1">Nom</td>
|
||||
<td data-priority="3">Prenom</td>
|
||||
<td data-priority="4">Téléphone</td>
|
||||
<td data-priority="5">Mail</td>
|
||||
<td data-priority="6">Poste</td>
|
||||
<td data-priority="7">Service</td>
|
||||
<td data-priority="2">Entreprise</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for correspondant, site in correspondants %}
|
||||
<tr>
|
||||
<td>{{ correspondant.nom }}</td>
|
||||
<td>{{ correspondant.prenom }}</td>
|
||||
<td>{{ correspondant.telephone }}</td>
|
||||
<td>{{ correspondant.mail }}</td>
|
||||
<td>{{ correspondant.poste}}</td>
|
||||
<td>{{ correspondant.service}}</td>
|
||||
<td><a href="{{ url_for('entreprises.fiche_entreprise', entreprise_id=site.entreprise.id) }}">{{ site.nom }}</a></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td>Nom</td>
|
||||
<td>Prenom</td>
|
||||
<td>Téléphone</td>
|
||||
<td>Mail</td>
|
||||
<td>Poste</td>
|
||||
<td>Service</td>
|
||||
<td>Entreprise</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
let table = new DataTable('#table-correspondants',
|
||||
{
|
||||
"autoWidth": false,
|
||||
"responsive": {
|
||||
"details": true
|
||||
},
|
||||
"pageLength": 10,
|
||||
"language": {
|
||||
"emptyTable": "Aucune donnée disponible dans le tableau",
|
||||
"info": "Affichage de _START_ à _END_ sur _TOTAL_ entrées",
|
||||
"infoEmpty": "Affichage de 0 à 0 sur 0 entrées",
|
||||
"infoFiltered": "(filtrées depuis un total de _MAX_ entrées)",
|
||||
"lengthMenu": "Afficher _MENU_ entrées",
|
||||
"loadingRecords": "Chargement...",
|
||||
"processing": "Traitement...",
|
||||
"search": "Rechercher:",
|
||||
"zeroRecords": "Aucune entrée correspondante trouvée",
|
||||
"paginate": {
|
||||
"next": "Suivante",
|
||||
"previous": "Précédente"
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
95
app/templates/entreprises/correspondants.j2
Normal file
95
app/templates/entreprises/correspondants.j2
Normal file
@ -0,0 +1,95 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends 'base.j2' %}
|
||||
|
||||
{% block styles %}
|
||||
{{super()}}
|
||||
<script src="/ScoDoc/static/jQuery/jquery-1.12.4.min.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/ScoDoc/static/DataTables/datatables.min.css">
|
||||
<script type="text/javascript" charset="utf8" src="/ScoDoc/static/DataTables/datatables.min.js"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block app_content %}
|
||||
{% include 'entreprises/nav.html' %}
|
||||
|
||||
{% if logs %}
|
||||
<div class="container">
|
||||
<h3>Dernières opérations <a href="{{ url_for('entreprises.logs') }}">Voir tout</a></h3>
|
||||
<ul>
|
||||
{% for log in logs %}
|
||||
<li><span style="margin-right: 10px;">{{ log.date.strftime('%d %b %Hh%M') }}</span><span>{{ log.text|safe }} par
|
||||
{{ log.authenticated_user|get_nomcomplet_by_username }}</span></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="container" style="margin-bottom: 10px;">
|
||||
<h1>Liste des correspondants</h1>
|
||||
<table id="table-correspondants">
|
||||
<thead>
|
||||
<tr>
|
||||
<td data-priority="1">Nom</td>
|
||||
<td data-priority="3">Prenom</td>
|
||||
<td data-priority="4">Téléphone</td>
|
||||
<td data-priority="5">Mail</td>
|
||||
<td data-priority="6">Poste</td>
|
||||
<td data-priority="7">Service</td>
|
||||
<td data-priority="2">Entreprise</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for correspondant, site in correspondants %}
|
||||
<tr>
|
||||
<td>{{ correspondant.nom }}</td>
|
||||
<td>{{ correspondant.prenom }}</td>
|
||||
<td>{{ correspondant.telephone }}</td>
|
||||
<td>{{ correspondant.mail }}</td>
|
||||
<td>{{ correspondant.poste}}</td>
|
||||
<td>{{ correspondant.service}}</td>
|
||||
<td><a href="{{ url_for('entreprises.fiche_entreprise', entreprise_id=site.entreprise.id) }}">{{
|
||||
site.nom }}</a></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td>Nom</td>
|
||||
<td>Prenom</td>
|
||||
<td>Téléphone</td>
|
||||
<td>Mail</td>
|
||||
<td>Poste</td>
|
||||
<td>Service</td>
|
||||
<td>Entreprise</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
let table = new DataTable('#table-correspondants',
|
||||
{
|
||||
"autoWidth": false,
|
||||
"responsive": {
|
||||
"details": true
|
||||
},
|
||||
"pageLength": 10,
|
||||
"language": {
|
||||
"emptyTable": "Aucune donnée disponible dans le tableau",
|
||||
"info": "Affichage de _START_ à _END_ sur _TOTAL_ entrées",
|
||||
"infoEmpty": "Affichage de 0 à 0 sur 0 entrées",
|
||||
"infoFiltered": "(filtrées depuis un total de _MAX_ entrées)",
|
||||
"lengthMenu": "Afficher _MENU_ entrées",
|
||||
"loadingRecords": "Chargement...",
|
||||
"processing": "Traitement...",
|
||||
"search": "Rechercher:",
|
||||
"zeroRecords": "Aucune entrée correspondante trouvée",
|
||||
"paginate": {
|
||||
"next": "Suivante",
|
||||
"previous": "Précédente"
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
@ -1,133 +0,0 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block styles %}
|
||||
{{super()}}
|
||||
<script src="/ScoDoc/static/jQuery/jquery-1.12.4.min.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/ScoDoc/static/DataTables/datatables.min.css">
|
||||
<script type="text/javascript" charset="utf8" src="/ScoDoc/static/DataTables/datatables.min.js"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block app_content %}
|
||||
{% include 'entreprises/nav.html' %}
|
||||
|
||||
{% if logs %}
|
||||
<div class="container">
|
||||
<h3>Dernières opérations <a href="{{ url_for('entreprises.logs') }}">Voir tout</a></h3>
|
||||
<ul>
|
||||
{% for log in logs %}
|
||||
<li><span style="margin-right: 10px;">{{ log.date.strftime('%d %b %Hh%M') }}</span><span>{{ log.text|safe }} par {{ log.authenticated_user|get_nomcomplet_by_username }}</span></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="container boutons">
|
||||
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %}
|
||||
<a class="btn btn-default" href="{{ url_for('entreprises.add_entreprise') }}">Ajouter une entreprise</a>
|
||||
{% endif %}
|
||||
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesExport, None) %}
|
||||
<a class="btn btn-default" href="{{ url_for('entreprises.import_donnees') }}">Importer des données</a>
|
||||
{% endif %}
|
||||
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesExport, None) and entreprises %}
|
||||
<a class="btn btn-default" href="{{ url_for('entreprises.export_donnees') }}">Exporter des données</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="container" style="margin-bottom: 10px;">
|
||||
<h1>Liste des entreprises</h1>
|
||||
{% if form %}
|
||||
<form id="form-entreprise-filter" method="POST" action="">
|
||||
{{ form.hidden_tag() }}
|
||||
<div><input id="active" name="active" type="checkbox" onChange="form.submit()" {% if checked[0] %} checked {% endif %}> {{ form.active.label }}</div>
|
||||
<div><input id="association" name="association" type="checkbox" onChange="form.submit()" {% if checked[1] %} checked {% endif %}> {{ form.association.label }}</div>
|
||||
<div><input id="siret_provisoire" name="siret_provisoire" type="checkbox" onChange="form.submit()" {% if checked[2] %} checked {% endif %}> {{ form.siret_provisoire.label }}</div>
|
||||
</form>
|
||||
{% endif %}
|
||||
<table id="table-entreprises">
|
||||
<thead>
|
||||
<tr>
|
||||
<td data-priority="2">SIRET</td>
|
||||
<td data-priority="1">Nom</td>
|
||||
<td data-priority="4">Adresse</td>
|
||||
<td data-priority="6">Code postal</td>
|
||||
<td data-priority="5">Ville</td>
|
||||
<td data-priority="7">Pays</td>
|
||||
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %}
|
||||
<td data-priority="3">Action</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for entreprise in entreprises %}
|
||||
<tr>
|
||||
<td><a href="{{ url_for('entreprises.fiche_entreprise', entreprise_id=entreprise.id) }}" style="{% if not entreprise.active %}color:red;{% endif %}{% if entreprise.siret_provisoire %}font-weight:bold;{% endif %}" >{{ entreprise.siret }}</a></td>
|
||||
<td>{{ entreprise.nom }}</td>
|
||||
<td>{{ entreprise.adresse }}</td>
|
||||
<td>{{ entreprise.codepostal }}</td>
|
||||
<td>{{ entreprise.ville }}</td>
|
||||
<td>{{ entreprise.pays }}</td>
|
||||
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %}
|
||||
<td>
|
||||
<div class="btn-group">
|
||||
<a class="btn btn-default dropdown-toggle" data-toggle="dropdown" href="#">Action
|
||||
<span class="caret"></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu pull-left">
|
||||
<li><a href="{{ url_for('entreprises.edit_entreprise', entreprise_id=entreprise.id) }}">Modifier</a></li>
|
||||
{% if entreprise.active %}
|
||||
<li><a href="{{ url_for('entreprises.fiche_entreprise_desactiver', entreprise_id=entreprise.id)}}" style="color:red">Désactiver</a></li>
|
||||
{% else %}
|
||||
<li><a href="{{ url_for('entreprises.fiche_entreprise_activer', entreprise_id=entreprise.id)}}" style="color:lightgreen">Activer</a></li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td>SIRET</td>
|
||||
<td>Nom</td>
|
||||
<td>Adresse</td>
|
||||
<td>Code postal</td>
|
||||
<td>Ville</td>
|
||||
<td>Pays</td>
|
||||
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %}
|
||||
<td>Action</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
let table = new DataTable('#table-entreprises',
|
||||
{
|
||||
"autoWidth": false,
|
||||
"responsive": {
|
||||
"details": true
|
||||
},
|
||||
"pageLength": 10,
|
||||
"language": {
|
||||
"emptyTable": "Aucune donnée disponible dans le tableau",
|
||||
"info": "Affichage de _START_ à _END_ sur _TOTAL_ entrées",
|
||||
"infoEmpty": "Affichage de 0 à 0 sur 0 entrées",
|
||||
"infoFiltered": "(filtrées depuis un total de _MAX_ entrées)",
|
||||
"lengthMenu": "Afficher _MENU_ entrées",
|
||||
"loadingRecords": "Chargement...",
|
||||
"processing": "Traitement...",
|
||||
"search": "Rechercher:",
|
||||
"zeroRecords": "Aucune entrée correspondante trouvée",
|
||||
"paginate": {
|
||||
"next": "Suivante",
|
||||
"previous": "Précédente"
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
143
app/templates/entreprises/entreprises.j2
Normal file
143
app/templates/entreprises/entreprises.j2
Normal file
@ -0,0 +1,143 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends 'base.j2' %}
|
||||
|
||||
{% block styles %}
|
||||
{{super()}}
|
||||
<script src="/ScoDoc/static/jQuery/jquery-1.12.4.min.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/ScoDoc/static/DataTables/datatables.min.css">
|
||||
<script type="text/javascript" charset="utf8" src="/ScoDoc/static/DataTables/datatables.min.js"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block app_content %}
|
||||
{% include 'entreprises/nav.html' %}
|
||||
|
||||
{% if logs %}
|
||||
<div class="container">
|
||||
<h3>Dernières opérations <a href="{{ url_for('entreprises.logs') }}">Voir tout</a></h3>
|
||||
<ul>
|
||||
{% for log in logs %}
|
||||
<li><span style="margin-right: 10px;">{{ log.date.strftime('%d %b %Hh%M') }}</span><span>{{ log.text|safe }} par
|
||||
{{ log.authenticated_user|get_nomcomplet_by_username }}</span></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="container boutons">
|
||||
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %}
|
||||
<a class="btn btn-default" href="{{ url_for('entreprises.add_entreprise') }}">Ajouter une entreprise</a>
|
||||
{% endif %}
|
||||
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesExport, None) %}
|
||||
<a class="btn btn-default" href="{{ url_for('entreprises.import_donnees') }}">Importer des données</a>
|
||||
{% endif %}
|
||||
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesExport, None) and entreprises %}
|
||||
<a class="btn btn-default" href="{{ url_for('entreprises.export_donnees') }}">Exporter des données</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="container" style="margin-bottom: 10px;">
|
||||
<h1>Liste des entreprises</h1>
|
||||
{% if form %}
|
||||
<form id="form-entreprise-filter" method="POST" action="">
|
||||
{{ form.hidden_tag() }}
|
||||
<div><input id="active" name="active" type="checkbox" onChange="form.submit()" {% if checked[0] %} checked {%
|
||||
endif %}> {{ form.active.label }}</div>
|
||||
<div><input id="association" name="association" type="checkbox" onChange="form.submit()" {% if checked[1] %}
|
||||
checked {% endif %}> {{ form.association.label }}</div>
|
||||
<div><input id="siret_provisoire" name="siret_provisoire" type="checkbox" onChange="form.submit()" {% if
|
||||
checked[2] %} checked {% endif %}> {{ form.siret_provisoire.label }}</div>
|
||||
</form>
|
||||
{% endif %}
|
||||
<table id="table-entreprises">
|
||||
<thead>
|
||||
<tr>
|
||||
<td data-priority="2">SIRET</td>
|
||||
<td data-priority="1">Nom</td>
|
||||
<td data-priority="4">Adresse</td>
|
||||
<td data-priority="6">Code postal</td>
|
||||
<td data-priority="5">Ville</td>
|
||||
<td data-priority="7">Pays</td>
|
||||
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %}
|
||||
<td data-priority="3">Action</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for entreprise in entreprises %}
|
||||
<tr>
|
||||
<td><a href="{{ url_for('entreprises.fiche_entreprise', entreprise_id=entreprise.id) }}"
|
||||
style="{% if not entreprise.active %}color:red;{% endif %}{% if entreprise.siret_provisoire %}font-weight:bold;{% endif %}">{{
|
||||
entreprise.siret }}</a></td>
|
||||
<td>{{ entreprise.nom }}</td>
|
||||
<td>{{ entreprise.adresse }}</td>
|
||||
<td>{{ entreprise.codepostal }}</td>
|
||||
<td>{{ entreprise.ville }}</td>
|
||||
<td>{{ entreprise.pays }}</td>
|
||||
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %}
|
||||
<td>
|
||||
<div class="btn-group">
|
||||
<a class="btn btn-default dropdown-toggle" data-toggle="dropdown" href="#">Action
|
||||
<span class="caret"></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu pull-left">
|
||||
<li><a
|
||||
href="{{ url_for('entreprises.edit_entreprise', entreprise_id=entreprise.id) }}">Modifier</a>
|
||||
</li>
|
||||
{% if entreprise.active %}
|
||||
<li><a href="{{ url_for('entreprises.fiche_entreprise_desactiver', entreprise_id=entreprise.id)}}"
|
||||
style="color:red">Désactiver</a></li>
|
||||
{% else %}
|
||||
<li><a href="{{ url_for('entreprises.fiche_entreprise_activer', entreprise_id=entreprise.id)}}"
|
||||
style="color:lightgreen">Activer</a></li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td>SIRET</td>
|
||||
<td>Nom</td>
|
||||
<td>Adresse</td>
|
||||
<td>Code postal</td>
|
||||
<td>Ville</td>
|
||||
<td>Pays</td>
|
||||
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %}
|
||||
<td>Action</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
let table = new DataTable('#table-entreprises',
|
||||
{
|
||||
"autoWidth": false,
|
||||
"responsive": {
|
||||
"details": true
|
||||
},
|
||||
"pageLength": 10,
|
||||
"language": {
|
||||
"emptyTable": "Aucune donnée disponible dans le tableau",
|
||||
"info": "Affichage de _START_ à _END_ sur _TOTAL_ entrées",
|
||||
"infoEmpty": "Affichage de 0 à 0 sur 0 entrées",
|
||||
"infoFiltered": "(filtrées depuis un total de _MAX_ entrées)",
|
||||
"lengthMenu": "Afficher _MENU_ entrées",
|
||||
"loadingRecords": "Chargement...",
|
||||
"processing": "Traitement...",
|
||||
"search": "Rechercher:",
|
||||
"zeroRecords": "Aucune entrée correspondante trouvée",
|
||||
"paginate": {
|
||||
"next": "Suivante",
|
||||
"previous": "Précédente"
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
@ -1,95 +0,0 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block styles %}
|
||||
{{super()}}
|
||||
<script src="/ScoDoc/static/jQuery/jquery-1.12.4.min.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/ScoDoc/static/DataTables/datatables.min.css">
|
||||
<script type="text/javascript" charset="utf8" src="/ScoDoc/static/DataTables/datatables.min.js"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block app_content %}
|
||||
{% include 'entreprises/nav.html' %}
|
||||
|
||||
{% if logs %}
|
||||
<div class="container">
|
||||
<h3>Dernières opérations</h3>
|
||||
<ul>
|
||||
{% for log in logs %}
|
||||
<li><span style="margin-right: 10px;">{{ log.date.strftime('%d %b %Hh%M') }}</span><span>{{ log.text|safe }} par {{ log.authenticated_user|get_nomcomplet_by_username }}</span></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="container" style="margin-bottom: 10px;">
|
||||
<h1>Liste des entreprises à valider</h1>
|
||||
<table id="table-entreprises-validation">
|
||||
<thead>
|
||||
<tr>
|
||||
<td data-priority="3">SIRET</td>
|
||||
<td data-priority="1">Nom</td>
|
||||
<td data-priority="4">Adresse</td>
|
||||
<td data-priority="5">Code postal</td>
|
||||
<td data-priority="6">Ville</td>
|
||||
<td data-priority="7">Pays</td>
|
||||
<td data-priority="2">Action</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for entreprise in entreprises %}
|
||||
<tr class="table-row active">
|
||||
<th><a href="{{ url_for('entreprises.fiche_entreprise_validation', entreprise_id=entreprise.id) }}">{{ entreprise.siret }}</a></th>
|
||||
<th>{{ entreprise.nom }}</th>
|
||||
<th>{{ entreprise.adresse }}</th>
|
||||
<th>{{ entreprise.codepostal }}</th>
|
||||
<th>{{ entreprise.ville }}</th>
|
||||
<th>{{ entreprise.pays }}</th>
|
||||
<th>
|
||||
<a class="btn btn-default" href="{{ url_for('entreprises.fiche_entreprise_validation', entreprise_id=entreprise.id) }}">Voir</a>
|
||||
</th>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td>SIRET</td>
|
||||
<td>Nom</td>
|
||||
<td>Adresse</td>
|
||||
<td>Code postal</td>
|
||||
<td>Ville</td>
|
||||
<td>Pays</td>
|
||||
<td>Action</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
let table = new DataTable('#table-entreprises-validation',
|
||||
{
|
||||
"autoWidth": false,
|
||||
"responsive": {
|
||||
"details": true
|
||||
},
|
||||
"pageLength": 10,
|
||||
"language": {
|
||||
"emptyTable": "Aucune donnée disponible dans le tableau",
|
||||
"info": "Affichage de _START_ à _END_ sur _TOTAL_ entrées",
|
||||
"infoEmpty": "Affichage de 0 à 0 sur 0 entrées",
|
||||
"infoFiltered": "(filtrées depuis un total de _MAX_ entrées)",
|
||||
"lengthMenu": "Afficher _MENU_ entrées",
|
||||
"loadingRecords": "Chargement...",
|
||||
"processing": "Traitement...",
|
||||
"search": "Rechercher:",
|
||||
"zeroRecords": "Aucune entrée correspondante trouvée",
|
||||
"paginate": {
|
||||
"next": "Suivante",
|
||||
"previous": "Précédente"
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
98
app/templates/entreprises/entreprises_validation.j2
Normal file
98
app/templates/entreprises/entreprises_validation.j2
Normal file
@ -0,0 +1,98 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends 'base.j2' %}
|
||||
|
||||
{% block styles %}
|
||||
{{super()}}
|
||||
<script src="/ScoDoc/static/jQuery/jquery-1.12.4.min.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/ScoDoc/static/DataTables/datatables.min.css">
|
||||
<script type="text/javascript" charset="utf8" src="/ScoDoc/static/DataTables/datatables.min.js"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block app_content %}
|
||||
{% include 'entreprises/nav.html' %}
|
||||
|
||||
{% if logs %}
|
||||
<div class="container">
|
||||
<h3>Dernières opérations</h3>
|
||||
<ul>
|
||||
{% for log in logs %}
|
||||
<li><span style="margin-right: 10px;">{{ log.date.strftime('%d %b %Hh%M') }}</span><span>{{ log.text|safe }} par
|
||||
{{ log.authenticated_user|get_nomcomplet_by_username }}</span></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="container" style="margin-bottom: 10px;">
|
||||
<h1>Liste des entreprises à valider</h1>
|
||||
<table id="table-entreprises-validation">
|
||||
<thead>
|
||||
<tr>
|
||||
<td data-priority="3">SIRET</td>
|
||||
<td data-priority="1">Nom</td>
|
||||
<td data-priority="4">Adresse</td>
|
||||
<td data-priority="5">Code postal</td>
|
||||
<td data-priority="6">Ville</td>
|
||||
<td data-priority="7">Pays</td>
|
||||
<td data-priority="2">Action</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for entreprise in entreprises %}
|
||||
<tr class="table-row active">
|
||||
<th><a href="{{ url_for('entreprises.fiche_entreprise_validation', entreprise_id=entreprise.id) }}">{{
|
||||
entreprise.siret }}</a></th>
|
||||
<th>{{ entreprise.nom }}</th>
|
||||
<th>{{ entreprise.adresse }}</th>
|
||||
<th>{{ entreprise.codepostal }}</th>
|
||||
<th>{{ entreprise.ville }}</th>
|
||||
<th>{{ entreprise.pays }}</th>
|
||||
<th>
|
||||
<a class="btn btn-default"
|
||||
href="{{ url_for('entreprises.fiche_entreprise_validation', entreprise_id=entreprise.id) }}">Voir</a>
|
||||
</th>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td>SIRET</td>
|
||||
<td>Nom</td>
|
||||
<td>Adresse</td>
|
||||
<td>Code postal</td>
|
||||
<td>Ville</td>
|
||||
<td>Pays</td>
|
||||
<td>Action</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
let table = new DataTable('#table-entreprises-validation',
|
||||
{
|
||||
"autoWidth": false,
|
||||
"responsive": {
|
||||
"details": true
|
||||
},
|
||||
"pageLength": 10,
|
||||
"language": {
|
||||
"emptyTable": "Aucune donnée disponible dans le tableau",
|
||||
"info": "Affichage de _START_ à _END_ sur _TOTAL_ entrées",
|
||||
"infoEmpty": "Affichage de 0 à 0 sur 0 entrées",
|
||||
"infoFiltered": "(filtrées depuis un total de _MAX_ entrées)",
|
||||
"lengthMenu": "Afficher _MENU_ entrées",
|
||||
"loadingRecords": "Chargement...",
|
||||
"processing": "Traitement...",
|
||||
"search": "Rechercher:",
|
||||
"zeroRecords": "Aucune entrée correspondante trouvée",
|
||||
"paginate": {
|
||||
"next": "Suivante",
|
||||
"previous": "Précédente"
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
@ -1,14 +0,0 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block app_content %}
|
||||
|
||||
<h2>Erreur !</h2>
|
||||
|
||||
{{ e }}
|
||||
|
||||
<p>
|
||||
<a href="{{ url_for('entreprises.index') }}">Retour</a>
|
||||
</p>
|
||||
|
||||
{% endblock %}
|
14
app/templates/entreprises/error.j2
Normal file
14
app/templates/entreprises/error.j2
Normal file
@ -0,0 +1,14 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends 'base.j2' %}
|
||||
|
||||
{% block app_content %}
|
||||
|
||||
<h2>Erreur !</h2>
|
||||
|
||||
{{ e }}
|
||||
|
||||
<p>
|
||||
<a href="{{ url_for('entreprises.index') }}">Retour</a>
|
||||
</p>
|
||||
|
||||
{% endblock %}
|
@ -1,227 +0,0 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block styles %}
|
||||
{{super()}}
|
||||
<script src="/ScoDoc/static/jQuery/jquery-1.12.4.min.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/ScoDoc/static/DataTables/datatables.min.css">
|
||||
<script type="text/javascript" charset="utf8" src="/ScoDoc/static/DataTables/datatables.min.js"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block app_content %}
|
||||
<div class="container">
|
||||
<ul class="breadcrumbs">
|
||||
<li class="breadcrumbs_item">
|
||||
<a href="{{ url_for('entreprises.index') }}" class="breadcrumbs_link">Entreprises</a>
|
||||
</li>
|
||||
<li class="breadcrumbs_item">
|
||||
<a href="" class="breadcrumbs_link breadcrumbs_link-active">Fiche entreprise</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{% if logs %}
|
||||
<div class="container">
|
||||
<h3>Dernières opérations sur cette fiche <a href="{{ url_for('entreprises.logs_entreprise', entreprise_id=entreprise.id) }}">Voir tout</a></h3>
|
||||
<ul>
|
||||
{% for log in logs %}
|
||||
<li>
|
||||
<span style="margin-right: 10px;">{{ log.date.strftime('%d %b %Hh%M') }}</span>
|
||||
<span>{{ log.text|safe }} par {{ log.authenticated_user|get_nomcomplet_by_username }}</span>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="container fiche-entreprise">
|
||||
<h2>Fiche entreprise - {{ entreprise.nom }} ({{ entreprise.siret }})</h2>
|
||||
|
||||
{% if not entreprise.active %}
|
||||
<div class="info-active">
|
||||
La fiche entreprise est désactivée<br>
|
||||
{% if entreprise.notes_active != "" %}
|
||||
Notes : {{ entreprise.notes_active }}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="entreprise">
|
||||
<div>
|
||||
SIRET {% if entreprise.siret_provisoire %}provisoire{% endif %} : {{ entreprise.siret }}<br>
|
||||
Nom : {{ entreprise.nom }}<br>
|
||||
Adresse : {{ entreprise.adresse }}<br>
|
||||
Code postal : {{ entreprise.codepostal }}<br>
|
||||
Ville : {{ entreprise.ville }}<br>
|
||||
Pays : {{ entreprise.pays }}<br>
|
||||
{% if entreprise.association %}
|
||||
Association
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %}
|
||||
<div>
|
||||
Taxe d'apprentissage<br>
|
||||
<a class="btn btn-primary" href="{{ url_for('entreprises.add_taxe_apprentissage', entreprise_id=entreprise.id) }}">Ajouter taxe apprentissage</a>
|
||||
<div class="taxe-apprentissage">
|
||||
<ul id="liste-taxes-apprentissages">
|
||||
{% if not taxes|check_taxe_now %}
|
||||
<li>année actuelle : non versée</li>
|
||||
{% endif %}
|
||||
{% for taxe in taxes %}
|
||||
<li>
|
||||
<a href="{{ url_for('entreprises.delete_taxe_apprentissage', entreprise_id=entreprise.id, taxe_id=taxe.id) }}"><img title="Supprimer taxe d'apprentissage" alt="supprimer" width="10" height="9" border="0" src="/ScoDoc/static/icons/delete_small_img.png" /></a>
|
||||
<a href="{{ url_for('entreprises.edit_taxe_apprentissage', entreprise_id=entreprise.id, taxe_id=taxe.id) }}">{{ taxe.annee }}</a> : {{ taxe.montant }} euros {% if taxe.notes %}- {{ taxe.notes}} {% endif %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %}
|
||||
<a class="btn btn-primary" href="{{ url_for('entreprises.edit_entreprise', entreprise_id=entreprise.id) }}">Modifier</a>
|
||||
{% if entreprise.active %}
|
||||
<a class="btn btn-danger" href="{{ url_for('entreprises.fiche_entreprise_desactiver', entreprise_id=entreprise.id) }}">Désactiver</a>
|
||||
{% else %}
|
||||
<a class="btn btn-success" href="{{ url_for('entreprises.fiche_entreprise_activer', entreprise_id=entreprise.id) }}">Activer</a>
|
||||
{% endif %}
|
||||
<a class="btn btn-primary" href="{{ url_for('entreprises.add_site', entreprise_id=entreprise.id) }}">Ajouter site</a>
|
||||
<a class="btn btn-primary" href="{{ url_for('entreprises.add_offre', entreprise_id=entreprise.id) }}">Ajouter offre</a>
|
||||
{% endif %}
|
||||
<a class="btn btn-primary" href="{{ url_for('entreprises.contacts', entreprise_id=entreprise.id) }}">Liste contacts</a>
|
||||
<a class="btn btn-primary" href="{{ url_for('entreprises.offres_expirees', entreprise_id=entreprise.id) }}">Voir les offres expirées</a>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="sites-et-offres">
|
||||
{% if entreprise.sites %}
|
||||
<div>
|
||||
<h3>Sites</h3>
|
||||
{% for site in entreprise.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) %}
|
||||
<div>
|
||||
<a class="btn btn-primary" href="{{ url_for('entreprises.edit_site', entreprise_id=entreprise.id, site_id=site.id) }}">Modifier</a>
|
||||
<a class="btn btn-primary" href="{{ url_for('entreprises.add_correspondant', entreprise_id=entreprise.id, site_id=site.id) }}">Ajouter correspondant</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesCorrespondants, None) %}
|
||||
{% for correspondant in site.correspondants %}
|
||||
{% include 'entreprises/_correspondant.html' %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if offres %}
|
||||
<div>
|
||||
<h3>Offres - <a href="{{ url_for('entreprises.offres_expirees', entreprise_id=entreprise.id) }}">Voir les offres expirées</a></h3>
|
||||
{% for offre, files, offre_depts, correspondant in offres %}
|
||||
{% include 'entreprises/_offre.html' %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 10px;">
|
||||
<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', entreprise_id=entreprise.id) }}" style="margin-bottom:10px;">Ajouter stage ou apprentissage</a>
|
||||
{% endif %}
|
||||
<table id="table-stages-apprentissages">
|
||||
<thead>
|
||||
<tr>
|
||||
<td data-priority="3">Date début</td>
|
||||
<td data-priority="4">Date fin</td>
|
||||
<td data-priority="5">Durée</td>
|
||||
<td data-priority="2">Type</td>
|
||||
<td data-priority="1">Étudiant</td>
|
||||
<td data-priority="6">Formation</td>
|
||||
<td data-priority="7">Notes</td>
|
||||
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %}
|
||||
<td data-priority="3">Action</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for stage_apprentissage, etudiant in stages_apprentissages %}
|
||||
<tr>
|
||||
<td>{{ stage_apprentissage.date_debut.strftime('%d/%m/%Y') }}</td>
|
||||
<td>{{ stage_apprentissage.date_fin.strftime('%d/%m/%Y') }}</td>
|
||||
<td>{{ (stage_apprentissage.date_fin-stage_apprentissage.date_debut).days//7 }} semaines</td>
|
||||
<td>{{ stage_apprentissage.type_offre }}</td>
|
||||
<td><a href="{{ url_for('scolar.ficheEtud', scodoc_dept=etudiant.dept_id|get_dept_acronym, etudid=stage_apprentissage.etudid) }}">{{ etudiant.nom|format_nom }} {{ etudiant.prenom|format_prenom }}</a></td>
|
||||
<td>{% if stage_apprentissage.formation_text %}{{ stage_apprentissage.formation_text }}{% endif %}</td>
|
||||
<td>{{ stage_apprentissage.notes }}</td>
|
||||
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %}
|
||||
<td>
|
||||
<div class="btn-group">
|
||||
<a class="btn btn-default dropdown-toggle" data-toggle="dropdown" href="#">Action
|
||||
<span class="caret"></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu pull-left">
|
||||
<li><a href="{{ url_for('entreprises.edit_stage_apprentissage', entreprise_id=entreprise.id, stage_apprentissage_id=stage_apprentissage.id) }}">Modifier</a></li>
|
||||
<li><a href="{{ url_for('entreprises.delete_stage_apprentissage', entreprise_id=entreprise.id, stage_apprentissage_id=stage_apprentissage.id) }}" style="color:red">Supprimer</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td>Date début</td>
|
||||
<td>Date fin</td>
|
||||
<td>Durée</td>
|
||||
<td>Type</td>
|
||||
<td>Étudiant</td>
|
||||
<td>Formation</td>
|
||||
<td>Notes</td>
|
||||
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %}
|
||||
<td>Action</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
let table = new DataTable('#table-stages-apprentissages',
|
||||
{
|
||||
"autoWidth": false,
|
||||
"responsive": {
|
||||
"details": true
|
||||
},
|
||||
"pageLength": 10,
|
||||
"language": {
|
||||
"emptyTable": "Aucune donnée disponible dans le tableau",
|
||||
"info": "Affichage de _START_ à _END_ sur _TOTAL_ entrées",
|
||||
"infoEmpty": "Affichage de 0 à 0 sur 0 entrées",
|
||||
"infoFiltered": "(filtrées depuis un total de _MAX_ entrées)",
|
||||
"lengthMenu": "Afficher _MENU_ entrées",
|
||||
"loadingRecords": "Chargement...",
|
||||
"processing": "Traitement...",
|
||||
"search": "Rechercher:",
|
||||
"zeroRecords": "Aucune entrée correspondante trouvée",
|
||||
"paginate": {
|
||||
"next": "Suivante",
|
||||
"previous": "Précédente"
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
253
app/templates/entreprises/fiche_entreprise.j2
Normal file
253
app/templates/entreprises/fiche_entreprise.j2
Normal file
@ -0,0 +1,253 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends 'base.j2' %}
|
||||
|
||||
{% block styles %}
|
||||
{{super()}}
|
||||
<script src="/ScoDoc/static/jQuery/jquery-1.12.4.min.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/ScoDoc/static/DataTables/datatables.min.css">
|
||||
<script type="text/javascript" charset="utf8" src="/ScoDoc/static/DataTables/datatables.min.js"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block app_content %}
|
||||
<div class="container">
|
||||
<ul class="breadcrumbs">
|
||||
<li class="breadcrumbs_item">
|
||||
<a href="{{ url_for('entreprises.index') }}" class="breadcrumbs_link">Entreprises</a>
|
||||
</li>
|
||||
<li class="breadcrumbs_item">
|
||||
<a href="" class="breadcrumbs_link breadcrumbs_link-active">Fiche entreprise</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{% if logs %}
|
||||
<div class="container">
|
||||
<h3>Dernières opérations sur cette fiche <a
|
||||
href="{{ url_for('entreprises.logs_entreprise', entreprise_id=entreprise.id) }}">Voir tout</a></h3>
|
||||
<ul>
|
||||
{% for log in logs %}
|
||||
<li>
|
||||
<span style="margin-right: 10px;">{{ log.date.strftime('%d %b %Hh%M') }}</span>
|
||||
<span>{{ log.text|safe }} par {{ log.authenticated_user|get_nomcomplet_by_username }}</span>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="container fiche-entreprise">
|
||||
<h2>Fiche entreprise - {{ entreprise.nom }} ({{ entreprise.siret }})</h2>
|
||||
|
||||
{% if not entreprise.active %}
|
||||
<div class="info-active">
|
||||
La fiche entreprise est désactivée<br>
|
||||
{% if entreprise.notes_active != "" %}
|
||||
Notes : {{ entreprise.notes_active }}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="entreprise">
|
||||
<div>
|
||||
SIRET {% if entreprise.siret_provisoire %}provisoire{% endif %} : {{ entreprise.siret }}<br>
|
||||
Nom : {{ entreprise.nom }}<br>
|
||||
Adresse : {{ entreprise.adresse }}<br>
|
||||
Code postal : {{ entreprise.codepostal }}<br>
|
||||
Ville : {{ entreprise.ville }}<br>
|
||||
Pays : {{ entreprise.pays }}<br>
|
||||
{% if entreprise.association %}
|
||||
Association
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %}
|
||||
<div>
|
||||
Taxe d'apprentissage<br>
|
||||
<a class="btn btn-primary"
|
||||
href="{{ url_for('entreprises.add_taxe_apprentissage', entreprise_id=entreprise.id) }}">Ajouter taxe
|
||||
apprentissage</a>
|
||||
<div class="taxe-apprentissage">
|
||||
<ul id="liste-taxes-apprentissages">
|
||||
{% if not taxes|check_taxe_now %}
|
||||
<li>année actuelle : non versée</li>
|
||||
{% endif %}
|
||||
{% for taxe in taxes %}
|
||||
<li>
|
||||
<a
|
||||
href="{{ url_for('entreprises.delete_taxe_apprentissage', entreprise_id=entreprise.id, taxe_id=taxe.id) }}"><img
|
||||
title="Supprimer taxe d'apprentissage" alt="supprimer" width="10" height="9" border="0"
|
||||
src="/ScoDoc/static/icons/delete_small_img.png" /></a>
|
||||
<a
|
||||
href="{{ url_for('entreprises.edit_taxe_apprentissage', entreprise_id=entreprise.id, taxe_id=taxe.id) }}">{{
|
||||
taxe.annee }}</a> : {{ taxe.montant }} euros {% if taxe.notes %}- {{ taxe.notes}} {% endif
|
||||
%}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %}
|
||||
<a class="btn btn-primary"
|
||||
href="{{ url_for('entreprises.edit_entreprise', entreprise_id=entreprise.id) }}">Modifier</a>
|
||||
{% if entreprise.active %}
|
||||
<a class="btn btn-danger"
|
||||
href="{{ url_for('entreprises.fiche_entreprise_desactiver', entreprise_id=entreprise.id) }}">Désactiver</a>
|
||||
{% else %}
|
||||
<a class="btn btn-success"
|
||||
href="{{ url_for('entreprises.fiche_entreprise_activer', entreprise_id=entreprise.id) }}">Activer</a>
|
||||
{% endif %}
|
||||
<a class="btn btn-primary" href="{{ url_for('entreprises.add_site', entreprise_id=entreprise.id) }}">Ajouter
|
||||
site</a>
|
||||
<a class="btn btn-primary" href="{{ url_for('entreprises.add_offre', entreprise_id=entreprise.id) }}">Ajouter
|
||||
offre</a>
|
||||
{% endif %}
|
||||
<a class="btn btn-primary" href="{{ url_for('entreprises.contacts', entreprise_id=entreprise.id) }}">Liste
|
||||
contacts</a>
|
||||
<a class="btn btn-primary" href="{{ url_for('entreprises.offres_expirees', entreprise_id=entreprise.id) }}">Voir
|
||||
les offres expirées</a>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="sites-et-offres">
|
||||
{% if entreprise.sites %}
|
||||
<div>
|
||||
<h3>Sites</h3>
|
||||
{% for site in entreprise.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) %}
|
||||
<div>
|
||||
<a class="btn btn-primary"
|
||||
href="{{ url_for('entreprises.edit_site', entreprise_id=entreprise.id, site_id=site.id) }}">Modifier</a>
|
||||
<a class="btn btn-primary"
|
||||
href="{{ url_for('entreprises.add_correspondant', entreprise_id=entreprise.id, site_id=site.id) }}">Ajouter
|
||||
correspondant</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesCorrespondants, None) %}
|
||||
{% for correspondant in site.correspondants %}
|
||||
{% include 'entreprises/_correspondant.html' %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if offres %}
|
||||
<div>
|
||||
<h3>Offres - <a href="{{ url_for('entreprises.offres_expirees', entreprise_id=entreprise.id) }}">Voir les
|
||||
offres expirées</a></h3>
|
||||
{% for offre, files, offre_depts, correspondant in offres %}
|
||||
{% include 'entreprises/_offre.html' %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 10px;">
|
||||
<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', entreprise_id=entreprise.id) }}"
|
||||
style="margin-bottom:10px;">Ajouter stage ou apprentissage</a>
|
||||
{% endif %}
|
||||
<table id="table-stages-apprentissages">
|
||||
<thead>
|
||||
<tr>
|
||||
<td data-priority="3">Date début</td>
|
||||
<td data-priority="4">Date fin</td>
|
||||
<td data-priority="5">Durée</td>
|
||||
<td data-priority="2">Type</td>
|
||||
<td data-priority="1">Étudiant</td>
|
||||
<td data-priority="6">Formation</td>
|
||||
<td data-priority="7">Notes</td>
|
||||
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %}
|
||||
<td data-priority="3">Action</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for stage_apprentissage, etudiant in stages_apprentissages %}
|
||||
<tr>
|
||||
<td>{{ stage_apprentissage.date_debut.strftime('%d/%m/%Y') }}</td>
|
||||
<td>{{ stage_apprentissage.date_fin.strftime('%d/%m/%Y') }}</td>
|
||||
<td>{{ (stage_apprentissage.date_fin-stage_apprentissage.date_debut).days//7 }} semaines</td>
|
||||
<td>{{ stage_apprentissage.type_offre }}</td>
|
||||
<td><a
|
||||
href="{{ url_for('scolar.ficheEtud', scodoc_dept=etudiant.dept_id|get_dept_acronym, etudid=stage_apprentissage.etudid) }}">{{
|
||||
etudiant.nom|format_nom }} {{ etudiant.prenom|format_prenom }}</a></td>
|
||||
<td>{% if stage_apprentissage.formation_text %}{{ stage_apprentissage.formation_text }}{% endif %}</td>
|
||||
<td>{{ stage_apprentissage.notes }}</td>
|
||||
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %}
|
||||
<td>
|
||||
<div class="btn-group">
|
||||
<a class="btn btn-default dropdown-toggle" data-toggle="dropdown" href="#">Action
|
||||
<span class="caret"></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu pull-left">
|
||||
<li><a
|
||||
href="{{ url_for('entreprises.edit_stage_apprentissage', entreprise_id=entreprise.id, stage_apprentissage_id=stage_apprentissage.id) }}">Modifier</a>
|
||||
</li>
|
||||
<li><a href="{{ url_for('entreprises.delete_stage_apprentissage', entreprise_id=entreprise.id, stage_apprentissage_id=stage_apprentissage.id) }}"
|
||||
style="color:red">Supprimer</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td>Date début</td>
|
||||
<td>Date fin</td>
|
||||
<td>Durée</td>
|
||||
<td>Type</td>
|
||||
<td>Étudiant</td>
|
||||
<td>Formation</td>
|
||||
<td>Notes</td>
|
||||
{% if current_user.has_permission(current_user.Permission.RelationsEntreprisesChange, None) %}
|
||||
<td>Action</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
let table = new DataTable('#table-stages-apprentissages',
|
||||
{
|
||||
"autoWidth": false,
|
||||
"responsive": {
|
||||
"details": true
|
||||
},
|
||||
"pageLength": 10,
|
||||
"language": {
|
||||
"emptyTable": "Aucune donnée disponible dans le tableau",
|
||||
"info": "Affichage de _START_ à _END_ sur _TOTAL_ entrées",
|
||||
"infoEmpty": "Affichage de 0 à 0 sur 0 entrées",
|
||||
"infoFiltered": "(filtrées depuis un total de _MAX_ entrées)",
|
||||
"lengthMenu": "Afficher _MENU_ entrées",
|
||||
"loadingRecords": "Chargement...",
|
||||
"processing": "Traitement...",
|
||||
"search": "Rechercher:",
|
||||
"zeroRecords": "Aucune entrée correspondante trouvée",
|
||||
"paginate": {
|
||||
"next": "Suivante",
|
||||
"previous": "Précédente"
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
@ -1,84 +0,0 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block app_content %}
|
||||
<div class="container">
|
||||
<ul class="breadcrumbs">
|
||||
<li class="breadcrumbs_item">
|
||||
<a href="{{ url_for('entreprises.validation') }}" class="breadcrumbs_link">Entreprises</a>
|
||||
</li>
|
||||
<li class="breadcrumbs_item">
|
||||
<a href="" class="breadcrumbs_link breadcrumbs_link-active">Fiche entreprise</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<h2>Fiche entreprise - {{ entreprise.nom }} ({{ entreprise.siret }})</h2>
|
||||
|
||||
<div class="entreprise">
|
||||
<div>
|
||||
SIRET {% if entreprise.siret_provisoire %}provisoire{% endif %} : {{ entreprise.siret }}<br>
|
||||
Nom : {{ entreprise.nom }}<br>
|
||||
Adresse : {{ entreprise.adresse }}<br>
|
||||
Code postal : {{ entreprise.codepostal }}<br>
|
||||
Ville : {{ entreprise.ville }}<br>
|
||||
Pays : {{ entreprise.pays }}<br>
|
||||
{% if entreprise.association %}
|
||||
Association
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sites-et-offres">
|
||||
{% if entreprise.sites %}
|
||||
<div>
|
||||
<h3>Sites</h3>
|
||||
{% for site in entreprise.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.RelationsEntreprisesCorrespondants, None) %}
|
||||
{% for correspondant in site.correspondants %}
|
||||
<div class="correspondant">
|
||||
<div>
|
||||
Civilité : {{ correspondant.civilite|get_civilité }}<br>
|
||||
Nom : {{ correspondant.nom }}<br>
|
||||
Prénom : {{ correspondant.prenom }}<br>
|
||||
{% if correspondant.telephone %}
|
||||
Téléphone : {{ correspondant.telephone }}<br>
|
||||
{% endif %}
|
||||
{% if correspondant.mail %}
|
||||
Mail : {{ correspondant.mail }}<br>
|
||||
{% endif %}
|
||||
{% if correspondant.poste %}
|
||||
Poste : {{ correspondant.poste }}<br>
|
||||
{% endif %}
|
||||
{% if correspondant.service %}
|
||||
Service : {{ correspondant.service }}<br>
|
||||
{% endif %}
|
||||
{% if correspondant.origine %}
|
||||
Origine : {{ correspondant.origine }}<br>
|
||||
{% endif %}
|
||||
{% if correspondant.notes %}
|
||||
Notes : {{ correspondant.notes }}<br>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<a class="btn btn-success" href="{{ url_for('entreprises.validate_entreprise', entreprise_id=entreprise.id) }}">Valider</a>
|
||||
<a class="btn btn-danger" href="{{ url_for('entreprises.delete_validation_entreprise', entreprise_id=entreprise.id) }}">Supprimer</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
86
app/templates/entreprises/fiche_entreprise_validation.j2
Normal file
86
app/templates/entreprises/fiche_entreprise_validation.j2
Normal file
@ -0,0 +1,86 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends 'base.j2' %}
|
||||
|
||||
{% block app_content %}
|
||||
<div class="container">
|
||||
<ul class="breadcrumbs">
|
||||
<li class="breadcrumbs_item">
|
||||
<a href="{{ url_for('entreprises.validation') }}" class="breadcrumbs_link">Entreprises</a>
|
||||
</li>
|
||||
<li class="breadcrumbs_item">
|
||||
<a href="" class="breadcrumbs_link breadcrumbs_link-active">Fiche entreprise</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<h2>Fiche entreprise - {{ entreprise.nom }} ({{ entreprise.siret }})</h2>
|
||||
|
||||
<div class="entreprise">
|
||||
<div>
|
||||
SIRET {% if entreprise.siret_provisoire %}provisoire{% endif %} : {{ entreprise.siret }}<br>
|
||||
Nom : {{ entreprise.nom }}<br>
|
||||
Adresse : {{ entreprise.adresse }}<br>
|
||||
Code postal : {{ entreprise.codepostal }}<br>
|
||||
Ville : {{ entreprise.ville }}<br>
|
||||
Pays : {{ entreprise.pays }}<br>
|
||||
{% if entreprise.association %}
|
||||
Association
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sites-et-offres">
|
||||
{% if entreprise.sites %}
|
||||
<div>
|
||||
<h3>Sites</h3>
|
||||
{% for site in entreprise.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.RelationsEntreprisesCorrespondants, None) %}
|
||||
{% for correspondant in site.correspondants %}
|
||||
<div class="correspondant">
|
||||
<div>
|
||||
Civilité : {{ correspondant.civilite|get_civilité }}<br>
|
||||
Nom : {{ correspondant.nom }}<br>
|
||||
Prénom : {{ correspondant.prenom }}<br>
|
||||
{% if correspondant.telephone %}
|
||||
Téléphone : {{ correspondant.telephone }}<br>
|
||||
{% endif %}
|
||||
{% if correspondant.mail %}
|
||||
Mail : {{ correspondant.mail }}<br>
|
||||
{% endif %}
|
||||
{% if correspondant.poste %}
|
||||
Poste : {{ correspondant.poste }}<br>
|
||||
{% endif %}
|
||||
{% if correspondant.service %}
|
||||
Service : {{ correspondant.service }}<br>
|
||||
{% endif %}
|
||||
{% if correspondant.origine %}
|
||||
Origine : {{ correspondant.origine }}<br>
|
||||
{% endif %}
|
||||
{% if correspondant.notes %}
|
||||
Notes : {{ correspondant.notes }}<br>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<a class="btn btn-success"
|
||||
href="{{ url_for('entreprises.validate_entreprise', entreprise_id=entreprise.id) }}">Valider</a>
|
||||
<a class="btn btn-danger"
|
||||
href="{{ url_for('entreprises.delete_validation_entreprise', entreprise_id=entreprise.id) }}">Supprimer</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
@ -1,62 +0,0 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends 'base.html' %}
|
||||
{% import 'bootstrap/wtf.html' as wtf %}
|
||||
|
||||
{% block styles %}
|
||||
{{super()}}
|
||||
<link type="text/css" rel="stylesheet" href="/ScoDoc/static/css/autosuggest_inquisitor.css" />
|
||||
<script src="/ScoDoc/static/libjs/AutoSuggest.js"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block app_content %}
|
||||
<h1>{{ title }}</h1>
|
||||
<br>
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<p>
|
||||
(*) champs requis
|
||||
</p>
|
||||
{{ wtf.quick_form(form, novalidate=True) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
{# pour les formulaires offre #}
|
||||
var champ_depts = document.getElementById("depts")
|
||||
if (champ_depts) {
|
||||
var closest_form_control = champ_depts.closest(".form-control")
|
||||
closest_form_control.classList.remove("form-control")
|
||||
}
|
||||
|
||||
if(document.getElementById("expiration_date") && document.getElementById("expiration_date").value === "")
|
||||
expiration()
|
||||
|
||||
if(document.getElementById("type_offre"))
|
||||
document.getElementById("type_offre").addEventListener("change", expiration);
|
||||
|
||||
function expiration() {
|
||||
var date = new Date()
|
||||
var expiration = document.getElementById("expiration_date")
|
||||
var type_offre = document.getElementById("type_offre").value
|
||||
if (type_offre === "Alternance") {
|
||||
expiration.value = `${date.getFullYear() + 1}-01-01`
|
||||
} else {
|
||||
if(date.getMonth() + 1 < 8)
|
||||
expiration.value = `${date.getFullYear()}-08-01`
|
||||
else
|
||||
expiration.value = `${date.getFullYear() + 1}-08-01`
|
||||
}
|
||||
}
|
||||
|
||||
var responsables_options = {
|
||||
script: "/ScoDoc/entreprises/responsables?",
|
||||
varname: "term",
|
||||
json: true,
|
||||
noresults: "Valeur invalide !",
|
||||
minchars: 2,
|
||||
timeout: 60000
|
||||
};
|
||||
|
||||
var as_utilisateurs = new bsn.AutoSuggest('utilisateur', responsables_options);
|
||||
</script>
|
||||
{% endblock %}
|
62
app/templates/entreprises/form.j2
Normal file
62
app/templates/entreprises/form.j2
Normal file
@ -0,0 +1,62 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends 'base.j2' %}
|
||||
{% import 'bootstrap/wtf.html' as wtf %}
|
||||
|
||||
{% block styles %}
|
||||
{{super()}}
|
||||
<link type="text/css" rel="stylesheet" href="/ScoDoc/static/css/autosuggest_inquisitor.css" />
|
||||
<script src="/ScoDoc/static/libjs/AutoSuggest.js"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block app_content %}
|
||||
<h1>{{ title }}</h1>
|
||||
<br>
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<p>
|
||||
(*) champs requis
|
||||
</p>
|
||||
{{ wtf.quick_form(form, novalidate=True) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
{# pour les formulaires offre # }
|
||||
var champ_depts = document.getElementById("depts")
|
||||
if (champ_depts) {
|
||||
var closest_form_control = champ_depts.closest(".form-control")
|
||||
closest_form_control.classList.remove("form-control")
|
||||
}
|
||||
|
||||
if (document.getElementById("expiration_date") && document.getElementById("expiration_date").value === "")
|
||||
expiration()
|
||||
|
||||
if (document.getElementById("type_offre"))
|
||||
document.getElementById("type_offre").addEventListener("change", expiration);
|
||||
|
||||
function expiration() {
|
||||
var date = new Date()
|
||||
var expiration = document.getElementById("expiration_date")
|
||||
var type_offre = document.getElementById("type_offre").value
|
||||
if (type_offre === "Alternance") {
|
||||
expiration.value = `${date.getFullYear() + 1}-01-01`
|
||||
} else {
|
||||
if (date.getMonth() + 1 < 8)
|
||||
expiration.value = `${date.getFullYear()}-08-01`
|
||||
else
|
||||
expiration.value = `${date.getFullYear() + 1}-08-01`
|
||||
}
|
||||
}
|
||||
|
||||
var responsables_options = {
|
||||
script: "/ScoDoc/entreprises/responsables?",
|
||||
varname: "term",
|
||||
json: true,
|
||||
noresults: "Valeur invalide !",
|
||||
minchars: 2,
|
||||
timeout: 60000
|
||||
};
|
||||
|
||||
var as_utilisateurs = new bsn.AutoSuggest('utilisateur', responsables_options);
|
||||
</script>
|
||||
{% endblock %}
|
@ -1,91 +0,0 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends 'base.html' %}
|
||||
{% import 'bootstrap/wtf.html' as wtf %}
|
||||
|
||||
{% block styles %}
|
||||
{{super()}}
|
||||
{% endblock %}
|
||||
|
||||
{% block app_content %}
|
||||
<h1>{{ title }}</h1>
|
||||
<br>
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<p>
|
||||
(*) champs requis
|
||||
</p>
|
||||
<form method="POST" action="" novalidate>
|
||||
{{ form.hidden_tag() }}
|
||||
{{ form.correspondants.label }}
|
||||
{% for subfield in form.correspondants %}
|
||||
{% if subfield.errors %}
|
||||
<p class="title-form-error">Formulaire {{ subfield.label.text }}</p>
|
||||
{% endif %}
|
||||
{% for subsubfield in subfield %}
|
||||
{% if subsubfield.errors %}
|
||||
{% for error in subsubfield.errors %}
|
||||
<p class="help-block form-error">{{ error }}</p>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
{{ form.correspondants }}
|
||||
<div style="margin-bottom: 10px;">
|
||||
<button class="btn btn-default" id="add-correspondant-field">Ajouter un correspondant</button>
|
||||
{{ form.submit(class_="btn btn-default") }}
|
||||
{{ form.cancel(class_="btn btn-default") }}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<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) {
|
||||
let addCorrespondantFieldBtn = document.getElementById('add-correspondant-field');
|
||||
addCorrespondantFieldBtn.addEventListener('click', function(e){
|
||||
e.preventDefault();
|
||||
let allCorrepondantsFieldWrapper = document.getElementById('correspondants');
|
||||
let allCorrepondantsField = allCorrepondantsFieldWrapper.getElementsByTagName('input');
|
||||
let correspondantInputIds = []
|
||||
let csrf_token = document.getElementById('csrf_token').value;
|
||||
for(let i = 0; i < allCorrepondantsField.length; i++) {
|
||||
correspondantInputIds.push(parseInt(allCorrepondantsField[i].name.split('-')[1]));
|
||||
}
|
||||
let newFieldName = `correspondants-${Math.max(...correspondantInputIds) + 1}`;
|
||||
allCorrepondantsFieldWrapper.insertAdjacentHTML('beforeend',`
|
||||
<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>
|
||||
{% endblock %}
|
91
app/templates/entreprises/form_ajout_correspondants.j2
Normal file
91
app/templates/entreprises/form_ajout_correspondants.j2
Normal file
@ -0,0 +1,91 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends 'base.j2' %}
|
||||
{% import 'bootstrap/wtf.html' as wtf %}
|
||||
|
||||
{% block styles %}
|
||||
{{super()}}
|
||||
{% endblock %}
|
||||
|
||||
{% block app_content %}
|
||||
<h1>{{ title }}</h1>
|
||||
<br>
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<p>
|
||||
(*) champs requis
|
||||
</p>
|
||||
<form method="POST" action="" novalidate>
|
||||
{{ form.hidden_tag() }}
|
||||
{{ form.correspondants.label }}
|
||||
{% for subfield in form.correspondants %}
|
||||
{% if subfield.errors %}
|
||||
<p class="title-form-error">Formulaire {{ subfield.label.text }}</p>
|
||||
{% endif %}
|
||||
{% for subsubfield in subfield %}
|
||||
{% if subsubfield.errors %}
|
||||
{% for error in subsubfield.errors %}
|
||||
<p class="help-block form-error">{{ error }}</p>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
{{ form.correspondants }}
|
||||
<div style="margin-bottom: 10px;">
|
||||
<button class="btn btn-default" id="add-correspondant-field">Ajouter un correspondant</button>
|
||||
{{ form.submit(class_="btn btn-default") }}
|
||||
{{ form.cancel(class_="btn btn-default") }}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<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) {
|
||||
let addCorrespondantFieldBtn = document.getElementById('add-correspondant-field');
|
||||
addCorrespondantFieldBtn.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
let allCorrepondantsFieldWrapper = document.getElementById('correspondants');
|
||||
let allCorrepondantsField = allCorrepondantsFieldWrapper.getElementsByTagName('input');
|
||||
let correspondantInputIds = []
|
||||
let csrf_token = document.getElementById('csrf_token').value;
|
||||
for (let i = 0; i < allCorrepondantsField.length; i++) {
|
||||
correspondantInputIds.push(parseInt(allCorrepondantsField[i].name.split('-')[1]));
|
||||
}
|
||||
let newFieldName = `correspondants-${Math.max(...correspondantInputIds) + 1}`;
|
||||
allCorrepondantsFieldWrapper.insertAdjacentHTML('beforeend', `
|
||||
<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>
|
||||
{% endblock %}
|
@ -1,58 +0,0 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends 'base.html' %}
|
||||
{% import 'bootstrap/wtf.html' as wtf %}
|
||||
|
||||
{% block app_content %}
|
||||
<h1>Ajout entreprise</h1>
|
||||
<br>
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<p>
|
||||
Les champs s'auto complète selon le SIRET<br>
|
||||
(*) champs requis
|
||||
</p>
|
||||
{{ wtf.quick_form(form, novalidate=True) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
{# ajout margin-bottom sur le champ pays #}
|
||||
var champ_pays = document.getElementById("pays")
|
||||
if (champ_pays !== null) {
|
||||
var closest_form_group = champ_pays.closest(".form-group")
|
||||
closest_form_group.style.marginBottom = "50px"
|
||||
}
|
||||
|
||||
document.getElementById("siret").addEventListener("keyup", autocomplete);
|
||||
|
||||
function autocomplete() {
|
||||
var input = document.getElementById("siret").value.replaceAll(" ", "")
|
||||
if(input.length >= 14) {
|
||||
fetch("https://entreprise.data.gouv.fr/api/sirene/v1/siret/" + input)
|
||||
.then(response => {
|
||||
if(response.ok)
|
||||
return response.json()
|
||||
else {
|
||||
emptyForm()
|
||||
}
|
||||
})
|
||||
.then(response => fillForm(response))
|
||||
.catch(err => err)
|
||||
}
|
||||
}
|
||||
|
||||
function fillForm(response) {
|
||||
document.getElementById("nom_entreprise").value = response.etablissement.l1_normalisee
|
||||
document.getElementById("adresse").value = response.etablissement.l4_normalisee
|
||||
document.getElementById("codepostal").value = response.etablissement.code_postal
|
||||
document.getElementById("ville").value = response.etablissement.libelle_commune
|
||||
}
|
||||
|
||||
function emptyForm() {
|
||||
document.getElementById("nom_entreprise").value = ''
|
||||
document.getElementById("adresse").value = ''
|
||||
document.getElementById("codepostal").value = ''
|
||||
document.getElementById("ville").value = ''
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
58
app/templates/entreprises/form_ajout_entreprise.j2
Normal file
58
app/templates/entreprises/form_ajout_entreprise.j2
Normal file
@ -0,0 +1,58 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends 'base.j2' %}
|
||||
{% import 'bootstrap/wtf.html' as wtf %}
|
||||
|
||||
{% block app_content %}
|
||||
<h1>Ajout entreprise</h1>
|
||||
<br>
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<p>
|
||||
Les champs s'auto complète selon le SIRET<br>
|
||||
(*) champs requis
|
||||
</p>
|
||||
{{ wtf.quick_form(form, novalidate=True) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
{# ajout margin - bottom sur le champ pays # }
|
||||
var champ_pays = document.getElementById("pays")
|
||||
if (champ_pays !== null) {
|
||||
var closest_form_group = champ_pays.closest(".form-group")
|
||||
closest_form_group.style.marginBottom = "50px"
|
||||
}
|
||||
|
||||
document.getElementById("siret").addEventListener("keyup", autocomplete);
|
||||
|
||||
function autocomplete() {
|
||||
var input = document.getElementById("siret").value.replaceAll(" ", "")
|
||||
if (input.length >= 14) {
|
||||
fetch("https://entreprise.data.gouv.fr/api/sirene/v1/siret/" + input)
|
||||
.then(response => {
|
||||
if (response.ok)
|
||||
return response.json()
|
||||
else {
|
||||
emptyForm()
|
||||
}
|
||||
})
|
||||
.then(response => fillForm(response))
|
||||
.catch(err => err)
|
||||
}
|
||||
}
|
||||
|
||||
function fillForm(response) {
|
||||
document.getElementById("nom_entreprise").value = response.etablissement.l1_normalisee
|
||||
document.getElementById("adresse").value = response.etablissement.l4_normalisee
|
||||
document.getElementById("codepostal").value = response.etablissement.code_postal
|
||||
document.getElementById("ville").value = response.etablissement.libelle_commune
|
||||
}
|
||||
|
||||
function emptyForm() {
|
||||
document.getElementById("nom_entreprise").value = ''
|
||||
document.getElementById("adresse").value = ''
|
||||
document.getElementById("codepostal").value = ''
|
||||
document.getElementById("ville").value = ''
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
@ -1,36 +0,0 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends 'base.html' %}
|
||||
{% import 'bootstrap/wtf.html' as wtf %}
|
||||
|
||||
{% block styles %}
|
||||
{{super()}}
|
||||
<link type="text/css" rel="stylesheet" href="/ScoDoc/static/css/autosuggest_inquisitor.css" />
|
||||
<script src="/ScoDoc/static/libjs/AutoSuggest.js"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block app_content %}
|
||||
<h1>{{ title }}</h1>
|
||||
<br>
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<p>
|
||||
(*) champs requis
|
||||
</p>
|
||||
{{ wtf.quick_form(form, novalidate=True) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
window.onload = function(e) {
|
||||
var etudiants_options = {
|
||||
script: "/ScoDoc/entreprises/etudiants?",
|
||||
varname: "term",
|
||||
json: true,
|
||||
noresults: "Valeur invalide !",
|
||||
minchars: 2,
|
||||
timeout: 60000
|
||||
};
|
||||
var as_etudiants = new bsn.AutoSuggest('etudiant', etudiants_options);
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
36
app/templates/entreprises/form_ajout_stage_apprentissage.j2
Normal file
36
app/templates/entreprises/form_ajout_stage_apprentissage.j2
Normal file
@ -0,0 +1,36 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends 'base.j2' %}
|
||||
{% import 'bootstrap/wtf.html' as wtf %}
|
||||
|
||||
{% block styles %}
|
||||
{{super()}}
|
||||
<link type="text/css" rel="stylesheet" href="/ScoDoc/static/css/autosuggest_inquisitor.css" />
|
||||
<script src="/ScoDoc/static/libjs/AutoSuggest.js"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block app_content %}
|
||||
<h1>{{ title }}</h1>
|
||||
<br>
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<p>
|
||||
(*) champs requis
|
||||
</p>
|
||||
{{ wtf.quick_form(form, novalidate=True) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
window.onload = function (e) {
|
||||
var etudiants_options = {
|
||||
script: "/ScoDoc/entreprises/etudiants?",
|
||||
varname: "term",
|
||||
json: true,
|
||||
noresults: "Valeur invalide !",
|
||||
minchars: 2,
|
||||
timeout: 60000
|
||||
};
|
||||
var as_etudiants = new bsn.AutoSuggest('etudiant', etudiants_options);
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
@ -1,15 +0,0 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends 'base.html' %}
|
||||
{% import 'bootstrap/wtf.html' as wtf %}
|
||||
|
||||
{% block app_content %}
|
||||
<h1>{{ title }}</h1>
|
||||
<br>
|
||||
<div>{{ info_message }}</div>
|
||||
<br>
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
{{ wtf.quick_form(form) }}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
15
app/templates/entreprises/form_confirmation.j2
Normal file
15
app/templates/entreprises/form_confirmation.j2
Normal file
@ -0,0 +1,15 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends 'base.j2' %}
|
||||
{% import 'bootstrap/wtf.html' as wtf %}
|
||||
|
||||
{% block app_content %}
|
||||
<h1>{{ title }}</h1>
|
||||
<br>
|
||||
<div>{{ info_message }}</div>
|
||||
<br>
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
{{ wtf.quick_form(form) }}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
@ -1,88 +0,0 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends 'base.html' %}
|
||||
{% import 'bootstrap/wtf.html' as wtf %}
|
||||
|
||||
{% block styles %}
|
||||
{{super()}}
|
||||
<link type="text/css" rel="stylesheet" href="/ScoDoc/static/css/autosuggest_inquisitor.css" />
|
||||
<script src="/ScoDoc/static/libjs/AutoSuggest.js"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block app_content %}
|
||||
<h1>Envoyer une offre</h1>
|
||||
<br>
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<p>
|
||||
(*) champs requis
|
||||
</p>
|
||||
<form method="POST" action="" novalidate>
|
||||
{{ form.hidden_tag() }}
|
||||
{{ form.responsables.label }}
|
||||
{% for error in form.responsables.errors %}
|
||||
<p class="help-block form-error">{{ error }}</p>
|
||||
{% endfor %}
|
||||
{{ form.responsables }}
|
||||
<div style="margin-bottom: 10px;">
|
||||
<button class="btn btn-default" id="add-responsable-field">Ajouter un responsable</button>
|
||||
{{ form.submit(class_="btn btn-default") }}
|
||||
{{ form.cancel(class_="btn btn-default") }}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<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) {
|
||||
var responsables_options = {
|
||||
script: "/ScoDoc/entreprises/responsables?",
|
||||
varname: "term",
|
||||
json: true,
|
||||
noresults: "Valeur invalide !",
|
||||
minchars: 2,
|
||||
timeout: 60000
|
||||
};
|
||||
|
||||
let allResponsablesFieldWrapper = document.getElementById('responsables');
|
||||
let allResponsablesField = allResponsablesFieldWrapper.getElementsByTagName('input');
|
||||
for(let i = 0; i < allResponsablesField.length; i++) {
|
||||
new bsn.AutoSuggest(allResponsablesField[i].id, responsables_options);
|
||||
}
|
||||
|
||||
let addResponsableFieldBtn = document.getElementById('add-responsable-field');
|
||||
addResponsableFieldBtn.addEventListener('click', function(e){
|
||||
e.preventDefault();
|
||||
let allResponsablesFieldWrapper = document.getElementById('responsables');
|
||||
let allResponsablesField = allResponsablesFieldWrapper.getElementsByTagName('input');
|
||||
let responsableInputIds = []
|
||||
for(let i = 0; i < allResponsablesField.length; i++) {
|
||||
responsableInputIds.push(parseInt(allResponsablesField[i].name.split('-')[1]));
|
||||
}
|
||||
let newFieldName = `responsables-${Math.max(...responsableInputIds) + 1}`;
|
||||
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">
|
||||
<div class="btn btn-default btn-remove" onclick="deleteForm('${newFieldName}')">Retirer</div>
|
||||
</li>
|
||||
`);
|
||||
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>
|
||||
{% endblock %}
|
88
app/templates/entreprises/form_envoi_offre.j2
Normal file
88
app/templates/entreprises/form_envoi_offre.j2
Normal file
@ -0,0 +1,88 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends 'base.j2' %}
|
||||
{% import 'bootstrap/wtf.html' as wtf %}
|
||||
|
||||
{% block styles %}
|
||||
{{super()}}
|
||||
<link type="text/css" rel="stylesheet" href="/ScoDoc/static/css/autosuggest_inquisitor.css" />
|
||||
<script src="/ScoDoc/static/libjs/AutoSuggest.js"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block app_content %}
|
||||
<h1>Envoyer une offre</h1>
|
||||
<br>
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<p>
|
||||
(*) champs requis
|
||||
</p>
|
||||
<form method="POST" action="" novalidate>
|
||||
{{ form.hidden_tag() }}
|
||||
{{ form.responsables.label }}
|
||||
{% for error in form.responsables.errors %}
|
||||
<p class="help-block form-error">{{ error }}</p>
|
||||
{% endfor %}
|
||||
{{ form.responsables }}
|
||||
<div style="margin-bottom: 10px;">
|
||||
<button class="btn btn-default" id="add-responsable-field">Ajouter un responsable</button>
|
||||
{{ form.submit(class_="btn btn-default") }}
|
||||
{{ form.cancel(class_="btn btn-default") }}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<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) {
|
||||
var responsables_options = {
|
||||
script: "/ScoDoc/entreprises/responsables?",
|
||||
varname: "term",
|
||||
json: true,
|
||||
noresults: "Valeur invalide !",
|
||||
minchars: 2,
|
||||
timeout: 60000
|
||||
};
|
||||
|
||||
let allResponsablesFieldWrapper = document.getElementById('responsables');
|
||||
let allResponsablesField = allResponsablesFieldWrapper.getElementsByTagName('input');
|
||||
for (let i = 0; i < allResponsablesField.length; i++) {
|
||||
new bsn.AutoSuggest(allResponsablesField[i].id, responsables_options);
|
||||
}
|
||||
|
||||
let addResponsableFieldBtn = document.getElementById('add-responsable-field');
|
||||
addResponsableFieldBtn.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
let allResponsablesFieldWrapper = document.getElementById('responsables');
|
||||
let allResponsablesField = allResponsablesFieldWrapper.getElementsByTagName('input');
|
||||
let responsableInputIds = []
|
||||
for (let i = 0; i < allResponsablesField.length; i++) {
|
||||
responsableInputIds.push(parseInt(allResponsablesField[i].name.split('-')[1]));
|
||||
}
|
||||
let newFieldName = `responsables-${Math.max(...responsableInputIds) + 1}`;
|
||||
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">
|
||||
<div class="btn btn-default btn-remove" onclick="deleteForm('${newFieldName}')">Retirer</div>
|
||||
</li>
|
||||
`);
|
||||
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>
|
||||
{% endblock %}
|
@ -1,68 +0,0 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends 'base.html' %}
|
||||
{% import 'bootstrap/wtf.html' as wtf %}
|
||||
|
||||
{% block styles %}
|
||||
{{super()}}
|
||||
{% endblock %}
|
||||
|
||||
{% block app_content %}
|
||||
<h1>{{ title }}</h1>
|
||||
<br>
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<p>
|
||||
(*) champs requis
|
||||
</p>
|
||||
{{ wtf.quick_form(form, novalidate=True) }}
|
||||
</div>
|
||||
|
||||
<div id="sirene-data" class="col-md-5">
|
||||
<b>Informations de la base SIRENE</b>
|
||||
<div id="nom_entreprise_base"></div>
|
||||
<div id="adresse_base"></div>
|
||||
<div id="codepostal_base"></div>
|
||||
<div id="ville_base"></div>
|
||||
<a class="btn btn-primary" onclick="getData()">Copier</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var value = document.getElementById("siret").value;
|
||||
fetch("https://entreprise.data.gouv.fr/api/sirene/v1/siret/" + value)
|
||||
.then(response => {
|
||||
if(response.ok)
|
||||
return response.json()
|
||||
})
|
||||
.then(response => showSireneData(response))
|
||||
.catch(err => {
|
||||
document.getElementById("sirene-data").style.display = "none"
|
||||
return err
|
||||
})
|
||||
|
||||
function showSireneData(response) {
|
||||
document.getElementById("nom_entreprise_base").innerHTML = "Nom de l'entreprise: " + response.etablissement.l1_normalisee
|
||||
document.getElementById("adresse_base").innerHTML = "Adresse: " + response.etablissement.l4_normalisee
|
||||
document.getElementById("codepostal_base").innerHTML = "Code postal: " + response.etablissement.code_postal
|
||||
document.getElementById("ville_base").innerHTML = "Ville: " + response.etablissement.libelle_commune
|
||||
}
|
||||
|
||||
function getData() {
|
||||
var value = document.getElementById("siret").value;
|
||||
fetch("https://entreprise.data.gouv.fr/api/sirene/v1/siret/" + value)
|
||||
.then(response => {
|
||||
if(response.ok)
|
||||
return response.json()
|
||||
})
|
||||
.then(response => fillForm(response))
|
||||
.catch(err => err)
|
||||
}
|
||||
|
||||
function fillForm(response) {
|
||||
document.getElementById("nom").value = response.etablissement.l1_normalisee
|
||||
document.getElementById("adresse").value = response.etablissement.l4_normalisee
|
||||
document.getElementById("codepostal").value = response.etablissement.code_postal
|
||||
document.getElementById("ville").value = response.etablissement.libelle_commune
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user