forked from ScoDoc/ScoDoc
wip
This commit is contained in:
parent
c0d5eb0f69
commit
6fc3e16bdf
@ -32,8 +32,10 @@ import time
|
|||||||
|
|
||||||
from flask import flash, abort
|
from flask import flash, abort
|
||||||
|
|
||||||
|
from app.but import jury_but
|
||||||
from app.but.cursus_but import EtudCursusBUT
|
from app.but.cursus_but import EtudCursusBUT
|
||||||
from app.but.prepajury_desc import ParcoursDesc
|
from app.but.jury_but import DecisionsProposeesAnnee
|
||||||
|
from app.but.prepajury_desc import ParcoursDesc, liste_annees, FormSemestreDesc
|
||||||
from app.comp import res_sem
|
from app.comp import res_sem
|
||||||
from app.comp.res_but import ResultatsSemestreBUT
|
from app.comp.res_but import ResultatsSemestreBUT
|
||||||
from app.models import (
|
from app.models import (
|
||||||
@ -48,101 +50,198 @@ import app.scodoc.sco_utils as scu
|
|||||||
from app.but.prepajury_xl import ScoExcelBook
|
from app.but.prepajury_xl import ScoExcelBook
|
||||||
|
|
||||||
|
|
||||||
class _Bilan:
|
class Element:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.note = 0
|
self.note = None
|
||||||
self.resultat = 0
|
self.resultat = None
|
||||||
self.format = 0
|
self.format = 0
|
||||||
|
|
||||||
|
def set_note(self, note):
|
||||||
|
self.note = note
|
||||||
|
|
||||||
class _UE:
|
def set_res(self, res):
|
||||||
|
self.res = res
|
||||||
|
|
||||||
|
def get_res(self):
|
||||||
|
return self.res
|
||||||
|
|
||||||
|
def get_note(self):
|
||||||
|
return self.note
|
||||||
|
|
||||||
|
|
||||||
|
class ElementUE(Element):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.bilan = None
|
super().__init__()
|
||||||
|
|
||||||
|
|
||||||
class _Niveau:
|
class ElementNiveau(Element):
|
||||||
def __init__(self, etudiant, niveauDesc, semestres):
|
def __init__(self, etudiant, niveauDesc, semestres):
|
||||||
self.bilan = None
|
super().__init__()
|
||||||
self.etudiant = etudiant
|
self.etudiant = etudiant
|
||||||
self.candidates = niveauDesc.get_ues(etudiant)
|
self.candidates = niveauDesc.get_ues(etudiant)
|
||||||
self.ues = collections.defaultdict(list)
|
self.ues = collections.defaultdict(list)
|
||||||
|
|
||||||
def add_ue_status(self, semestre_idx, status):
|
def add_ue_status(self, semestre_idx, status):
|
||||||
|
ue_id = status["ue"]["id"]
|
||||||
self.ues[semestre_idx].append(status)
|
self.ues[semestre_idx].append(status)
|
||||||
|
self.etudiant.ues[ue_id] = status
|
||||||
|
|
||||||
|
|
||||||
class _Annee:
|
class ElementAnnee(Element):
|
||||||
def __init__(self, etudiant, annee_desc):
|
def __init__(self, etudiant, annee_desc):
|
||||||
|
super().__init__()
|
||||||
self.etudiant = etudiant
|
self.etudiant = etudiant
|
||||||
self.anneeDesc = annee_desc
|
self.anneeDesc = annee_desc
|
||||||
self.bilan: _Bilan = None
|
|
||||||
self.niveaux = {}
|
self.niveaux = {}
|
||||||
|
|
||||||
|
|
||||||
class _Competence:
|
class CompetenceEtudiantJury:
|
||||||
def __init__(self, etudiant, competenceDesc, semestres):
|
def __init__(self, etudiant, competenceDesc, semestres):
|
||||||
self.descr = competenceDesc
|
self.descr = competenceDesc
|
||||||
self.etudiant = etudiant
|
self.etudiant = etudiant
|
||||||
self.niveaux = {}
|
self.niveaux = {}
|
||||||
for niveau_id, niveauDesc in competenceDesc.niveaux.items():
|
for niveau_id, niveauDesc in competenceDesc.niveaux.items():
|
||||||
self.niveaux[niveau_id] = _Niveau(etudiant, niveauDesc, semestres)
|
self.niveaux[niveau_id] = ElementNiveau(etudiant, niveauDesc, semestres)
|
||||||
|
etudiant.niveaux[niveau_id] = self.niveaux[niveau_id]
|
||||||
|
|
||||||
def getNiveau(self, niveau_id):
|
def getNiveau(self, niveau_id):
|
||||||
return self.niveaux[niveau_id]
|
return self.niveaux[niveau_id]
|
||||||
|
|
||||||
|
|
||||||
class _Semestre:
|
class ElementFormsemestre(Element):
|
||||||
def __init__(self, formsemestre_id, formsemestre=None):
|
def __init__(self, formsemestre_id=None, formsemestre=None):
|
||||||
|
super().__init__()
|
||||||
if formsemestre is None:
|
if formsemestre is None:
|
||||||
formsemestre = FormSemestre.get_formsemestre(formsemestre_id)
|
formsemestre = FormSemestre.get_formsemestre(formsemestre_id)
|
||||||
self.formsemestre = formsemestre
|
self.formsemestre = formsemestre
|
||||||
self.resultatsSemestreBUT: ResultatsSemestreBUT = (
|
self.deca = None
|
||||||
res_sem.load_formsemestre_results(formsemestre)
|
|
||||||
)
|
def get_deca(self):
|
||||||
# self.etuds_ues = (
|
if self.deca is None:
|
||||||
# self.resultatsSemestreBUT.load_ues_inscr_parcours()
|
self.deca = 0
|
||||||
# )
|
return self.deca
|
||||||
|
|
||||||
|
|
||||||
class _Etudiant:
|
class ListeElements:
|
||||||
def __init__(self, ident, formation):
|
def __init__(self):
|
||||||
|
self.elements = []
|
||||||
|
|
||||||
|
def add(self, element):
|
||||||
|
self.elements.append(element)
|
||||||
|
|
||||||
|
def last(self):
|
||||||
|
return self.elements[-1]
|
||||||
|
|
||||||
|
|
||||||
|
class EtudiantJury:
|
||||||
|
def __init__(self, ident, formation, current_formsemestre, contexte):
|
||||||
|
self.contexte = contexte
|
||||||
self.ident = ident
|
self.ident = ident
|
||||||
self.cursus: EtudCursusBUT = EtudCursusBUT(ident, formation)
|
self.formsemestre = current_formsemestre
|
||||||
self.formsemestres = []
|
self.formsemestres = []
|
||||||
|
self.formation = formation
|
||||||
|
self.cursus: EtudCursusBUT = EtudCursusBUT(ident, formation)
|
||||||
self.parcour = self.cursus.inscriptions[-1].parcour
|
self.parcour = self.cursus.inscriptions[-1].parcour
|
||||||
|
# Variables calculées
|
||||||
self.history = []
|
self.history = []
|
||||||
self.competences = {}
|
#
|
||||||
self.annees = []
|
self.formsemestre_par_semestre_idx = collections.defaultdict(lambda: ListeElements())
|
||||||
for inscription in self.cursus.inscriptions:
|
# self.niveau_par_annee_et_competence : list(ListeElements) = {}
|
||||||
|
self.ues_par_annee_et_competence : list(ListeElements) = {}
|
||||||
|
#
|
||||||
|
for inscription in sorted(
|
||||||
|
self.cursus.inscriptions, key=lambda x: x.formsemestre.date_debut
|
||||||
|
):
|
||||||
formsemestre = inscription.formsemestre
|
formsemestre = inscription.formsemestre
|
||||||
self.formsemestres.append(inscription.formsemestre.id)
|
element_formsemestre = contexte.get_element_formsemestre(formsemestre.formsemestre_id)
|
||||||
Sx = f"S{formsemestre.semestre_id}"
|
Sx = f"S{formsemestre.semestre_id}"
|
||||||
|
self.formsemestre_par_semestre_idx[formsemestre.semestre_id].add(formsemestre)
|
||||||
etat = inscription.etat
|
etat = inscription.etat
|
||||||
if etat != "I":
|
if etat != "I":
|
||||||
Sx += "(Dem)" if etat == "D" else f"({etat})"
|
Sx += " (Dem)" if etat == "D" else f" ({etat})"
|
||||||
self.history.append(Sx)
|
self.history.append(Sx)
|
||||||
|
|
||||||
|
def select(self, annee_idx=None, periode_idx=None, competence_id=None):
|
||||||
|
pass
|
||||||
|
|
||||||
def fill_in(self, parcourDescr, semestres):
|
def fill_in(self, parcourDescr, semestres):
|
||||||
self.annees = {
|
# Remplissage des competences
|
||||||
codeAnnee: _Annee(self, anneeDesc)
|
# Remplissage des formsemestres
|
||||||
for codeAnnee, anneeDesc in parcourDescr.annees.items()
|
|
||||||
}
|
|
||||||
for (competence_id, competenceDesc) in parcourDescr.competences.items():
|
|
||||||
self.competences[competence_id] = _Competence(
|
|
||||||
self, competenceDesc, semestres
|
|
||||||
)
|
|
||||||
for formsemestre_id in self.formsemestres:
|
for formsemestre_id in self.formsemestres:
|
||||||
semestre: _Semestre = semestres[formsemestre_id]
|
formsemestre_desc = self.contexte.get_element_formsemestre(formsemestre_id)
|
||||||
ues = semestre.resultatsSemestreBUT.etud_ues(self.ident.etudid)
|
semestre_idx = formsemestre_desc.formsemestre.semestre_id
|
||||||
|
self.formsemestre_par_semestre_idx[semestre_idx] = formsemestre_desc
|
||||||
|
for semestre_idx in range(1, 6):
|
||||||
|
if semestre_idx in self.formsemestre_par_semestre_idx:
|
||||||
|
formsemestre_desc = self.formsemestre_par_semestre_idx[semestre_idx]
|
||||||
|
resultats = formsemestre_desc.get_resultats()
|
||||||
|
ues = resultats.etud_ues(self.ident.etudid)
|
||||||
for ue in ues:
|
for ue in ues:
|
||||||
niveau_id = ue.niveau_competence_id
|
|
||||||
competence_id = ue.niveau_competence.competence_id
|
competence_id = ue.niveau_competence.competence_id
|
||||||
semestre_idx = ue.semestre_idx
|
status = resultats.get_etud_ue_status(
|
||||||
niveau = self.competences[competence_id].getNiveau(niveau_id)
|
|
||||||
status = semestre.resultatsSemestreBUT.get_etud_ue_status(
|
|
||||||
self.ident.etudid, ue.id
|
self.ident.etudid, ue.id
|
||||||
)
|
)
|
||||||
niveau.add_ue_status(semestre_idx, status)
|
self.ues_par_competence_et_annee[(semestre_idx, competence_id)] = status
|
||||||
|
pass
|
||||||
|
|
||||||
|
# deca = DecisionsProposeesAnnee(self.ident, formsemestre)
|
||||||
|
# Remplissage des niveaux de compétence
|
||||||
|
# for (competence_id, item) in self.cursus.validation_par_competence_et_annee.items():
|
||||||
|
# for (annee, validation) in item.items():
|
||||||
|
# self.niveau_par_annee_and_competence[(annee, competence_id)].res = validation.code
|
||||||
|
# for annee, idx in [("BUT1", 1), ("BUT2", 2), ("BUT3", 3)]:
|
||||||
|
# formsemestre = self.formsemestre_par_semestre_idx.get(idx + 1, self.formsemestre_par_semestre_idx.get(idx, None))
|
||||||
|
# if formsemestre is not None:
|
||||||
|
# deca = DecisionsProposeesAnnee(self.ident, formsemestre)
|
||||||
|
|
||||||
|
# for (competence_id, competenceDesc) in parcourDescr.competences.items():
|
||||||
|
# self.competences[competence_id] = CompetenceEtudiantJury(
|
||||||
|
# self, competenceDesc, semestres
|
||||||
|
# )
|
||||||
|
# self.annees = {
|
||||||
|
# codeAnnee: _Annee(self, anneeDesc)
|
||||||
|
# for codeAnnee, anneeDesc in parcourDescr.annees.items()
|
||||||
|
# }
|
||||||
|
# for semestre, annee in [(2, "BUT1"), (4, "BUT2"), (6, "BUT3")]:
|
||||||
|
# if semestre in self.formsemestre_par_semestre_idx:
|
||||||
|
# self.deca[annee] = jury_but.DecisionsProposeesAnnee(
|
||||||
|
# self.ident, self.formsemestre_par_semestre_idx[semestre]
|
||||||
|
# )
|
||||||
|
# elif semestre - 1 in self.formsemestre_par_semestre_idx:
|
||||||
|
# self.deca[annee] = jury_but.DecisionsProposeesAnnee(
|
||||||
|
# self.ident, self.formsemestre_par_semestre_idx[semestre - 1]
|
||||||
|
# )
|
||||||
|
# if annee in self.deca:
|
||||||
|
# for rcue in self.deca[annee].rcues_annee:
|
||||||
|
# ue_id1 = rcue.ue_1.id
|
||||||
|
# self.notes_ues[ue_id1] = rcue.moy_ue_1
|
||||||
|
# ue_id2 = rcue.ue_2.id
|
||||||
|
# self.notes_ues[ue_id2] = rcue.moy_ue_2
|
||||||
|
# rcue_id = rcue.ue_1.niveau_competence_id
|
||||||
|
# self.notes_rcues[rcue_id] = rcue.moy_rcue
|
||||||
|
|
||||||
|
def add_formsemestre(self, formsemestre_id):
|
||||||
|
self.formsemestres.append(formsemestre_id)
|
||||||
|
|
||||||
|
def getDipl(self, codeAnnée):
|
||||||
|
return ""
|
||||||
|
|
||||||
|
def getNote(self, codeAnnée, niveau_id=None, ue_id=None):
|
||||||
|
annee = self.annees.get(codeAnnée, None)
|
||||||
|
if annee is None:
|
||||||
|
return "-"
|
||||||
|
if niveau_id is None:
|
||||||
|
return ""
|
||||||
|
elif ue_id is None:
|
||||||
|
return self.notes_rcues.get(niveau_id, "")
|
||||||
|
return self.notes_ues.get(ue_id, "")
|
||||||
|
|
||||||
|
def getRes(self, codeAnnée, niveau_id=None, ue_id=None):
|
||||||
|
if niveau_id is None:
|
||||||
|
return ""
|
||||||
|
elif ue_id is None:
|
||||||
|
return ""
|
||||||
|
return ""
|
||||||
|
|
||||||
def getData(self):
|
def getData(self):
|
||||||
result = [
|
result = [
|
||||||
@ -160,53 +259,63 @@ class _Etudiant:
|
|||||||
|
|
||||||
class _Compilation:
|
class _Compilation:
|
||||||
def __init__(self, formsemestre: FormSemestre):
|
def __init__(self, formsemestre: FormSemestre):
|
||||||
self.semestres = {}
|
# Dictionnaire des éléments
|
||||||
self.parcours = {}
|
self.inv_formsemestres = {}
|
||||||
|
# self.inv_niveaux = {}
|
||||||
|
# self.inv_ues = {}
|
||||||
|
# self.inv_annees = {}
|
||||||
|
self.inv_parcours = {}
|
||||||
|
#
|
||||||
formsemestre_id = formsemestre.formsemestre_id
|
formsemestre_id = formsemestre.formsemestre_id
|
||||||
self.semestre: _Semestre = _Semestre(formsemestre_id, formsemestre)
|
|
||||||
self.formation: Formation = formsemestre.formation
|
self.formation: Formation = formsemestre.formation
|
||||||
self.add_semestre(formsemestre_id, self.semestre)
|
self.consider_formsemestre(formsemestre=formsemestre)
|
||||||
for ident in self.semestre.resultatsSemestreBUT.get_inscrits(order_by="moy"):
|
formsemestre_desc = self.get_element_formsemestre(formsemestre_id)
|
||||||
etudiant: _Etudiant = _Etudiant(ident, self.formation)
|
for ident in formsemestre_desc.get_resultats().get_inscrits(order_by="moy"):
|
||||||
for inscription in etudiant.cursus.inscriptions:
|
etudiant: EtudiantJury = EtudiantJury(ident, self.formation, formsemestre, self)
|
||||||
|
# Ajout de tous les semestres de l'étudiant
|
||||||
|
for inscription in sorted(etudiant.cursus.inscriptions, key=lambda x: x.formsemestre.date_debut):
|
||||||
formsemestre = inscription.formsemestre
|
formsemestre = inscription.formsemestre
|
||||||
if (
|
if (
|
||||||
formsemestre.formation.referentiel_competence
|
formsemestre.formation.referentiel_competence
|
||||||
== self.formation.referentiel_competence
|
== self.formation.referentiel_competence
|
||||||
):
|
):
|
||||||
self.add_semestre(formsemestre.id)
|
self.consider_formsemestre(formsemestre=formsemestre)
|
||||||
|
etudiant.add_formsemestre(formsemestre.formsemestre_id)
|
||||||
|
# Prise en compte du parcours
|
||||||
scodocParcour = etudiant.parcour
|
scodocParcour = etudiant.parcour
|
||||||
if scodocParcour is None:
|
if scodocParcour is None:
|
||||||
parcourCode = "TC"
|
parcourCode = "TC"
|
||||||
else:
|
else:
|
||||||
parcourCode = scodocParcour.code
|
parcourCode = scodocParcour.code
|
||||||
if parcourCode in self.parcours:
|
if parcourCode in self.inv_parcours:
|
||||||
parcoursDesc = self.parcours[parcourCode]
|
parcoursDesc = self.inv_parcours[parcourCode]
|
||||||
else:
|
else:
|
||||||
parcoursDesc = ParcoursDesc(self.formation, scodocParcour)
|
parcoursDesc = ParcoursDesc(self.formation, scodocParcour)
|
||||||
self.parcours[parcourCode] = parcoursDesc
|
self.inv_parcours[parcourCode] = parcoursDesc
|
||||||
parcoursDesc.add_etudiant(etudiant)
|
parcoursDesc.add_etudiant(etudiant)
|
||||||
# etudiant.fill_in(parcoursDesc, self.semestres)
|
etudiant.fill_in(parcoursDesc, self)
|
||||||
pass
|
|
||||||
|
|
||||||
def add_semestre(self, formsemestre_id, semestre: _Semestre = None):
|
def get_element_formsemestre(self, formsemestre_id):
|
||||||
if not formsemestre_id in self.semestres:
|
return self.inv_formsemestres.get(formsemestre_id, None)
|
||||||
|
|
||||||
|
def consider_formsemestre(self, formsemestre: FormSemestre):
|
||||||
|
formsemestre_id = formsemestre.formsemestre_id
|
||||||
|
if formsemestre_id not in self.inv_formsemestres:
|
||||||
|
formsemestre_desc = FormSemestreDesc(formsemestre)
|
||||||
|
self.inv_formsemestres[formsemestre_id] = formsemestre_desc
|
||||||
|
|
||||||
|
def add_semestre(self, formsemestre_id, semestre: ElementFormsemestre = None):
|
||||||
|
if not formsemestre_id in self.ElemFormSemestres:
|
||||||
if semestre is None:
|
if semestre is None:
|
||||||
semestre = _Semestre(formsemestre_id)
|
semestre = ElementFormsemestre(formsemestre_id)
|
||||||
self.semestres[formsemestre_id] = _Semestre(formsemestre_id)
|
self.ElemFormSemestres[formsemestre_id] = ElementFormsemestre(formsemestre_id)
|
||||||
|
|
||||||
def add_parcours(self, scodocParcour: ApcParcours, etudiant: _Etudiant):
|
|
||||||
parcour_code = scodocParcour.get("code", "TC")
|
|
||||||
if not parcour_code in self.parcours:
|
|
||||||
self.parcours[parcour_code] = ParcoursDesc(self.formation, scodocParcour)
|
|
||||||
self.parcours[parcour_code].add(etudiant)
|
|
||||||
|
|
||||||
def computes_decision(self):
|
def computes_decision(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def make_excel(self, filename: str):
|
def make_excel(self, filename: str):
|
||||||
workbook = ScoExcelBook()
|
workbook = ScoExcelBook()
|
||||||
for parcoursCode, parcours in self.parcours.items():
|
for parcoursCode, parcours in self.inv_parcours.items():
|
||||||
parcours.generate(workbook)
|
parcours.generate(workbook)
|
||||||
|
|
||||||
mime, suffix = scu.get_mime_suffix("xlsx")
|
mime, suffix = scu.get_mime_suffix("xlsx")
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import openpyxl
|
import openpyxl
|
||||||
from openpyxl.worksheet.worksheet import Worksheet
|
from openpyxl.worksheet.worksheet import Worksheet
|
||||||
|
|
||||||
from app.but.prepajury_xl_format import (
|
from app.but.prepajury_xl_format import (
|
||||||
SCO_COLORS,
|
SCO_COLORS,
|
||||||
FMT,
|
FMT,
|
||||||
@ -11,6 +12,8 @@ from app.but.prepajury_xl_format import (
|
|||||||
HAIR_BLACK,
|
HAIR_BLACK,
|
||||||
SCO_NUMBER_FORMAT,
|
SCO_NUMBER_FORMAT,
|
||||||
)
|
)
|
||||||
|
from app.comp import res_sem
|
||||||
|
from app.comp.res_but import ResultatsSemestreBUT
|
||||||
from app.models import ApcCompetence, ApcParcours
|
from app.models import ApcCompetence, ApcParcours
|
||||||
from app.but.prepajury_xl import (
|
from app.but.prepajury_xl import (
|
||||||
ScoExcelBook,
|
ScoExcelBook,
|
||||||
@ -21,11 +24,8 @@ from app.but.prepajury_xl import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def parite(semestre_idx):
|
UNUSED = "XXX"
|
||||||
return (semestre_idx + 1) % 2
|
liste_annees = ["BUT1", "BUT2", "BUT3"]
|
||||||
|
|
||||||
|
|
||||||
listeAnnees = ["BUT1", "BUT2", "BUT3"]
|
|
||||||
header_colors = {
|
header_colors = {
|
||||||
"BUT1": {
|
"BUT1": {
|
||||||
"BUT": SCO_COLORS.BUT1,
|
"BUT": SCO_COLORS.BUT1,
|
||||||
@ -45,6 +45,25 @@ header_colors = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def parite(semestre_idx):
|
||||||
|
return (semestre_idx + 1) % 2
|
||||||
|
|
||||||
|
|
||||||
|
class FormSemestreDesc:
|
||||||
|
def __init__(self, formsemestre):
|
||||||
|
self.formsemestre = formsemestre
|
||||||
|
self.deca = None
|
||||||
|
self.resultats = None
|
||||||
|
|
||||||
|
def get_resultats(self):
|
||||||
|
if self.resultats is None:
|
||||||
|
self.resultats: ResultatsSemestreBUT = (
|
||||||
|
res_sem.load_formsemestre_results(self.formsemestre)
|
||||||
|
)
|
||||||
|
return self.resultats
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class NiveauDesc:
|
class NiveauDesc:
|
||||||
def __init__(self, scodocNiveau):
|
def __init__(self, scodocNiveau):
|
||||||
self.fromScodoc = scodocNiveau
|
self.fromScodoc = scodocNiveau
|
||||||
@ -55,6 +74,93 @@ class NiveauDesc:
|
|||||||
if not scodocUe.is_external:
|
if not scodocUe.is_external:
|
||||||
self.ue[parite(scodocUe.semestre_idx)] = scodocUe
|
self.ue[parite(scodocUe.semestre_idx)] = scodocUe
|
||||||
|
|
||||||
|
def generate_data(
|
||||||
|
self, ws: ScoExcelSheet, row: int, etudiant: "EtudiantJury", column: int
|
||||||
|
) -> int:
|
||||||
|
for ue in self.ue:
|
||||||
|
if ue is None:
|
||||||
|
ws.set_cell(row, column, UNUSED)
|
||||||
|
ws.set_cell(row, column + 1, UNUSED)
|
||||||
|
else:
|
||||||
|
ws.set_cell(
|
||||||
|
row,
|
||||||
|
column,
|
||||||
|
etudiant.getNote(self.fromScodoc.annee, self.fromScodoc.id, ue.id),
|
||||||
|
base_signature,
|
||||||
|
)
|
||||||
|
ws.set_cell(
|
||||||
|
row,
|
||||||
|
column + 1,
|
||||||
|
etudiant.getRes(self.fromScodoc.annee, self.fromScodoc.id, ue.id),
|
||||||
|
)
|
||||||
|
column += 2
|
||||||
|
ws.set_cell(
|
||||||
|
row,
|
||||||
|
column,
|
||||||
|
etudiant.getNote(self.fromScodoc.annee, self.fromScodoc.id),
|
||||||
|
base_signature,
|
||||||
|
)
|
||||||
|
ws.set_cell(
|
||||||
|
row, column + 1, etudiant.getRes(self.fromScodoc.annee, self.fromScodoc.id)
|
||||||
|
)
|
||||||
|
return column + 2
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def generate_blank_data(ws: ScoExcelSheet, row: int, column: int) -> int:
|
||||||
|
ws.set_cell(row, column + 0, "UN1")
|
||||||
|
ws.set_cell(row, column + 1, "UR1")
|
||||||
|
ws.set_cell(row, column + 2, "UN2")
|
||||||
|
ws.set_cell(row, column + 3, "UR2")
|
||||||
|
ws.set_cell(row, column + 4, "R1")
|
||||||
|
ws.set_cell(row, column + 5, "R2")
|
||||||
|
column += 6
|
||||||
|
return column
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def generate_blank_header(ws: ScoExcelSheet, column: int, annee: str):
|
||||||
|
rcue_signature = FMT.FILL_BGCOLOR.write(
|
||||||
|
value=header_colors[annee]["RCUE"].value,
|
||||||
|
signature=base_signature,
|
||||||
|
)
|
||||||
|
ue_signature = FMT.FILL_BGCOLOR.write(
|
||||||
|
value=header_colors[annee]["UE"].value,
|
||||||
|
signature=base_signature,
|
||||||
|
)
|
||||||
|
merge = ws.get_merge_engine(start_row=2, start_column=column)
|
||||||
|
frame = ws.get_frame_engine(
|
||||||
|
start_row=2, start_column=column, thickness=SCO_BORDERTHICKNESS.BORDER_THIN
|
||||||
|
)
|
||||||
|
ws.set_cell(2, column, UNUSED, from_signature=rcue_signature)
|
||||||
|
for ue in ["UE1", "UE2"]:
|
||||||
|
frame_ue = ws.get_frame_engine(
|
||||||
|
start_row=3,
|
||||||
|
start_column=column,
|
||||||
|
thickness=SCO_BORDERTHICKNESS.BORDER_THIN,
|
||||||
|
color=SCO_COLORS.GREY,
|
||||||
|
)
|
||||||
|
merge_ue = ws.get_merge_engine(start_row=3, start_column=column)
|
||||||
|
ws.set_cell(3, column, UNUSED, ue_signature)
|
||||||
|
ws.set_cell(4, column, "Note", ue_signature)
|
||||||
|
ws.set_column_dimension_hidden(ScoExcelSheet.i2col(column - 1), True)
|
||||||
|
column += 1
|
||||||
|
ws.set_cell(4, column, "Rés.", ue_signature)
|
||||||
|
ws.set_column_dimension_hidden(ScoExcelSheet.i2col(column - 1), True)
|
||||||
|
column += 1
|
||||||
|
merge_ue.close(end_row=3, end_column=column - 1)
|
||||||
|
frame_ue.close(end_row=4, end_column=column - 1)
|
||||||
|
merge_rcue = ws.get_merge_engine(start_row=3, start_column=column)
|
||||||
|
ws.set_cell(3, column, UNUSED, rcue_signature)
|
||||||
|
ws.set_cell(4, column, UNUSED, rcue_signature)
|
||||||
|
ws.set_column_dimension_hidden(ScoExcelSheet.i2col(column - 1), True)
|
||||||
|
column += 1
|
||||||
|
ws.set_cell(4, column, UNUSED, rcue_signature)
|
||||||
|
ws.set_column_dimension_hidden(ScoExcelSheet.i2col(column - 1), True)
|
||||||
|
column += 1
|
||||||
|
merge_rcue.close(end_row=3, end_column=column - 1)
|
||||||
|
frame.close(end_row=4, end_column=column - 1)
|
||||||
|
merge.close(end_row=2, end_column=column - 1)
|
||||||
|
return column
|
||||||
|
|
||||||
def generate_header(self, ws: ScoExcelSheet, column: int):
|
def generate_header(self, ws: ScoExcelSheet, column: int):
|
||||||
rcue_signature = FMT.FILL_BGCOLOR.write(
|
rcue_signature = FMT.FILL_BGCOLOR.write(
|
||||||
value=header_colors[self.fromScodoc.annee]["RCUE"].value,
|
value=header_colors[self.fromScodoc.annee]["RCUE"].value,
|
||||||
@ -68,7 +174,9 @@ class NiveauDesc:
|
|||||||
frame = ws.get_frame_engine(
|
frame = ws.get_frame_engine(
|
||||||
start_row=2, start_column=column, thickness=SCO_BORDERTHICKNESS.BORDER_THIN
|
start_row=2, start_column=column, thickness=SCO_BORDERTHICKNESS.BORDER_THIN
|
||||||
)
|
)
|
||||||
ws.set_cell(2, column, self.fromScodoc.libelle, from_signature=rcue_signature)
|
ws.set_cell(
|
||||||
|
2, column, self.fromScodoc.competence.titre, from_signature=rcue_signature
|
||||||
|
)
|
||||||
for ue in self.ue:
|
for ue in self.ue:
|
||||||
frame_ue = ws.get_frame_engine(
|
frame_ue = ws.get_frame_engine(
|
||||||
start_row=3,
|
start_row=3,
|
||||||
@ -140,6 +248,25 @@ class AnneeDesc:
|
|||||||
def generate_blank_niveau(self, ws: ScoExcelSheet, column: int):
|
def generate_blank_niveau(self, ws: ScoExcelSheet, column: int):
|
||||||
return column
|
return column
|
||||||
|
|
||||||
|
def generate_data(
|
||||||
|
self, ws: ScoExcelSheet, row: int, etudiant: "EtudiantJury", column: int
|
||||||
|
) -> int:
|
||||||
|
for niveau in self.niveaux.values():
|
||||||
|
column = niveau.generate_data(ws, row, etudiant, column)
|
||||||
|
for i in range(len(self.niveaux), 6):
|
||||||
|
column = NiveauDesc.generate_blank_data(ws, row, column)
|
||||||
|
ws.set_cell(row, column + 0, "A1")
|
||||||
|
ws.set_cell(row, column + 1, etudiant.getNote(self.codeAnnee), base_signature)
|
||||||
|
ws.set_cell(row, column + 2, etudiant.getRes(self.codeAnnee))
|
||||||
|
column += 3
|
||||||
|
if self.codeAnnee == "BUT2":
|
||||||
|
ws.set_cell(row, column, etudiant.getDipl("BUT2"))
|
||||||
|
column += 1
|
||||||
|
if self.codeAnnee == "BUT3":
|
||||||
|
ws.set_cell(row, column, etudiant.getDipl("BUT3"))
|
||||||
|
column += 1
|
||||||
|
return column
|
||||||
|
|
||||||
def generate_header(self, ws: ScoExcelSheet, column: int):
|
def generate_header(self, ws: ScoExcelSheet, column: int):
|
||||||
start = column
|
start = column
|
||||||
but_signature = FMT.FILL_BGCOLOR.write(
|
but_signature = FMT.FILL_BGCOLOR.write(
|
||||||
@ -162,7 +289,7 @@ class AnneeDesc:
|
|||||||
for niveau in self.niveaux.values():
|
for niveau in self.niveaux.values():
|
||||||
column = niveau.generate_header(ws, column)
|
column = niveau.generate_header(ws, column)
|
||||||
for i in range(len(self.niveaux), 6):
|
for i in range(len(self.niveaux), 6):
|
||||||
column = self.generate_blank_niveau(ws, column)
|
column = NiveauDesc.generate_blank_header(ws, column, self.codeAnnee)
|
||||||
merge_annee = ws.get_merge_engine(start_row=2, start_column=column)
|
merge_annee = ws.get_merge_engine(start_row=2, start_column=column)
|
||||||
ws.set_cell(2, column, "Année", from_signature=but_signature)
|
ws.set_cell(2, column, "Année", from_signature=but_signature)
|
||||||
# cell_format(ws.cell(2, column), but_signature, [(FMT.FONT_BOLD, True)])
|
# cell_format(ws.cell(2, column), but_signature, [(FMT.FONT_BOLD, True)])
|
||||||
@ -227,7 +354,7 @@ class ParcoursDesc:
|
|||||||
self.competences[scodocCompetence.id] = CompetenceDesc(
|
self.competences[scodocCompetence.id] = CompetenceDesc(
|
||||||
scodocCompetence
|
scodocCompetence
|
||||||
)
|
)
|
||||||
for codeAnnee in listeAnnees:
|
for codeAnnee in liste_annees:
|
||||||
anneeDesc = AnneeDesc(codeAnnee)
|
anneeDesc = AnneeDesc(codeAnnee)
|
||||||
for competence_id, competence in self.competences.items():
|
for competence_id, competence in self.competences.items():
|
||||||
anneeDesc.addNiveau(competence.getNiveaux(codeAnnee))
|
anneeDesc.addNiveau(competence.getNiveaux(codeAnnee))
|
||||||
@ -312,7 +439,7 @@ class ParcoursDesc:
|
|||||||
|
|
||||||
def generate_header(self, ws: ScoExcelSheet):
|
def generate_header(self, ws: ScoExcelSheet):
|
||||||
column: int = self.generate_etudiant_header(ws)
|
column: int = self.generate_etudiant_header(ws)
|
||||||
for codeAnnee in listeAnnees:
|
for codeAnnee in liste_annees:
|
||||||
column = self.annees[codeAnnee].generate_header(ws, column)
|
column = self.annees[codeAnnee].generate_header(ws, column)
|
||||||
|
|
||||||
def generate(self, workbook: ScoExcelBook):
|
def generate(self, workbook: ScoExcelBook):
|
||||||
@ -322,3 +449,28 @@ class ParcoursDesc:
|
|||||||
sheet_name = "TC"
|
sheet_name = "TC"
|
||||||
worksheet: ScoExcelSheet = workbook.create_sheet(sheet_name)
|
worksheet: ScoExcelSheet = workbook.create_sheet(sheet_name)
|
||||||
self.generate_header(worksheet)
|
self.generate_header(worksheet)
|
||||||
|
self.generate_etudiants(worksheet)
|
||||||
|
|
||||||
|
def generate_data(
|
||||||
|
self, ws: ScoExcelSheet, row: int, column: int, etudiant: "EtudiantJury"
|
||||||
|
):
|
||||||
|
for codeAnnee in liste_annees:
|
||||||
|
column = self.annees[codeAnnee].generate_data(ws, row, etudiant, column)
|
||||||
|
ws.set_cell(row, column, "FIN")
|
||||||
|
|
||||||
|
def generate_etudiants(self, ws: ScoExcelSheet):
|
||||||
|
ligne = 5
|
||||||
|
for etudiant in self.etudiants:
|
||||||
|
ws.set_cell(ligne, 1, etudiant.ident.id)
|
||||||
|
ws.set_cell(ligne, 2, etudiant.ident.code_nip)
|
||||||
|
ws.set_cell(ligne, 3, etudiant.ident.civilite)
|
||||||
|
ws.set_cell(ligne, 4, etudiant.ident.nom)
|
||||||
|
ws.set_cell(ligne, 5, etudiant.ident.prenom)
|
||||||
|
if etudiant.parcour:
|
||||||
|
ws.set_cell(ligne, 6, etudiant.parcour.code)
|
||||||
|
else:
|
||||||
|
ws.set_cell(ligne, 6, "-")
|
||||||
|
cursus = ", ".join(etudiant.history)
|
||||||
|
ws.set_cell(ligne, 7, cursus)
|
||||||
|
self.generate_data(ws, ligne, 10, etudiant)
|
||||||
|
ligne = ligne + 1
|
||||||
|
@ -284,9 +284,9 @@ class ScoExcelSheet:
|
|||||||
if idx < 26: # one letter key
|
if idx < 26: # one letter key
|
||||||
return chr(idx + 65)
|
return chr(idx + 65)
|
||||||
else: # two letters AA..ZZ
|
else: # two letters AA..ZZ
|
||||||
first = (idx // 26) + 66
|
first = idx // 26
|
||||||
second = (idx % 26) + 65
|
second = idx % 26
|
||||||
return "" + chr(first) + chr(second)
|
return "" + chr(first + 64) + chr(second + 65)
|
||||||
|
|
||||||
def set_cell(
|
def set_cell(
|
||||||
self,
|
self,
|
||||||
@ -332,6 +332,13 @@ class ScoExcelSheet:
|
|||||||
"""
|
"""
|
||||||
self.ws.row_dimensions[cle].hidden = value
|
self.ws.row_dimensions[cle].hidden = value
|
||||||
|
|
||||||
|
def set_column_dimension_hidden(self, cle, value):
|
||||||
|
"""Masque ou affiche une ligne.
|
||||||
|
cle -- identifie la colonne (1...)
|
||||||
|
value -- boolean (vrai = colonne cachée)
|
||||||
|
"""
|
||||||
|
self.ws.column_dimensions[cle].hidden = value
|
||||||
|
|
||||||
# def make_cell(self, value: any = None, style: Sco_Style = None, comment=None):
|
# def make_cell(self, value: any = None, style: Sco_Style = None, comment=None):
|
||||||
# """Construit une cellule.
|
# """Construit une cellule.
|
||||||
# value -- contenu de la cellule (texte, numérique, booléen ou date)
|
# value -- contenu de la cellule (texte, numérique, booléen ou date)
|
||||||
|
@ -90,6 +90,7 @@ class SCO_NUMBER_FORMAT(Enum):
|
|||||||
NONE = (0, None)
|
NONE = (0, None)
|
||||||
NUMBER_GENERAL = (0, FORMAT_GENERAL)
|
NUMBER_GENERAL = (0, FORMAT_GENERAL)
|
||||||
NUMBER_00 = (1, FORMAT_NUMBER_00)
|
NUMBER_00 = (1, FORMAT_NUMBER_00)
|
||||||
|
NUMBER_0 = (2, "0.0")
|
||||||
|
|
||||||
|
|
||||||
class SCO_HALIGN(Enum):
|
class SCO_HALIGN(Enum):
|
||||||
|
@ -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 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 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
|
||||||
@ -2493,7 +2494,19 @@ def formsemestre_validation_but(
|
|||||||
erase_span = f"""<a href="{
|
erase_span = f"""<a href="{
|
||||||
url_for("notes.formsemestre_jury_but_erase",
|
url_for("notes.formsemestre_jury_but_erase",
|
||||||
scodoc_dept=g.scodoc_dept, formsemestre_id=deca.formsemestre_id,
|
scodoc_dept=g.scodoc_dept, formsemestre_id=deca.formsemestre_id,
|
||||||
etudid=deca.etud.id)}" class="stdlink">effacer décisions</a>"""
|
etudid=deca.etud.id)}" class="stdlink"
|
||||||
|
title="efface décisions issues des jurys de cette année"
|
||||||
|
>effacer décisions</a>
|
||||||
|
|
||||||
|
<a style="margin-left: 16px;" class="stdlink"
|
||||||
|
href="{
|
||||||
|
url_for("notes.erase_decisions_annee_formation",
|
||||||
|
scodoc_dept=g.scodoc_dept, formation_id=deca.formsemestre.formation.id,
|
||||||
|
etudid=deca.etud.id, annee=deca.annee_but)}"
|
||||||
|
title="efface toutes décisions concernant le BUT{deca.annee_but}
|
||||||
|
de cet étudiant (même extérieures ou issues d'un redoublement)"
|
||||||
|
>effacer toutes ses décisions de BUT{deca.annee_but}</a>
|
||||||
|
"""
|
||||||
H.append(
|
H.append(
|
||||||
f"""<div class="but_settings">
|
f"""<div class="but_settings">
|
||||||
<input type="checkbox" onchange="enable_manual_codes(this)">
|
<input type="checkbox" onchange="enable_manual_codes(this)">
|
||||||
@ -2814,15 +2827,15 @@ def formsemestre_saisie_jury(formsemestre_id: int, selected_etudid: int = None):
|
|||||||
)
|
)
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoView)
|
@permission_required(Permission.ScoView)
|
||||||
def formsemestre_jury_but_erase(
|
def formsemestre_jury_but_erase(formsemestre_id: int, etudid: int = None):
|
||||||
formsemestre_id: int, etudid: int = None, only_one_sem=False
|
|
||||||
):
|
|
||||||
"""Supprime la décision de jury BUT pour cette année.
|
"""Supprime la décision de jury BUT pour cette année.
|
||||||
Si only_one_sem, n'efface que pour le formsemestre indiqué, pas les deux de l'année.
|
|
||||||
Si l'étudiant n'est pas spécifié, efface les décisions de tous les inscrits.
|
Si l'étudiant n'est pas spécifié, efface les décisions de tous les inscrits.
|
||||||
|
Si only_one_sem, n'efface que pour le formsemestre indiqué, pas les deux de l'année.
|
||||||
"""
|
"""
|
||||||
only_one_sem = int(request.args.get("only_one_sem") or False)
|
only_one_sem = int(request.args.get("only_one_sem") or False)
|
||||||
formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id)
|
formsemestre: FormSemestre = FormSemestre.query.filter_by(
|
||||||
|
id=formsemestre_id, dept_id=g.scodoc_dept_id
|
||||||
|
).first_or_404()
|
||||||
if not formsemestre.can_edit_jury():
|
if not formsemestre.can_edit_jury():
|
||||||
raise ScoPermissionDenied(
|
raise ScoPermissionDenied(
|
||||||
dest_url=url_for(
|
dest_url=url_for(
|
||||||
@ -2880,14 +2893,65 @@ def formsemestre_jury_but_erase(
|
|||||||
if only_one_sem
|
if only_one_sem
|
||||||
else """Les validations de toutes les UE, RCUE (compétences) et année
|
else """Les validations de toutes les UE, RCUE (compétences) et année
|
||||||
issues de cette année scolaire seront effacées.
|
issues de cette année scolaire seront effacées.
|
||||||
Les décisions des années scolaires précédentes ne seront pas modifiées.
|
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
+ """<div class="warning">Cette opération est irréversible !</div>""",
|
+ """
|
||||||
|
<p>Les décisions des années scolaires précédentes ne seront pas modifiées.</p>
|
||||||
|
<div class="warning">Cette opération est irréversible !</div>
|
||||||
|
""",
|
||||||
cancel_url=dest_url,
|
cancel_url=dest_url,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route(
|
||||||
|
"/erase_decisions_annee_formation/<int:etudid>/<int:formation_id>/<int:annee>",
|
||||||
|
methods=["GET", "POST"],
|
||||||
|
)
|
||||||
|
@scodoc
|
||||||
|
@permission_required(Permission.ScoEtudInscrit)
|
||||||
|
def erase_decisions_annee_formation(etudid: int, formation_id: int, annee: int):
|
||||||
|
"""Efface toute les décisions d'une année pour cet étudiant"""
|
||||||
|
etud: Identite = Identite.query.get_or_404(etudid)
|
||||||
|
formation: Formation = Formation.query.filter_by(
|
||||||
|
id=formation_id, dept_id=g.scodoc_dept_id
|
||||||
|
).first_or_404()
|
||||||
|
if request.method == "POST":
|
||||||
|
jury.erase_decisions_annee_formation(etud, formation, annee, delete=True)
|
||||||
|
flash("Décisions de jury effacées")
|
||||||
|
return redirect(
|
||||||
|
url_for(
|
||||||
|
"scolar.ficheEtud",
|
||||||
|
scodoc_dept=g.scodoc_dept,
|
||||||
|
etudid=etud.id,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
validations = jury.erase_decisions_annee_formation(etud, formation, annee)
|
||||||
|
return render_template(
|
||||||
|
"jury/erase_decisions_annee_formation.j2",
|
||||||
|
annee=annee,
|
||||||
|
cancel_url=url_for(
|
||||||
|
"scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etud.id
|
||||||
|
),
|
||||||
|
etud=etud,
|
||||||
|
formation=formation,
|
||||||
|
validations=validations,
|
||||||
|
sco=ScoData(),
|
||||||
|
title=f"Effacer décisions de jury {etud.nom} - année {annee}",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@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