diff --git a/app/api/etudiants.py b/app/api/etudiants.py index 2b1128364..46478231b 100644 --- a/app/api/etudiants.py +++ b/app/api/etudiants.py @@ -473,7 +473,7 @@ def etudiant_bulletin_semestre( # XXX TODO Ajouter la possibilité de retourner return response return sco_bulletins.get_formsemestre_bulletin_etud_json( - formsemestre, etud, version + formsemestre, etud, version=version ) diff --git a/app/comp/res_common.py b/app/comp/res_common.py index 04bd92d13..98b5a9c6f 100644 --- a/app/comp/res_common.py +++ b/app/comp/res_common.py @@ -650,7 +650,7 @@ class ResultatsSemestre(ResultatsCache): elif nb_ues_validables < len(ues_sans_bonus): row["_ues_validables_class"] += " moy_inf" row["_ues_validables_order"] = nb_ues_validables # pour tri - if mode_jury: + if mode_jury and self.validations: dec_sem = self.validations.decisions_jury.get(etudid) jury_code_sem = dec_sem["code"] if dec_sem else "" idx = add_cell( diff --git a/app/models/but_refcomp.py b/app/models/but_refcomp.py index 29428c05d..3aff0e9ce 100644 --- a/app/models/but_refcomp.py +++ b/app/models/but_refcomp.py @@ -451,6 +451,7 @@ class ApcAppCritique(db.Model, XMLModel): if competence is not None: query = query.filter(ApcNiveau.competence == competence) return query +<<<<<<< HEAD def __init__(self, id, niveau_id, code, libelle, modules): self.id = id @@ -458,6 +459,8 @@ class ApcAppCritique(db.Model, XMLModel): self.code = code self.libelle = libelle self.modules = modules +======= +>>>>>>> 7c340c798ad59c41653efc83bfd079f11fce1938 def to_dict(self) -> dict: return {"libelle": self.libelle} @@ -544,11 +547,14 @@ class ApcAnneeParcours(db.Model, XMLModel): ) ordre = db.Column(db.Integer) "numéro de l'année: 1, 2, 3" +<<<<<<< HEAD def __init__(self, id, parcours_id, ordre): self.id = id self.parcours_id = parcours_id self.ordre = ordre +======= +>>>>>>> 7c340c798ad59c41653efc83bfd079f11fce1938 def __repr__(self): return f"<{self.__class__.__name__} ordre={self.ordre!r} parcours={self.parcours.code!r}>" diff --git a/app/models/but_validations.py b/app/models/but_validations.py index ebedadd71..9d42c14d3 100644 --- a/app/models/but_validations.py +++ b/app/models/but_validations.py @@ -43,6 +43,7 @@ class ApcValidationRCUE(db.Model): formsemestre_id = db.Column( db.Integer, db.ForeignKey("notes_formsemestre.id"), index=True, nullable=True ) + "formsemestre pair du RCUE" # Les deux UE associées à ce niveau: ue1_id = db.Column(db.Integer, db.ForeignKey("notes_ue.id"), nullable=False) ue2_id = db.Column(db.Integer, db.ForeignKey("notes_ue.id"), nullable=False) diff --git a/app/scodoc/sco_bulletins.py b/app/scodoc/sco_bulletins.py index daf4a9419..4a82674e2 100644 --- a/app/scodoc/sco_bulletins.py +++ b/app/scodoc/sco_bulletins.py @@ -58,7 +58,6 @@ from app.scodoc import sco_formations from app.scodoc import sco_formsemestre from app.scodoc import sco_groups from app.scodoc import sco_permissions_check -from app.scodoc import sco_photos from app.scodoc import sco_preferences from app.scodoc import sco_pvjury from app.scodoc import sco_users @@ -66,15 +65,6 @@ import app.scodoc.sco_utils as scu from app.scodoc.sco_utils import ModuleType, fmt_note import app.scodoc.notesdb as ndb -# ----- CLASSES DE BULLETINS DE NOTES -from app.scodoc import sco_bulletins_standard -from app.scodoc import sco_bulletins_legacy - -# import sco_bulletins_example # format exemple (à désactiver en production) - -# ... ajouter ici vos modules ... -from app.scodoc import sco_bulletins_ucac # format expérimental UCAC Cameroun - def get_formsemestre_bulletin_etud_json( formsemestre: FormSemestre, diff --git a/app/scodoc/sco_bulletins_json.py b/app/scodoc/sco_bulletins_json.py index 78425028d..c48c0d439 100644 --- a/app/scodoc/sco_bulletins_json.py +++ b/app/scodoc/sco_bulletins_json.py @@ -92,7 +92,6 @@ def formsemestre_bulletinetud_published_dict( nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre) d = {"type": "classic", "version": "0"} - if (not sem["bul_hide_xml"]) or force_publishing: published = True else: @@ -134,6 +133,7 @@ def formsemestre_bulletinetud_published_dict( ) d["etudiant"]["sexe"] = d["etudiant"]["civilite"] # backward compat for our clients # Disponible pour publication ? + d["publie"] = published if not published: return d # stop ! @@ -364,8 +364,35 @@ def formsemestre_bulletinetud_published_dict( return d -def dict_decision_jury(etudid, formsemestre_id, with_decisions=False): - "dict avec decision pour bulletins json" +def dict_decision_jury(etudid, formsemestre_id, with_decisions=False) -> dict: + """dict avec decision pour bulletins json + - decision : décision semestre + - decision_ue : list des décisions UE + - situation + + with_decision donne les décision même si bul_show_decision est faux. + + Exemple: + { + 'autorisation_inscription': [{'semestre_id': 4}], + 'decision': {'code': 'ADM', + 'compense_formsemestre_id': None, + 'date': '2022-01-21', + 'etat': 'I'}, + 'decision_ue': [ + { + 'acronyme': 'UE31', + 'code': 'ADM', + 'ects': 16.0, + 'numero': 23, + 'titre': 'Approfondissement métiers', + 'ue_id': 1787 + }, + ... + ], + 'situation': 'Inscrit le 25/06/2021. Décision jury: Validé. UE acquises: ' + 'UE31, UE32. Diplôme obtenu.'} + """ from app.scodoc import sco_bulletins d = {} diff --git a/app/scodoc/sco_formsemestre_validation.py b/app/scodoc/sco_formsemestre_validation.py index 2af209c2a..a9d13c016 100644 --- a/app/scodoc/sco_formsemestre_validation.py +++ b/app/scodoc/sco_formsemestre_validation.py @@ -35,13 +35,17 @@ from app.models.etudiants import Identite import app.scodoc.notesdb as ndb import app.scodoc.sco_utils as scu -from app import log +from app import db, log from app.comp import res_sem from app.comp.res_compat import NotesTableCompat from app.models import FormSemestre from app.models.notes import etud_has_notes_attente - +from app.models.validations import ( + ScolarAutorisationInscription, + ScolarFormSemestreValidation, +) +from app.models.but_validations import ApcValidationRCUE, ApcValidationAnnee from app.scodoc.sco_exceptions import ScoValueError from app.scodoc.scolog import logdb from app.scodoc.sco_codes_parcours import * @@ -989,28 +993,32 @@ def do_formsemestre_validation_auto(formsemestre_id): def formsemestre_validation_suppress_etud(formsemestre_id, etudid): - """Suppression des decisions de jury pour un etudiant.""" - log("formsemestre_validation_suppress_etud( %s, %s)" % (formsemestre_id, etudid)) - cnx = ndb.GetDBConnexion() - cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor) - args = {"formsemestre_id": formsemestre_id, "etudid": etudid} - try: - # -- Validation du semestre et des UEs - cursor.execute( - """delete from scolar_formsemestre_validation - where etudid = %(etudid)s and formsemestre_id=%(formsemestre_id)s""", - args, - ) - # -- Autorisations d'inscription - cursor.execute( - """delete from scolar_autorisation_inscription - where etudid = %(etudid)s and origin_formsemestre_id=%(formsemestre_id)s""", - args, - ) - cnx.commit() - except: - cnx.rollback() - raise + """Suppression des décisions de jury pour un étudiant/formsemestre. + Efface toutes les décisions enregistrées concernant ce formsemestre et cet étudiant: + code semestre, UEs, autorisations d'inscription + """ + log(f"formsemestre_validation_suppress_etud( {formsemestre_id}, {etudid})") + + # Validations jury classiques (semestres, UEs, autorisations) + for v in ScolarFormSemestreValidation.query.filter_by( + etudid=etudid, formsemestre_id=formsemestre_id + ): + db.session.delete(v) + for v in ScolarAutorisationInscription.query.filter_by( + etudid=etudid, origin_formsemestre_id=formsemestre_id + ): + db.session.delete(v) + # Validations jury spécifiques BUT + for v in ApcValidationRCUE.query.filter_by( + etudid=etudid, formsemestre_id=formsemestre_id + ): + db.session.delete(v) + for v in ApcValidationAnnee.query.filter_by( + etudid=etudid, formsemestre_id=formsemestre_id + ): + db.session.delete(v) + + db.session.commit() sem = sco_formsemestre.get_formsemestre(formsemestre_id) _invalidate_etud_formation_caches( diff --git a/app/static/js/releve-but.js b/app/static/js/releve-but.js index edfdf79f1..7d3bc985e 100644 --- a/app/static/js/releve-but.js +++ b/app/static/js/releve-but.js @@ -224,9 +224,26 @@ class releveBUT extends HTMLElement {
Opération non autorisée pour %s" % current_user, dest_url=scu.ScoURL(), ) + etud = Identite.query.get_or_404(etudid) + formsemestre = FormSemestre.query.get_or_404(formsemestre_id) + if formsemestre.formation.is_apc(): + next_url = url_for( + "scolar.ficheEtud", + scodoc_dept=g.scodoc_dept, + etudid=etudid, + ) + else: + next_url = url_for( + "notes.formsemestre_validation_etud_form", + scodoc_dept=g.scodoc_dept, + formsemestre_id=formsemestre_id, + etudid=etudid, + ) if not dialog_confirmed: - etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0] - formsemestre = FormSemestre.query.get_or_404(formsemestre_id) - sem = formsemestre.to_dict() - nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre) - decision_jury = nt.get_etud_decision_sem(etudid) - if decision_jury: - existing = ( - "
Décision existante: %(code)s du %(event_date)s
" % decision_jury - ) + d = sco_bulletins_json.dict_decision_jury( + etudid, formsemestre_id, with_decisions=True + ) + d.update(but_validations.dict_decision_jury(etud, formsemestre)) + + descr_ues = [f"{u['acronyme']}: {u['code']}" for u in d.get("decision_ue", [])] + dec_annee = d.get("decision_annee") + if dec_annee: + descr_annee = dec_annee.get("code", "-") else: - existing = "" + descr_annee = "-" + + existing = f""" +Cette opération est irréversible. -
- """ - % ( - sem["titre_num"], - sem["date_debut"], - sem["date_fin"], - etud["nomprenom"], - existing, - ), + f"""Cette opération est irréversible.
+