forked from ScoDoc/ScoDoc
Update opolka/ScoDoc from ScoDoc/ScoDoc #2
144
app/api/jury.py
144
app/api/jury.py
@ -12,11 +12,20 @@ from flask_json import as_json
|
|||||||
from flask_login import login_required
|
from flask_login import login_required
|
||||||
|
|
||||||
import app
|
import app
|
||||||
from app.api import api_bp as bp, api_web_bp
|
from app import db, log
|
||||||
|
from app.api import api_bp as bp, api_web_bp, tools
|
||||||
from app.decorators import scodoc, permission_required
|
from app.decorators import scodoc, permission_required
|
||||||
from app.scodoc.sco_exceptions import ScoException
|
from app.scodoc.sco_exceptions import ScoException
|
||||||
from app.but import jury_but_results
|
from app.but import jury_but_results
|
||||||
from app.models import FormSemestre
|
from app.models import (
|
||||||
|
ApcValidationAnnee,
|
||||||
|
ApcValidationRCUE,
|
||||||
|
FormSemestre,
|
||||||
|
Identite,
|
||||||
|
ScolarAutorisationInscription,
|
||||||
|
ScolarFormSemestreValidation,
|
||||||
|
)
|
||||||
|
from app.scodoc import sco_cache
|
||||||
from app.scodoc.sco_permissions import Permission
|
from app.scodoc.sco_permissions import Permission
|
||||||
|
|
||||||
|
|
||||||
@ -36,3 +45,134 @@ def decisions_jury(formsemestre_id: int):
|
|||||||
return rows
|
return rows
|
||||||
else:
|
else:
|
||||||
raise ScoException("non implemente")
|
raise ScoException("non implemente")
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route(
|
||||||
|
"/etudiant/<int:etudid>/jury/validation_ue/<int:validation_id>/delete",
|
||||||
|
methods=["POST"],
|
||||||
|
)
|
||||||
|
@api_web_bp.route(
|
||||||
|
"/etudiant/<int:etudid>/jury/validation_ue/<int:validation_id>/delete",
|
||||||
|
methods=["POST"],
|
||||||
|
)
|
||||||
|
@login_required
|
||||||
|
@scodoc
|
||||||
|
@permission_required(Permission.ScoEtudInscrit)
|
||||||
|
@as_json
|
||||||
|
def validation_ue_delete(etudid: int, validation_id: int):
|
||||||
|
"Efface cette validation"
|
||||||
|
return _validation_ue_delete(etudid, validation_id)
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route(
|
||||||
|
"/etudiant/<int:etudid>/jury/validation_formsemestre/<int:validation_id>/delete",
|
||||||
|
methods=["POST"],
|
||||||
|
)
|
||||||
|
@api_web_bp.route(
|
||||||
|
"/etudiant/<int:etudid>/jury/validation_formsemestre/<int:validation_id>/delete",
|
||||||
|
methods=["POST"],
|
||||||
|
)
|
||||||
|
@login_required
|
||||||
|
@scodoc
|
||||||
|
@permission_required(Permission.ScoEtudInscrit)
|
||||||
|
@as_json
|
||||||
|
def validation_formsemestre_delete(etudid: int, validation_id: int):
|
||||||
|
"Efface cette validation"
|
||||||
|
# c'est la même chose (formations classiques)
|
||||||
|
return _validation_ue_delete(etudid, validation_id)
|
||||||
|
|
||||||
|
|
||||||
|
def _validation_ue_delete(etudid: int, validation_id: int):
|
||||||
|
"Efface cette validation (semestres classiques ou UEs)"
|
||||||
|
etud = tools.get_etud(etudid)
|
||||||
|
if etud is None:
|
||||||
|
return "étudiant inconnu", 404
|
||||||
|
validation = ScolarFormSemestreValidation.query.filter_by(
|
||||||
|
id=validation_id, etudid=etudid
|
||||||
|
).first_or_404()
|
||||||
|
log(f"validation_ue_delete: etuid={etudid} {validation}")
|
||||||
|
db.session.delete(validation)
|
||||||
|
sco_cache.invalidate_formsemestre_etud(etud)
|
||||||
|
db.session.commit()
|
||||||
|
return "ok"
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route(
|
||||||
|
"/etudiant/<int:etudid>/jury/autorisation_inscription/<int:validation_id>/delete",
|
||||||
|
methods=["POST"],
|
||||||
|
)
|
||||||
|
@api_web_bp.route(
|
||||||
|
"/etudiant/<int:etudid>/jury/autorisation_inscription/<int:validation_id>/delete",
|
||||||
|
methods=["POST"],
|
||||||
|
)
|
||||||
|
@login_required
|
||||||
|
@scodoc
|
||||||
|
@permission_required(Permission.ScoEtudInscrit)
|
||||||
|
@as_json
|
||||||
|
def autorisation_inscription_delete(etudid: int, validation_id: int):
|
||||||
|
"Efface cette validation"
|
||||||
|
etud = tools.get_etud(etudid)
|
||||||
|
if etud is None:
|
||||||
|
return "étudiant inconnu", 404
|
||||||
|
validation = ScolarAutorisationInscription.query.filter_by(
|
||||||
|
id=validation_id, etudid=etudid
|
||||||
|
).first_or_404()
|
||||||
|
log(f"autorisation_inscription_delete: etuid={etudid} {validation}")
|
||||||
|
db.session.delete(validation)
|
||||||
|
sco_cache.invalidate_formsemestre_etud(etud)
|
||||||
|
db.session.commit()
|
||||||
|
return "ok"
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route(
|
||||||
|
"/etudiant/<int:etudid>/jury/validation_rcue/<int:validation_id>/delete",
|
||||||
|
methods=["POST"],
|
||||||
|
)
|
||||||
|
@api_web_bp.route(
|
||||||
|
"/etudiant/<int:etudid>/jury/validation_rcue/<int:validation_id>/delete",
|
||||||
|
methods=["POST"],
|
||||||
|
)
|
||||||
|
@login_required
|
||||||
|
@scodoc
|
||||||
|
@permission_required(Permission.ScoEtudInscrit)
|
||||||
|
@as_json
|
||||||
|
def validation_rcue_delete(etudid: int, validation_id: int):
|
||||||
|
"Efface cette validation"
|
||||||
|
etud = tools.get_etud(etudid)
|
||||||
|
if etud is None:
|
||||||
|
return "étudiant inconnu", 404
|
||||||
|
validation = ApcValidationRCUE.query.filter_by(
|
||||||
|
id=validation_id, etudid=etudid
|
||||||
|
).first_or_404()
|
||||||
|
log(f"validation_ue_delete: etuid={etudid} {validation}")
|
||||||
|
db.session.delete(validation)
|
||||||
|
sco_cache.invalidate_formsemestre_etud(etud)
|
||||||
|
db.session.commit()
|
||||||
|
return "ok"
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route(
|
||||||
|
"/etudiant/<int:etudid>/jury/validation_annee_but/<int:validation_id>/delete",
|
||||||
|
methods=["POST"],
|
||||||
|
)
|
||||||
|
@api_web_bp.route(
|
||||||
|
"/etudiant/<int:etudid>/jury/validation_annee_but/<int:validation_id>/delete",
|
||||||
|
methods=["POST"],
|
||||||
|
)
|
||||||
|
@login_required
|
||||||
|
@scodoc
|
||||||
|
@permission_required(Permission.ScoEtudInscrit)
|
||||||
|
@as_json
|
||||||
|
def validation_annee_but_delete(etudid: int, validation_id: int):
|
||||||
|
"Efface cette validation"
|
||||||
|
etud = tools.get_etud(etudid)
|
||||||
|
if etud is None:
|
||||||
|
return "étudiant inconnu", 404
|
||||||
|
validation = ApcValidationAnnee.query.filter_by(
|
||||||
|
id=validation_id, etudid=etudid
|
||||||
|
).first_or_404()
|
||||||
|
log(f"validation_annee_but: etuid={etudid} {validation}")
|
||||||
|
db.session.delete(validation)
|
||||||
|
sco_cache.invalidate_formsemestre_etud(etud)
|
||||||
|
db.session.commit()
|
||||||
|
return "ok"
|
||||||
|
66
app/but/jury_edit_manual.py
Normal file
66
app/but/jury_edit_manual.py
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
##############################################################################
|
||||||
|
# ScoDoc
|
||||||
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||||
|
# See LICENSE
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
"""Jury édition manuelle des décisions (correction d'erreurs, parcours hors normes)
|
||||||
|
|
||||||
|
Non spécifique au BUT.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import flask
|
||||||
|
from flask import flash, render_template, url_for
|
||||||
|
from flask import g, request
|
||||||
|
|
||||||
|
from app import db
|
||||||
|
|
||||||
|
from app.models import (
|
||||||
|
ApcValidationAnnee,
|
||||||
|
ApcValidationRCUE,
|
||||||
|
FormSemestre,
|
||||||
|
Identite,
|
||||||
|
UniteEns,
|
||||||
|
ScolarAutorisationInscription,
|
||||||
|
ScolarFormSemestreValidation,
|
||||||
|
)
|
||||||
|
from app.views import ScoData
|
||||||
|
|
||||||
|
|
||||||
|
def jury_delete_manual(etud: Identite):
|
||||||
|
"""Vue (réservée au chef de dept.)
|
||||||
|
présentant *toutes* les décisions de jury concernant cet étudiant
|
||||||
|
et permettant de les supprimer une à une.
|
||||||
|
"""
|
||||||
|
sem_vals = ScolarFormSemestreValidation.query.filter_by(
|
||||||
|
etudid=etud.id, ue_id=None
|
||||||
|
).order_by(ScolarFormSemestreValidation.event_date)
|
||||||
|
ue_vals = (
|
||||||
|
ScolarFormSemestreValidation.query.filter_by(etudid=etud.id)
|
||||||
|
.join(UniteEns)
|
||||||
|
.order_by(ScolarFormSemestreValidation.event_date, UniteEns.numero)
|
||||||
|
)
|
||||||
|
autorisations = ScolarAutorisationInscription.query.filter_by(
|
||||||
|
etudid=etud.id
|
||||||
|
).order_by(
|
||||||
|
ScolarAutorisationInscription.semestre_id, ScolarAutorisationInscription.date
|
||||||
|
)
|
||||||
|
rcue_vals = (
|
||||||
|
ApcValidationRCUE.query.filter_by(etudid=etud.id)
|
||||||
|
.join(UniteEns, UniteEns.id == ApcValidationRCUE.ue1_id)
|
||||||
|
.order_by(UniteEns.semestre_idx, UniteEns.numero, ApcValidationRCUE.date)
|
||||||
|
)
|
||||||
|
annee_but_vals = ApcValidationAnnee.query.filter_by(etudid=etud.id).order_by(
|
||||||
|
ApcValidationAnnee.ordre, ApcValidationAnnee.date
|
||||||
|
)
|
||||||
|
return render_template(
|
||||||
|
"jury/jury_delete_manual.j2",
|
||||||
|
etud=etud,
|
||||||
|
sem_vals=sem_vals,
|
||||||
|
ue_vals=ue_vals,
|
||||||
|
autorisations=autorisations,
|
||||||
|
rcue_vals=rcue_vals,
|
||||||
|
annee_but_vals=annee_but_vals,
|
||||||
|
sco=ScoData(),
|
||||||
|
title=f"Toutes les décisions de jury enregistrées pour {etud.html_link_fiche()}",
|
||||||
|
)
|
@ -82,6 +82,12 @@ class Identite(db.Model):
|
|||||||
f"<Etud {self.id}/{self.departement.acronym} {self.nom!r} {self.prenom!r}>"
|
f"<Etud {self.id}/{self.departement.acronym} {self.nom!r} {self.prenom!r}>"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def html_link_fiche(self) -> str:
|
||||||
|
"lien vers la fiche"
|
||||||
|
return f"""<a class="stdlink" href="{
|
||||||
|
url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=self.id)
|
||||||
|
}">{self.nomprenom}</a>"""
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_request(cls, etudid=None, code_nip=None) -> "Identite":
|
def from_request(cls, etudid=None, code_nip=None) -> "Identite":
|
||||||
"""Étudiant à partir de l'etudid ou du code_nip, soit
|
"""Étudiant à partir de l'etudid ou du code_nip, soit
|
||||||
|
@ -76,12 +76,14 @@ class ScolarFormSemestreValidation(db.Model):
|
|||||||
d.pop("_sa_instance_state", None)
|
d.pop("_sa_instance_state", None)
|
||||||
return d
|
return d
|
||||||
|
|
||||||
def html(self) -> str:
|
def html(self, detail=False) -> str:
|
||||||
"Affichage html"
|
"Affichage html"
|
||||||
if self.ue_id is not None:
|
if self.ue_id is not None:
|
||||||
return f"""Validation de l'UE {self.ue.acronyme}
|
return f"""Validation de l'UE {self.ue.acronyme} de {self.ue.formation.acronyme}
|
||||||
(<b>{self.code}</b>
|
{("émise par " + self.formsemestre.html_link_status())
|
||||||
le {self.event_date.strftime("%d/%m/%Y")} à {self.event_date.strftime("%Hh%M")})
|
if self.formsemestre else ""}
|
||||||
|
:<b>{self.code}</b>
|
||||||
|
le {self.event_date.strftime("%d/%m/%Y")} à {self.event_date.strftime("%Hh%M")}
|
||||||
"""
|
"""
|
||||||
else:
|
else:
|
||||||
return f"""Validation du semestre S{
|
return f"""Validation du semestre S{
|
||||||
|
@ -312,7 +312,13 @@ def ficheEtud(etudid=None):
|
|||||||
] = f"""<span class="link_bul_pdf"><a class="stdlink" href="{
|
] = f"""<span class="link_bul_pdf"><a class="stdlink" href="{
|
||||||
url_for("notes.formsemestre_inscription_with_modules_form",
|
url_for("notes.formsemestre_inscription_with_modules_form",
|
||||||
scodoc_dept=g.scodoc_dept, etudid=etudid)
|
scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||||
}">inscrire à un autre semestre</a></span>"""
|
}">inscrire à un autre semestre</a></span>
|
||||||
|
<span class="link_bul_pdf"><a class="stdlink" href="{
|
||||||
|
url_for("notes.jury_delete_manual",
|
||||||
|
scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||||
|
}">éditer toutes décisions de jury</a></span>
|
||||||
|
"""
|
||||||
|
|
||||||
else:
|
else:
|
||||||
info["link_inscrire_ailleurs"] = ""
|
info["link_inscrire_ailleurs"] = ""
|
||||||
else:
|
else:
|
||||||
|
9
app/static/css/jury_delete_manual.css
Normal file
9
app/static/css/jury_delete_manual.css
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
|
||||||
|
div.jury_decisions_list div {
|
||||||
|
font-size: 120%;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.jury_decisions_list form {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
@ -3,7 +3,7 @@
|
|||||||
{% block app_content %}
|
{% block app_content %}
|
||||||
|
|
||||||
{% if not validations %}
|
{% if not validations %}
|
||||||
<p>Aucune validation de jury enregistrée pour <b>{{etud.nom_disp()}}</b> sur
|
<p>Aucune validation de jury enregistrée pour <b>{{etud.html_link_fiche()}}</b> sur
|
||||||
<b>l'année {{annee}}</b>
|
<b>l'année {{annee}}</b>
|
||||||
de la formation <em>{{ formation.html() }}</em>
|
de la formation <em>{{ formation.html() }}</em>
|
||||||
</p>
|
</p>
|
||||||
@ -13,7 +13,7 @@ de la formation <em>{{ formation.html() }}</em>
|
|||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
|
|
||||||
<h2>Effacer les décisions de jury pour l'année {{annee}} de {{etud.nom_disp()}} ?</h2>
|
<h2>Effacer les décisions de jury pour l'année {{annee}} de {{etud.html_link_fiche()}} ?</h2>
|
||||||
|
|
||||||
<p class="help">Affectera toutes les décisions concernant l'année {{annee}} de la formation,
|
<p class="help">Affectera toutes les décisions concernant l'année {{annee}} de la formation,
|
||||||
quelle que soit leur origine.</p>
|
quelle que soit leur origine.</p>
|
||||||
|
134
app/templates/jury/jury_delete_manual.j2
Normal file
134
app/templates/jury/jury_delete_manual.j2
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
{% extends 'base.j2' %}
|
||||||
|
|
||||||
|
{% block styles %}
|
||||||
|
{{super()}}
|
||||||
|
<link href="{{scu.STATIC_DIR}}/css/jury_delete_manual.css" rel="stylesheet" type="text/css" />
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block app_content %}
|
||||||
|
|
||||||
|
|
||||||
|
<h2>Décisions de jury enregistrées pour {{etud.html_link_fiche()|safe}}</h2>
|
||||||
|
|
||||||
|
<p class="help">
|
||||||
|
Cette page liste toutes les décisions de jury connus de ScoDoc concernant cet étudiant
|
||||||
|
et permet de les effacer une par une.
|
||||||
|
</p>
|
||||||
|
<p class="help">
|
||||||
|
<b>Attention</b>, il vous appartient de vérifier la cohérence du résultat !
|
||||||
|
En principe, <b>l'usage de cette page devrait rester exceptionnel</b>.
|
||||||
|
Aucune annulation n'est ici possible (vous devrez re-saisir les décisions via les
|
||||||
|
pages de saisie de jury habituelles).
|
||||||
|
</p>
|
||||||
|
{% if sem_vals.first() %}
|
||||||
|
<div class="jury_decisions_list jury_decisions_sems">
|
||||||
|
<div>Décisions de semestres</div>
|
||||||
|
<ul>
|
||||||
|
{% for v in sem_vals %}
|
||||||
|
<li>{{v.html()|safe}}
|
||||||
|
<form><button data-v_id="{{v.id}}" data-type="validation_formsemestre">effacer</button></form>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if ue_vals.first() %}
|
||||||
|
<div class="jury_decisions_list jury_decisions_ues">
|
||||||
|
<div>Décisions d'UEs</div>
|
||||||
|
<ul>
|
||||||
|
{% for v in ue_vals %}
|
||||||
|
<li>{{v.html(detail=True)|safe}}
|
||||||
|
<form><button data-v_id="{{v.id}}" data-type="validation_ue">effacer</button></form>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if rcue_vals.first() %}
|
||||||
|
<div class="jury_decisions_list jury_decisions_rcues">
|
||||||
|
<div>Décisions de RCUE (niveaux de compétences)</div>
|
||||||
|
<ul>
|
||||||
|
{% for v in rcue_vals %}
|
||||||
|
<li>{{v.html()|safe}}
|
||||||
|
<form><button data-v_id="{{v.id}}" data-type="validation_rcue">effacer</button></form>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if annee_but_vals.first() %}
|
||||||
|
<div class="jury_decisions_list jury_decisions_annees_but">
|
||||||
|
<div>Décisions d'années BUT</div>
|
||||||
|
<ul>
|
||||||
|
{% for v in annee_but_vals %}
|
||||||
|
<li>{{v.html()|safe}}
|
||||||
|
<form><button data-v_id="{{v.id}}" data-type="validation_annee_but">effacer</button></form>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if autorisations.first() %}
|
||||||
|
<div class="jury_decisions_list jury_decisions_autorisation_inscription">
|
||||||
|
<div>Autorisations d'inscriptions (passages)</div>
|
||||||
|
<ul>
|
||||||
|
{% for v in autorisations %}
|
||||||
|
<li>{{v.html()|safe}}
|
||||||
|
<form><button data-v_id="{{v.id}}" data-type="autorisation_inscription">effacer</button></form>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if not(
|
||||||
|
sem_vals.first() or sem_ues.first() or sem_rcues.first()
|
||||||
|
or annee_but_vals.first() or autorisations.first())
|
||||||
|
%}
|
||||||
|
<div>
|
||||||
|
<p class="fontred">aucune décision enregistrée</p>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<a class="stdlink" href="{{etud.html_link_fiche()}}">retour à sa fiche</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
|
||||||
|
{% block scripts %}
|
||||||
|
{{super()}}
|
||||||
|
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
const buttons = document.querySelectorAll('.jury_decisions_list button');
|
||||||
|
|
||||||
|
buttons.forEach(button => {
|
||||||
|
button.addEventListener('click', (event) => {
|
||||||
|
// Handle button click event here
|
||||||
|
event.preventDefault();
|
||||||
|
const v_id = event.target.dataset.v_id;
|
||||||
|
const validation_type = event.target.dataset.type;
|
||||||
|
if (confirm("Supprimer cette validation ?")) {
|
||||||
|
fetch(`${SCO_URL}/../api/etudiant/{{etud.id}}/jury/${validation_type}/${v_id}/delete`,
|
||||||
|
{
|
||||||
|
method: "POST",
|
||||||
|
}).then(response => {
|
||||||
|
// Handle the response
|
||||||
|
if (response.ok) {
|
||||||
|
location.reload();
|
||||||
|
} else {
|
||||||
|
throw new Error('Request failed');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
@ -47,11 +47,12 @@ from app.but import jury_but, jury_but_validation_auto
|
|||||||
from app.but.forms import jury_but_forms
|
from app.but.forms import jury_but_forms
|
||||||
from app.but import jury_but_pv
|
from app.but import jury_but_pv
|
||||||
from app.but import jury_but_view
|
from app.but import jury_but_view
|
||||||
|
from app.but import jury_edit_manual
|
||||||
|
|
||||||
from app.comp import jury, res_sem
|
from app.comp import jury, res_sem
|
||||||
from app.comp.res_compat import NotesTableCompat
|
from app.comp.res_compat import NotesTableCompat
|
||||||
from app.models import Formation, ScolarAutorisationInscription, ScolarNews, Scolog
|
from app.models import Formation, ScolarAutorisationInscription, ScolarNews, Scolog
|
||||||
from app.models.but_refcomp import ApcNiveau, ApcParcours
|
from app.models.but_refcomp import ApcNiveau
|
||||||
from app.models.config import ScoDocSiteConfig
|
from app.models.config import ScoDocSiteConfig
|
||||||
from app.models.etudiants import Identite
|
from app.models.etudiants import Identite
|
||||||
from app.models.formsemestre import FormSemestre
|
from app.models.formsemestre import FormSemestre
|
||||||
@ -2940,6 +2941,18 @@ def erase_decisions_annee_formation(etudid: int, formation_id: int, annee: int):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route(
|
||||||
|
"/jury_delete_manual/<int:etudid>",
|
||||||
|
methods=["GET", "POST"],
|
||||||
|
)
|
||||||
|
@scodoc
|
||||||
|
@permission_required(Permission.ScoEtudInscrit)
|
||||||
|
def jury_delete_manual(etudid: int):
|
||||||
|
"""Efface toute les décisions d'une année pour cet étudiant"""
|
||||||
|
etud: Identite = Identite.query.get_or_404(etudid)
|
||||||
|
return jury_edit_manual.jury_delete_manual(etud)
|
||||||
|
|
||||||
|
|
||||||
sco_publish(
|
sco_publish(
|
||||||
"/formsemestre_lettres_individuelles",
|
"/formsemestre_lettres_individuelles",
|
||||||
sco_pv_forms.formsemestre_lettres_individuelles,
|
sco_pv_forms.formsemestre_lettres_individuelles,
|
||||||
|
Loading…
Reference in New Issue
Block a user