forked from ScoDoc/ScoDoc
Compare commits
15 Commits
84f43e1b36
...
ba0062135b
Author | SHA1 | Date | |
---|---|---|---|
|
ba0062135b | ||
|
401a43378d | ||
44123c022e | |||
63784e341a | |||
cca72dfed2 | |||
5c951d58e7 | |||
202ce4e73e | |||
c81c4efb40 | |||
d877648546 | |||
58a8bcb83d | |||
fae11d82ce | |||
7a85ec7466 | |||
091a49cb0d | |||
ab212a5b2b | |||
a67515d560 |
@ -53,9 +53,10 @@ from app.models import ApcReferentielCompetences
|
|||||||
from app.scodoc.sco_abs import annule_absence, annule_justif
|
from app.scodoc.sco_abs import annule_absence, annule_justif
|
||||||
from app.scodoc.sco_bulletins import formsemestre_bulletinetud_dict
|
from app.scodoc.sco_bulletins import formsemestre_bulletinetud_dict
|
||||||
from app.scodoc.sco_bulletins_json import make_json_formsemestre_bulletinetud
|
from app.scodoc.sco_bulletins_json import make_json_formsemestre_bulletinetud
|
||||||
|
from app.scodoc.sco_evaluation_db import do_evaluation_get_all_notes
|
||||||
from app.scodoc.sco_formations import formation_export
|
from app.scodoc.sco_formations import formation_export
|
||||||
from app.scodoc.sco_formsemestre_inscriptions import do_formsemestre_inscription_listinscrits
|
from app.scodoc.sco_formsemestre_inscriptions import do_formsemestre_inscription_listinscrits
|
||||||
from app.scodoc.sco_groups import setGroups, get_etud_groups
|
from app.scodoc.sco_groups import setGroups, get_etud_groups, get_group_members
|
||||||
from app.scodoc.sco_moduleimpl import moduleimpl_list
|
from app.scodoc.sco_moduleimpl import moduleimpl_list
|
||||||
from app.scodoc.sco_permissions import Permission
|
from app.scodoc.sco_permissions import Permission
|
||||||
|
|
||||||
@ -63,6 +64,7 @@ from app.scodoc.sco_permissions import Permission
|
|||||||
############################################### Departements ##########################################################
|
############################################### Departements ##########################################################
|
||||||
from app.scodoc.sco_prepajury import feuille_preparation_jury
|
from app.scodoc.sco_prepajury import feuille_preparation_jury
|
||||||
from app.scodoc.sco_pvjury import formsemestre_pvjury
|
from app.scodoc.sco_pvjury import formsemestre_pvjury
|
||||||
|
from app.scodoc.sco_recapcomplet import formsemestre_recapcomplet
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/departements", methods=["GET"])
|
@bp.route("/departements", methods=["GET"])
|
||||||
@ -441,15 +443,29 @@ def bulletins(formsemestre_id: int):
|
|||||||
"""
|
"""
|
||||||
Les bulletins d'un formsemestre donné
|
Les bulletins d'un formsemestre donné
|
||||||
"""
|
"""
|
||||||
return error_response(501, message="Not implemented")
|
# fonction to use : formsemestre_recapcomplet
|
||||||
|
|
||||||
|
try:
|
||||||
|
data = formsemestre_recapcomplet(formsemestre_id)
|
||||||
|
except ValueError:
|
||||||
|
return error_response(409, message="La requête ne peut être traitée en l’état actuel")
|
||||||
|
|
||||||
|
return jsonify(data)
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/formsemestre/<int:formsemestre_id>/jury", methods=["GET"])
|
@bp.route("/formsemestre/<int:formsemestre_id>/jury", methods=["GET"])
|
||||||
def jury(formsemestre_id: int):
|
def jury(formsemestre_id: int):
|
||||||
"""
|
"""
|
||||||
|
Le récapitulatif des décisions jury
|
||||||
"""
|
"""
|
||||||
return error_response(501, message="Not implemented")
|
# fonction to use : formsemestre_pvjury
|
||||||
|
|
||||||
|
try:
|
||||||
|
data = formsemestre_pvjury(formsemestre_id)
|
||||||
|
except ValueError:
|
||||||
|
return error_response(409, message="La requête ne peut être traitée en l’état actuel")
|
||||||
|
|
||||||
|
return jsonify(data)
|
||||||
|
|
||||||
|
|
||||||
############################################### Partitions ############################################################
|
############################################### Partitions ############################################################
|
||||||
@ -467,15 +483,30 @@ def partition(formsemestre_id: int):
|
|||||||
return error_response(501, message="Not implemented")
|
return error_response(501, message="Not implemented")
|
||||||
|
|
||||||
|
|
||||||
@bp.route(
|
# @bp.route(
|
||||||
"/partitions/formsemestre/<int:formsemestre_id>/groups/group_ids?with_codes=&all_groups=&etat=",
|
# "/partitions/formsemestre/<int:formsemestre_id>/groups/group_ids?with_codes=&all_groups=&etat=",
|
||||||
methods=["GET"],
|
# methods=["GET"],
|
||||||
)
|
# )
|
||||||
def groups(formsemestre_id: int, group_ids: int):
|
@bp.route("/partitions/groups/<int:group_id>", methods=["GET"])
|
||||||
|
@bp.route("/partitions/groups/<int:group_id>/etat/<string:etat>", methods=["GET"])
|
||||||
|
def etud_in_group(group_id: int, etat=None):
|
||||||
"""
|
"""
|
||||||
Liste des étudiants dans un groupe
|
Liste des étudiants dans un groupe
|
||||||
"""
|
"""
|
||||||
return error_response(501, message="Not implemented")
|
# fonction to use : get_group_members
|
||||||
|
|
||||||
|
if etat is None:
|
||||||
|
try:
|
||||||
|
data = get_group_members(group_id)
|
||||||
|
except ValueError:
|
||||||
|
return error_response(409, message="La requête ne peut être traitée en l’état actuel")
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
data = get_group_members(group_id, etat)
|
||||||
|
except ValueError:
|
||||||
|
return error_response(409, message="La requête ne peut être traitée en l’état actuel")
|
||||||
|
|
||||||
|
return jsonify(data)
|
||||||
|
|
||||||
|
|
||||||
@bp.route(
|
@bp.route(
|
||||||
@ -516,12 +547,13 @@ def evaluation_notes(evaluation_id: int):
|
|||||||
"""
|
"""
|
||||||
Liste des notes à partir de l'id d'une évaluation donnée
|
Liste des notes à partir de l'id d'une évaluation donnée
|
||||||
"""
|
"""
|
||||||
notes = models.NotesNotes.query.filter_by(evaluation_id=evaluation_id).all()
|
# fonction to use : do_evaluation_get_all_notes
|
||||||
|
try:
|
||||||
data = [d.to_dict() for d in notes]
|
data = do_evaluation_get_all_notes(evaluation_id)
|
||||||
|
except ValueError:
|
||||||
|
return error_response(409, message="La requête ne peut être traitée en l’état actuel")
|
||||||
|
|
||||||
return jsonify(data)
|
return jsonify(data)
|
||||||
# return error_response(501, message="Not implemented")
|
|
||||||
|
|
||||||
|
|
||||||
@bp.route(
|
@bp.route(
|
||||||
@ -705,7 +737,7 @@ def abs_groupe_etat(
|
|||||||
Liste des absences d'un ou plusieurs groupes entre deux dates
|
Liste des absences d'un ou plusieurs groupes entre deux dates
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# list_abs_date
|
# list_abs_date<
|
||||||
return error_response(501, message="Not implemented")
|
return error_response(501, message="Not implemented")
|
||||||
|
|
||||||
|
|
||||||
|
@ -205,7 +205,8 @@ class BonusSportAdditif(BonusSport):
|
|||||||
"""calcul du bonus
|
"""calcul du bonus
|
||||||
sem_modimpl_moys_inscrits: les notes de sport
|
sem_modimpl_moys_inscrits: les notes de sport
|
||||||
En APC: ndarray (nb_etuds, nb_mod_sport, nb_ues_non_bonus)
|
En APC: ndarray (nb_etuds, nb_mod_sport, nb_ues_non_bonus)
|
||||||
modimpl_coefs_etuds_no_nan:
|
En classic: ndarray (nb_etuds, nb_mod_sport)
|
||||||
|
modimpl_coefs_etuds_no_nan: même shape, les coefs.
|
||||||
"""
|
"""
|
||||||
if 0 in sem_modimpl_moys_inscrits.shape:
|
if 0 in sem_modimpl_moys_inscrits.shape:
|
||||||
# pas d'étudiants ou pas d'UE ou pas de module...
|
# pas d'étudiants ou pas d'UE ou pas de module...
|
||||||
@ -228,12 +229,22 @@ class BonusSportAdditif(BonusSport):
|
|||||||
bonus_moy_arr = np.clip(bonus_moy_arr, 0.0, 20.0, out=bonus_moy_arr)
|
bonus_moy_arr = np.clip(bonus_moy_arr, 0.0, 20.0, out=bonus_moy_arr)
|
||||||
|
|
||||||
# en APC, bonus_moy_arr est (nb_etuds, nb_ues_non_bonus)
|
# en APC, bonus_moy_arr est (nb_etuds, nb_ues_non_bonus)
|
||||||
if self.formsemestre.formation.is_apc() or self.classic_use_bonus_ues:
|
if self.formsemestre.formation.is_apc():
|
||||||
# Bonus sur les UE et None sur moyenne générale
|
# Bonus sur les UE et None sur moyenne générale
|
||||||
ues_idx = [ue.id for ue in self.formsemestre.query_ues(with_sport=False)]
|
ues_idx = [ue.id for ue in self.formsemestre.query_ues(with_sport=False)]
|
||||||
self.bonus_ues = pd.DataFrame(
|
self.bonus_ues = pd.DataFrame(
|
||||||
bonus_moy_arr, index=self.etuds_idx, columns=ues_idx, dtype=float
|
bonus_moy_arr, index=self.etuds_idx, columns=ues_idx, dtype=float
|
||||||
)
|
)
|
||||||
|
elif self.classic_use_bonus_ues:
|
||||||
|
# Formations classiques apppliquant le bonus sur les UEs
|
||||||
|
# ici bonus_moy_arr = ndarray 1d nb_etuds
|
||||||
|
ues_idx = [ue.id for ue in self.formsemestre.query_ues(with_sport=False)]
|
||||||
|
self.bonus_ues = pd.DataFrame(
|
||||||
|
np.stack([bonus_moy_arr] * len(ues_idx)).T,
|
||||||
|
index=self.etuds_idx,
|
||||||
|
columns=ues_idx,
|
||||||
|
dtype=float,
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
# Bonus sur la moyenne générale seulement
|
# Bonus sur la moyenne générale seulement
|
||||||
self.bonus_moy_gen = pd.Series(
|
self.bonus_moy_gen = pd.Series(
|
||||||
@ -284,6 +295,7 @@ class BonusSportMultiplicatif(BonusSport):
|
|||||||
|
|
||||||
class BonusDirect(BonusSportAdditif):
|
class BonusDirect(BonusSportAdditif):
|
||||||
"""Bonus direct: les points sont directement ajoutés à la moyenne générale.
|
"""Bonus direct: les points sont directement ajoutés à la moyenne générale.
|
||||||
|
|
||||||
Les coefficients sont ignorés: tous les points de bonus sont sommés.
|
Les coefficients sont ignorés: tous les points de bonus sont sommés.
|
||||||
(rappel: la note est ramenée sur 20 avant application).
|
(rappel: la note est ramenée sur 20 avant application).
|
||||||
"""
|
"""
|
||||||
@ -294,47 +306,64 @@ class BonusDirect(BonusSportAdditif):
|
|||||||
proportion_point = 1.0
|
proportion_point = 1.0
|
||||||
|
|
||||||
|
|
||||||
class BonusAnnecy(BonusSport):
|
class BonusAmiens(BonusSportAdditif):
|
||||||
"""Calcul bonus modules optionnels (sport), règle IUT d'Annecy.
|
"""Bonus IUT Amiens pour les modules optionnels (sport, culture, ...).
|
||||||
Il peut y avoir plusieurs modules de bonus.
|
|
||||||
Prend pour chaque étudiant la meilleure de ses notes bonus et
|
Toute note non nulle, peu importe sa valeur, entraine un bonus de 0,1 point
|
||||||
ajoute à chaque UE :
|
sur toutes les moyennes d'UE.
|
||||||
0.05 point si >=10,
|
|
||||||
0.1 point si >=12,
|
|
||||||
0.15 point si >=14,
|
|
||||||
0.2 point si >=16,
|
|
||||||
0.25 point si >=18.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
name = "bonus_iut_annecy"
|
name = "bonus_amiens"
|
||||||
displayed_name = "IUT d'Annecy"
|
displayed_name = "IUT d'Amiens"
|
||||||
|
seuil_moy_gen = 0.0 # tous les points sont comptés
|
||||||
|
proportion_point = 1e10
|
||||||
|
bonus_max = 0.1
|
||||||
|
classic_use_bonus_ues = True # s'applique aux UEs en DUT et LP
|
||||||
|
|
||||||
def compute_bonus(self, sem_modimpl_moys_inscrits, modimpl_coefs_etuds_no_nan):
|
|
||||||
"""calcul du bonus"""
|
|
||||||
# if math.prod(sem_modimpl_moys_inscrits.shape) == 0:
|
|
||||||
# return # no etuds or no mod sport
|
|
||||||
# Prend la note de chaque modimpl, sans considération d'UE
|
|
||||||
if len(sem_modimpl_moys_inscrits.shape) > 2: # apc
|
|
||||||
sem_modimpl_moys_inscrits = sem_modimpl_moys_inscrits[:, :, 0]
|
|
||||||
# ici sem_modimpl_moys_inscrits est nb_etuds x nb_mods_bonus, en APC et en classic
|
|
||||||
note_bonus_max = np.max(sem_modimpl_moys_inscrits, axis=1) # 1d, nb_etuds
|
|
||||||
bonus = np.zeros(note_bonus_max.shape)
|
|
||||||
bonus[note_bonus_max >= 18.0] = 0.25
|
|
||||||
bonus[note_bonus_max >= 16.0] = 0.20
|
|
||||||
bonus[note_bonus_max >= 14.0] = 0.15
|
|
||||||
bonus[note_bonus_max >= 12.0] = 0.10
|
|
||||||
bonus[note_bonus_max >= 10.0] = 0.05
|
|
||||||
|
|
||||||
# Bonus moyenne générale et sur les UE
|
# Finalement ils n'en veulent pas.
|
||||||
self.bonus_moy_gen = pd.Series(bonus, index=self.etuds_idx, dtype=float)
|
# class BonusAnnecy(BonusSport):
|
||||||
ues_idx = [ue.id for ue in self.formsemestre.query_ues(with_sport=False)]
|
# """Calcul bonus modules optionnels (sport), règle IUT d'Annecy.
|
||||||
nb_ues_no_bonus = len(ues_idx)
|
|
||||||
self.bonus_ues = pd.DataFrame(
|
# Il peut y avoir plusieurs modules de bonus.
|
||||||
np.stack([bonus] * nb_ues_no_bonus, axis=1),
|
# Prend pour chaque étudiant la meilleure de ses notes bonus et
|
||||||
columns=ues_idx,
|
# ajoute à chaque UE :<br>
|
||||||
index=self.etuds_idx,
|
# 0.05 point si >=10,<br>
|
||||||
dtype=float,
|
# 0.1 point si >=12,<br>
|
||||||
)
|
# 0.15 point si >=14,<br>
|
||||||
|
# 0.2 point si >=16,<br>
|
||||||
|
# 0.25 point si >=18.
|
||||||
|
# """
|
||||||
|
|
||||||
|
# name = "bonus_iut_annecy"
|
||||||
|
# displayed_name = "IUT d'Annecy"
|
||||||
|
|
||||||
|
# def compute_bonus(self, sem_modimpl_moys_inscrits, modimpl_coefs_etuds_no_nan):
|
||||||
|
# """calcul du bonus"""
|
||||||
|
# # if math.prod(sem_modimpl_moys_inscrits.shape) == 0:
|
||||||
|
# # return # no etuds or no mod sport
|
||||||
|
# # Prend la note de chaque modimpl, sans considération d'UE
|
||||||
|
# if len(sem_modimpl_moys_inscrits.shape) > 2: # apc
|
||||||
|
# sem_modimpl_moys_inscrits = sem_modimpl_moys_inscrits[:, :, 0]
|
||||||
|
# # ici sem_modimpl_moys_inscrits est nb_etuds x nb_mods_bonus, en APC et en classic
|
||||||
|
# note_bonus_max = np.max(sem_modimpl_moys_inscrits, axis=1) # 1d, nb_etuds
|
||||||
|
# bonus = np.zeros(note_bonus_max.shape)
|
||||||
|
# bonus[note_bonus_max >= 10.0] = 0.05
|
||||||
|
# bonus[note_bonus_max >= 12.0] = 0.10
|
||||||
|
# bonus[note_bonus_max >= 14.0] = 0.15
|
||||||
|
# bonus[note_bonus_max >= 16.0] = 0.20
|
||||||
|
# bonus[note_bonus_max >= 18.0] = 0.25
|
||||||
|
|
||||||
|
# # Bonus moyenne générale et sur les UE
|
||||||
|
# self.bonus_moy_gen = pd.Series(bonus, index=self.etuds_idx, dtype=float)
|
||||||
|
# ues_idx = [ue.id for ue in self.formsemestre.query_ues(with_sport=False)]
|
||||||
|
# nb_ues_no_bonus = len(ues_idx)
|
||||||
|
# self.bonus_ues = pd.DataFrame(
|
||||||
|
# np.stack([bonus] * nb_ues_no_bonus, axis=1),
|
||||||
|
# columns=ues_idx,
|
||||||
|
# index=self.etuds_idx,
|
||||||
|
# dtype=float,
|
||||||
|
# )
|
||||||
|
|
||||||
|
|
||||||
class BonusBethune(BonusSportMultiplicatif):
|
class BonusBethune(BonusSportMultiplicatif):
|
||||||
@ -375,15 +404,16 @@ class BonusBezier(BonusSportAdditif):
|
|||||||
class BonusBordeaux1(BonusSportMultiplicatif):
|
class BonusBordeaux1(BonusSportMultiplicatif):
|
||||||
"""Calcul bonus modules optionnels (sport, culture), règle IUT Bordeaux 1, sur moyenne générale
|
"""Calcul bonus modules optionnels (sport, culture), règle IUT Bordeaux 1, sur moyenne générale
|
||||||
et UE.
|
et UE.
|
||||||
|
<p>
|
||||||
Les étudiants de l'IUT peuvent suivre des enseignements optionnels
|
Les étudiants de l'IUT peuvent suivre des enseignements optionnels
|
||||||
de l'Université Bordeaux 1 (sport, théâtre) non rattachés à une unité d'enseignement.
|
de l'Université Bordeaux 1 (sport, théâtre) non rattachés à une unité d'enseignement.
|
||||||
|
</p><p>
|
||||||
Chaque point au-dessus de 10 sur 20 obtenus dans cet enseignement correspond à un %
|
Chaque point au-dessus de 10 sur 20 obtenus dans cet enseignement correspond à un %
|
||||||
qui augmente la moyenne de chaque UE et la moyenne générale.
|
qui augmente la moyenne de chaque UE et la moyenne générale.<br>
|
||||||
Formule : le % = points>moyenne / 2
|
Formule : pourcentage = (points au dessus de 10) / 2
|
||||||
|
</p><p>
|
||||||
Par exemple : sport 13/20 : chaque UE sera multipliée par 1+0,015, ainsi que la moyenne générale.
|
Par exemple : sport 13/20 : chaque UE sera multipliée par 1+0,015, ainsi que la moyenne générale.
|
||||||
|
</p>
|
||||||
"""
|
"""
|
||||||
|
|
||||||
name = "bonus_iutBordeaux1"
|
name = "bonus_iutBordeaux1"
|
||||||
@ -393,6 +423,68 @@ class BonusBordeaux1(BonusSportMultiplicatif):
|
|||||||
amplitude = 0.005
|
amplitude = 0.005
|
||||||
|
|
||||||
|
|
||||||
|
class BonusCachan1(BonusSportAdditif):
|
||||||
|
"""Calcul bonus optionnels (sport, culture), règle IUT de Cachan 1.
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li> DUT/LP : la meilleure note d'option, si elle est supérieure à 10,
|
||||||
|
bonifie les moyennes d'UE (<b>sauf l'UE41 dont le code est UE41_E</b>) à raison
|
||||||
|
de <em>bonus = (option - 10)/10</em>.
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li> BUT : la meilleure note d'option, si elle est supérieure à 10, bonifie
|
||||||
|
les moyennes d'UE à raison de <em>bonus = (option - 10)*5%</em>.</li>
|
||||||
|
</ul>
|
||||||
|
"""
|
||||||
|
|
||||||
|
name = "bonus_cachan1"
|
||||||
|
displayed_name = "IUT de Cachan 1"
|
||||||
|
seuil_moy_gen = 10.0 # tous les points sont comptés
|
||||||
|
proportion_point = 0.05
|
||||||
|
classic_use_bonus_ues = True
|
||||||
|
|
||||||
|
def compute_bonus(self, sem_modimpl_moys_inscrits, modimpl_coefs_etuds_no_nan):
|
||||||
|
"""calcul du bonus, avec réglage différent suivant le type de formation"""
|
||||||
|
# Prend la note de chaque modimpl, sans considération d'UE
|
||||||
|
if len(sem_modimpl_moys_inscrits.shape) > 2: # apc
|
||||||
|
sem_modimpl_moys_inscrits = sem_modimpl_moys_inscrits[:, :, 0]
|
||||||
|
# ici sem_modimpl_moys_inscrits est nb_etuds x nb_mods_bonus, en APC et en classic
|
||||||
|
note_bonus_max = np.max(sem_modimpl_moys_inscrits, axis=1) # 1d, nb_etuds
|
||||||
|
ues = self.formsemestre.query_ues(with_sport=False).all()
|
||||||
|
ues_idx = [ue.id for ue in ues]
|
||||||
|
|
||||||
|
if self.formsemestre.formation.is_apc(): # --- BUT
|
||||||
|
bonus_moy_arr = np.where(
|
||||||
|
note_bonus_max > self.seuil_moy_gen,
|
||||||
|
(note_bonus_max - self.seuil_moy_gen) * self.proportion_point,
|
||||||
|
0.0,
|
||||||
|
)
|
||||||
|
self.bonus_ues = pd.DataFrame(
|
||||||
|
np.stack([bonus_moy_arr] * len(ues)).T,
|
||||||
|
index=self.etuds_idx,
|
||||||
|
columns=ues_idx,
|
||||||
|
dtype=float,
|
||||||
|
)
|
||||||
|
else: # --- DUT
|
||||||
|
# pareil mais proportion différente et exclusion d'une UE
|
||||||
|
proportion_point = 0.1
|
||||||
|
bonus_moy_arr = np.where(
|
||||||
|
note_bonus_max > self.seuil_moy_gen,
|
||||||
|
(note_bonus_max - self.seuil_moy_gen) * proportion_point,
|
||||||
|
0.0,
|
||||||
|
)
|
||||||
|
self.bonus_ues = pd.DataFrame(
|
||||||
|
np.stack([bonus_moy_arr] * len(ues)).T,
|
||||||
|
index=self.etuds_idx,
|
||||||
|
columns=ues_idx,
|
||||||
|
dtype=float,
|
||||||
|
)
|
||||||
|
# Pas de bonus sur la ou les ue de code "UE41_E"
|
||||||
|
ue_exclues = [ue for ue in ues if ue.ue_code == "UE41_E"]
|
||||||
|
for ue in ue_exclues:
|
||||||
|
self.bonus_ues[ue.id] = 0.0
|
||||||
|
|
||||||
|
|
||||||
class BonusColmar(BonusSportAdditif):
|
class BonusColmar(BonusSportAdditif):
|
||||||
"""Calcul bonus modules optionnels (sport, culture), règle IUT Colmar.
|
"""Calcul bonus modules optionnels (sport, culture), règle IUT Colmar.
|
||||||
|
|
||||||
@ -417,19 +509,21 @@ class BonusColmar(BonusSportAdditif):
|
|||||||
class BonusGrenobleIUT1(BonusSportMultiplicatif):
|
class BonusGrenobleIUT1(BonusSportMultiplicatif):
|
||||||
"""Bonus IUT1 de Grenoble
|
"""Bonus IUT1 de Grenoble
|
||||||
|
|
||||||
|
<p>
|
||||||
À compter de sept. 2021:
|
À compter de sept. 2021:
|
||||||
La note de sport est sur 20, et on calcule une bonification (en %)
|
La note de sport est sur 20, et on calcule une bonification (en %)
|
||||||
qui va s'appliquer à la moyenne de chaque UE du semestre en appliquant
|
qui va s'appliquer à la moyenne de chaque UE du semestre en appliquant
|
||||||
la formule : bonification (en %) = (note-10)*0,5.
|
la formule : bonification (en %) = (note-10)*0,5.
|
||||||
|
</p><p>
|
||||||
Bonification qui ne s'applique que si la note est >10.
|
<em>La bonification ne s'applique que si la note est supérieure à 10.</em>
|
||||||
|
</p><p>
|
||||||
(Une note de 10 donne donc 0% de bonif ; note de 20 : 5% de bonif)
|
(Une note de 10 donne donc 0% de bonif, et une note de 20 : 5% de bonif)
|
||||||
|
</p><p>
|
||||||
Avant sept. 2021, la note de sport allait de 0 à 5 points (sur 20).
|
Avant sept. 2021, la note de sport allait de 0 à 5 points (sur 20).
|
||||||
Chaque point correspondait à 0.25% d'augmentation de la moyenne
|
Chaque point correspondait à 0.25% d'augmentation de la moyenne
|
||||||
générale.
|
générale.
|
||||||
Par exemple : note de sport 2/5 : la moyenne générale était augmentée de 0.5%.
|
Par exemple : note de sport 2/5 : la moyenne générale était augmentée de 0.5%.
|
||||||
|
</p>
|
||||||
"""
|
"""
|
||||||
|
|
||||||
name = "bonus_iut1grenoble_2017"
|
name = "bonus_iut1grenoble_2017"
|
||||||
@ -456,9 +550,11 @@ class BonusGrenobleIUT1(BonusSportMultiplicatif):
|
|||||||
class BonusLaRochelle(BonusSportAdditif):
|
class BonusLaRochelle(BonusSportAdditif):
|
||||||
"""Calcul bonus modules optionnels (sport, culture), règle IUT de La Rochelle.
|
"""Calcul bonus modules optionnels (sport, culture), règle IUT de La Rochelle.
|
||||||
|
|
||||||
Si la note de sport est comprise entre 0 et 10 : pas d'ajout de point.
|
<ul>
|
||||||
Si la note de sport est comprise entre 10 et 20 : ajout de 1% de cette
|
<li>Si la note de sport est comprise entre 0 et 10 : pas d'ajout de point.</li>
|
||||||
note sur la moyenne générale du semestre (ou sur les UE en BUT).
|
<li>Si la note de sport est comprise entre 10 et 20 : ajout de 1% de cette
|
||||||
|
note sur la moyenne générale du semestre (ou sur les UE en BUT).</li>
|
||||||
|
</ul>
|
||||||
"""
|
"""
|
||||||
|
|
||||||
name = "bonus_iutlr"
|
name = "bonus_iutlr"
|
||||||
@ -483,16 +579,17 @@ class BonusLeHavre(BonusSportMultiplicatif):
|
|||||||
class BonusLeMans(BonusSportAdditif):
|
class BonusLeMans(BonusSportAdditif):
|
||||||
"""Calcul bonus modules optionnels (sport, culture), règle IUT Le Mans.
|
"""Calcul bonus modules optionnels (sport, culture), règle IUT Le Mans.
|
||||||
|
|
||||||
Les points au-dessus de 10 sur 20 obtenus dans chacune des matières
|
<p>Les points au-dessus de 10 sur 20 obtenus dans chacune des matières
|
||||||
optionnelles sont cumulés.
|
optionnelles sont cumulés.
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li>En BUT: la moyenne de chacune des UE du semestre est augmentée de
|
||||||
|
2% du cumul des points de bonus;</li>
|
||||||
|
|
||||||
|
<li>En DUT/LP: la moyenne générale est augmentée de 5% du cumul des points bonus.
|
||||||
En BUT: la moyenne de chacune des UE du semestre est augmentée de
|
</li>
|
||||||
2% du cumul des points de bonus,
|
</ul>
|
||||||
|
<p>Dans tous les cas, le bonus est dans la limite de 0,5 point.</p>
|
||||||
En DUT/LP: la moyenne générale est augmentée de 5% du cumul des points bonus.
|
|
||||||
|
|
||||||
Dans tous les cas, le bonus est dans la limite de 0,5 point.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
name = "bonus_iutlemans"
|
name = "bonus_iutlemans"
|
||||||
@ -516,12 +613,13 @@ class BonusLeMans(BonusSportAdditif):
|
|||||||
class BonusLille(BonusSportAdditif):
|
class BonusLille(BonusSportAdditif):
|
||||||
"""Calcul bonus modules optionnels (sport, culture), règle IUT Villeneuve d'Ascq
|
"""Calcul bonus modules optionnels (sport, culture), règle IUT Villeneuve d'Ascq
|
||||||
|
|
||||||
Les étudiants de l'IUT peuvent suivre des enseignements optionnels
|
<p>Les étudiants de l'IUT peuvent suivre des enseignements optionnels
|
||||||
de l'Université Lille (sports, etc) non rattachés à une unité d'enseignement.
|
de l'Université Lille (sports, etc) non rattachés à une unité d'enseignement.
|
||||||
|
</p><p>
|
||||||
Les points au-dessus de 10 sur 20 obtenus dans chacune des matières
|
Les points au-dessus de 10 sur 20 obtenus dans chacune des matières
|
||||||
optionnelles sont cumulés et 4% (2% avant août 2010) de ces points cumulés
|
optionnelles sont cumulés et 4% (2% avant août 2010) de ces points cumulés
|
||||||
s'ajoutent à la moyenne générale du semestre déjà obtenue par l'étudiant.
|
s'ajoutent à la moyenne générale du semestre déjà obtenue par l'étudiant.
|
||||||
|
</p>
|
||||||
"""
|
"""
|
||||||
|
|
||||||
name = "bonus_lille"
|
name = "bonus_lille"
|
||||||
@ -573,17 +671,19 @@ class BonusMulhouse(BonusSportAdditif):
|
|||||||
class BonusNantes(BonusSportAdditif):
|
class BonusNantes(BonusSportAdditif):
|
||||||
"""IUT de Nantes (Septembre 2018)
|
"""IUT de Nantes (Septembre 2018)
|
||||||
|
|
||||||
Nous avons différents types de bonification
|
<p>Nous avons différents types de bonification
|
||||||
(sport, culture, engagement citoyen).
|
(sport, culture, engagement citoyen).
|
||||||
|
</p><p>
|
||||||
Nous ajoutons aux moyennes une bonification de 0,2 pour chaque item
|
Nous ajoutons aux moyennes une bonification de 0,2 pour chaque item
|
||||||
la bonification totale ne doit pas excéder les 0,5 point.
|
la bonification totale ne doit pas excéder les 0,5 point.
|
||||||
Sur le bulletin nous ne mettons pas une note sur 20 mais directement les bonifications.
|
Sur le bulletin nous ne mettons pas une note sur 20 mais directement les bonifications.
|
||||||
|
</p><p>
|
||||||
Dans ScoDoc: on a déclarera une UE "sport&culture" dans laquelle on aura des modules
|
Dans ScoDoc: on a déclarera une UE "sport&culture" dans laquelle on aura
|
||||||
pour chaque activité (Sport, Associations, ...)
|
des modules pour chaque activité (Sport, Associations, ...)
|
||||||
avec à chaque fois une note (ScoDoc l'affichera comme une note sur 20, mais en fait ce sera la
|
avec à chaque fois une note (ScoDoc l'affichera comme une note sur 20,
|
||||||
valeur de la bonification: entrer 0,1/20 signifiera un bonus de 0,1 point la moyenne générale)
|
mais en fait ce sera la valeur de la bonification: entrer 0,1/20 signifiera
|
||||||
|
un bonus de 0,1 point la moyenne générale).
|
||||||
|
</p>
|
||||||
"""
|
"""
|
||||||
|
|
||||||
name = "bonus_nantes"
|
name = "bonus_nantes"
|
||||||
@ -604,7 +704,7 @@ class BonusRoanne(BonusSportAdditif):
|
|||||||
displayed_name = "IUT de Roanne"
|
displayed_name = "IUT de Roanne"
|
||||||
seuil_moy_gen = 0.0
|
seuil_moy_gen = 0.0
|
||||||
bonus_max = 0.6 # plafonnement à 0.6 points
|
bonus_max = 0.6 # plafonnement à 0.6 points
|
||||||
apply_bonus_mg_to_ues = True # sur les UE, même en DUT et LP
|
classic_use_bonus_ues = True # sur les UE, même en DUT et LP
|
||||||
|
|
||||||
|
|
||||||
class BonusStDenis(BonusSportAdditif):
|
class BonusStDenis(BonusSportAdditif):
|
||||||
@ -627,13 +727,14 @@ class BonusStDenis(BonusSportAdditif):
|
|||||||
class BonusTours(BonusDirect):
|
class BonusTours(BonusDirect):
|
||||||
"""Calcul bonus sport & culture IUT Tours.
|
"""Calcul bonus sport & culture IUT Tours.
|
||||||
|
|
||||||
Les notes des UE bonus (ramenées sur 20) sont sommées
|
<p>Les notes des UE bonus (ramenées sur 20) sont sommées
|
||||||
et 1/40 (2,5%) est ajouté aux moyennes: soit à la moyenne générale,
|
et 1/40 (2,5%) est ajouté aux moyennes: soit à la moyenne générale,
|
||||||
soit pour le BUT à chaque moyenne d'UE.
|
soit pour le BUT à chaque moyenne d'UE.
|
||||||
|
</p><p>
|
||||||
Attention: en GEII, facteur 1/40, ailleurs facteur 1.
|
<em>Attention: en GEII, facteur 1/40, ailleurs facteur 1.</em>
|
||||||
|
</p><p>
|
||||||
Le bonus total est limité à 1 point.
|
Le bonus total est limité à 1 point.
|
||||||
|
</p>
|
||||||
"""
|
"""
|
||||||
|
|
||||||
name = "bonus_tours"
|
name = "bonus_tours"
|
||||||
@ -658,11 +759,13 @@ class BonusVilleAvray(BonusSport):
|
|||||||
|
|
||||||
Les étudiants de l'IUT peuvent suivre des enseignements optionnels
|
Les étudiants de l'IUT peuvent suivre des enseignements optionnels
|
||||||
de l'Université Paris 10 (C2I) non rattachés à une unité d'enseignement.
|
de l'Université Paris 10 (C2I) non rattachés à une unité d'enseignement.
|
||||||
Si la note est >= 10 et < 12, bonus de 0.1 point
|
<ul>
|
||||||
Si la note est >= 12 et < 16, bonus de 0.2 point
|
<li>Si la note est >= 10 et < 12, bonus de 0.1 point</li>
|
||||||
Si la note est >= 16, bonus de 0.3 point
|
<li>Si la note est >= 12 et < 16, bonus de 0.2 point</li>
|
||||||
Ce bonus s'ajoute à la moyenne générale du semestre déjà obtenue par
|
<li>Si la note est >= 16, bonus de 0.3 point</li>
|
||||||
l'étudiant.
|
</ul>
|
||||||
|
<p>Ce bonus s'ajoute à la moyenne générale du semestre déjà obtenue par
|
||||||
|
l'étudiant.</p>
|
||||||
"""
|
"""
|
||||||
|
|
||||||
name = "bonus_iutva"
|
name = "bonus_iutva"
|
||||||
@ -700,7 +803,7 @@ class BonusIUTV(BonusSportAdditif):
|
|||||||
|
|
||||||
name = "bonus_iutv"
|
name = "bonus_iutv"
|
||||||
displayed_name = "IUT de Villetaneuse"
|
displayed_name = "IUT de Villetaneuse"
|
||||||
pass # oui, c'ets le bonus par défaut
|
pass # oui, c'est le bonus par défaut
|
||||||
|
|
||||||
|
|
||||||
def get_bonus_class_dict(start=BonusSport, d=None):
|
def get_bonus_class_dict(start=BonusSport, d=None):
|
||||||
|
@ -335,15 +335,17 @@ class ModuleImplResultsAPC(ModuleImplResults):
|
|||||||
notes_rat / (eval_rat.note_max / 20.0),
|
notes_rat / (eval_rat.note_max / 20.0),
|
||||||
np.nan,
|
np.nan,
|
||||||
)
|
)
|
||||||
|
# "Étend" le rattrapage sur les UE: la note de rattrapage est la même
|
||||||
|
# pour toutes les UE mais ne remplace que là où elle est supérieure
|
||||||
|
notes_rat_ues = np.stack([notes_rat] * nb_ues, axis=1)
|
||||||
# prend le max
|
# prend le max
|
||||||
etuds_use_rattrapage = notes_rat > etuds_moy_module
|
etuds_use_rattrapage = notes_rat_ues > etuds_moy_module
|
||||||
etuds_moy_module = np.where(
|
etuds_moy_module = np.where(
|
||||||
etuds_use_rattrapage[:, np.newaxis],
|
etuds_use_rattrapage, notes_rat_ues, etuds_moy_module
|
||||||
np.tile(notes_rat[:, np.newaxis], nb_ues),
|
|
||||||
etuds_moy_module,
|
|
||||||
)
|
)
|
||||||
|
# Serie indiquant que l'étudiant utilise une note de rattarage sur l'une des UE:
|
||||||
self.etuds_use_rattrapage = pd.Series(
|
self.etuds_use_rattrapage = pd.Series(
|
||||||
etuds_use_rattrapage, index=self.evals_notes.index
|
etuds_use_rattrapage.any(axis=1), index=self.evals_notes.index
|
||||||
)
|
)
|
||||||
self.etuds_moy_module = pd.DataFrame(
|
self.etuds_moy_module = pd.DataFrame(
|
||||||
etuds_moy_module,
|
etuds_moy_module,
|
||||||
@ -359,6 +361,10 @@ def load_evaluations_poids(moduleimpl_id: int) -> tuple[pd.DataFrame, list]:
|
|||||||
Les valeurs manquantes (évaluations sans coef vers des UE) sont
|
Les valeurs manquantes (évaluations sans coef vers des UE) sont
|
||||||
remplies: 1 si le coef de ce module dans l'UE est non nul, zéro sinon
|
remplies: 1 si le coef de ce module dans l'UE est non nul, zéro sinon
|
||||||
(sauf pour module bonus, defaut à 1)
|
(sauf pour module bonus, defaut à 1)
|
||||||
|
|
||||||
|
Si le module n'est pas une ressource ou une SAE, ne charge pas de poids
|
||||||
|
et renvoie toujours les poids par défaut.
|
||||||
|
|
||||||
Résultat: (evals_poids, liste de UEs du semestre sauf le sport)
|
Résultat: (evals_poids, liste de UEs du semestre sauf le sport)
|
||||||
"""
|
"""
|
||||||
modimpl: ModuleImpl = ModuleImpl.query.get(moduleimpl_id)
|
modimpl: ModuleImpl = ModuleImpl.query.get(moduleimpl_id)
|
||||||
@ -367,6 +373,10 @@ def load_evaluations_poids(moduleimpl_id: int) -> tuple[pd.DataFrame, list]:
|
|||||||
ue_ids = [ue.id for ue in ues]
|
ue_ids = [ue.id for ue in ues]
|
||||||
evaluation_ids = [evaluation.id for evaluation in evaluations]
|
evaluation_ids = [evaluation.id for evaluation in evaluations]
|
||||||
evals_poids = pd.DataFrame(columns=ue_ids, index=evaluation_ids, dtype=float)
|
evals_poids = pd.DataFrame(columns=ue_ids, index=evaluation_ids, dtype=float)
|
||||||
|
if (
|
||||||
|
modimpl.module.module_type == ModuleType.RESSOURCE
|
||||||
|
or modimpl.module.module_type == ModuleType.SAE
|
||||||
|
):
|
||||||
for ue_poids in EvaluationUEPoids.query.join(
|
for ue_poids in EvaluationUEPoids.query.join(
|
||||||
EvaluationUEPoids.evaluation
|
EvaluationUEPoids.evaluation
|
||||||
).filter_by(moduleimpl_id=moduleimpl_id):
|
).filter_by(moduleimpl_id=moduleimpl_id):
|
||||||
|
@ -55,6 +55,9 @@ def create_dept(acronym: str, visible=True) -> Departement:
|
|||||||
"Create new departement"
|
"Create new departement"
|
||||||
from app.models import ScoPreference
|
from app.models import ScoPreference
|
||||||
|
|
||||||
|
existing = Departement.query.filter_by(acronym=acronym).count()
|
||||||
|
if existing:
|
||||||
|
raise ValueError(f"acronyme {acronym} déjà existant")
|
||||||
departement = Departement(acronym=acronym, visible=visible)
|
departement = Departement(acronym=acronym, visible=visible)
|
||||||
p1 = ScoPreference(name="DeptName", value=acronym, departement=departement)
|
p1 = ScoPreference(name="DeptName", value=acronym, departement=departement)
|
||||||
db.session.add(p1)
|
db.session.add(p1)
|
||||||
|
@ -500,6 +500,13 @@ def module_edit(module_id=None):
|
|||||||
matieres = matieres.filter(UniteEns.semestre_idx == a_module.ue.semestre_idx)
|
matieres = matieres.filter(UniteEns.semestre_idx == a_module.ue.semestre_idx)
|
||||||
|
|
||||||
if is_apc:
|
if is_apc:
|
||||||
|
# ne conserve que la 1ere matière de chaque UE,
|
||||||
|
# et celle à laquelle ce module est rattaché
|
||||||
|
matieres = [
|
||||||
|
mat
|
||||||
|
for mat in matieres
|
||||||
|
if a_module.matiere.id == mat.id or mat.id == mat.ue.matieres.first().id
|
||||||
|
]
|
||||||
mat_names = [
|
mat_names = [
|
||||||
"S%s / %s" % (mat.ue.semestre_idx, mat.ue.acronyme) for mat in matieres
|
"S%s / %s" % (mat.ue.semestre_idx, mat.ue.acronyme) for mat in matieres
|
||||||
]
|
]
|
||||||
|
@ -601,7 +601,12 @@ def ue_table(formation_id=None, semestre_idx=1, msg=""): # was ue_list
|
|||||||
_add_ue_semestre_id(ues_externes, is_apc)
|
_add_ue_semestre_id(ues_externes, is_apc)
|
||||||
ues.sort(key=lambda u: (u["semestre_id"], u["numero"]))
|
ues.sort(key=lambda u: (u["semestre_id"], u["numero"]))
|
||||||
ues_externes.sort(key=lambda u: (u["semestre_id"], u["numero"]))
|
ues_externes.sort(key=lambda u: (u["semestre_id"], u["numero"]))
|
||||||
has_duplicate_ue_codes = len(set([ue["ue_code"] for ue in ues])) != len(ues)
|
# Codes dupliqués (pour aider l'utilisateur)
|
||||||
|
seen = set()
|
||||||
|
duplicated_codes = {
|
||||||
|
ue["ue_code"] for ue in ues if ue["ue_code"] in seen or seen.add(ue["ue_code"])
|
||||||
|
}
|
||||||
|
ues_with_duplicated_code = [ue for ue in ues if ue["ue_code"] in duplicated_codes]
|
||||||
|
|
||||||
has_perm_change = current_user.has_permission(Permission.ScoChangeFormation)
|
has_perm_change = current_user.has_permission(Permission.ScoChangeFormation)
|
||||||
# editable = (not locked) and has_perm_change
|
# editable = (not locked) and has_perm_change
|
||||||
@ -664,11 +669,17 @@ du programme" (menu "Semestre") si vous avez un semestre en cours);
|
|||||||
if msg:
|
if msg:
|
||||||
H.append('<p class="msg">' + msg + "</p>")
|
H.append('<p class="msg">' + msg + "</p>")
|
||||||
|
|
||||||
if has_duplicate_ue_codes:
|
if ues_with_duplicated_code:
|
||||||
H.append(
|
H.append(
|
||||||
"""<div class="ue_warning"><span>Attention: plusieurs UE de cette
|
f"""<div class="ue_warning"><span>Attention: plusieurs UE de cette
|
||||||
formation ont le même code. Il faut corriger cela ci-dessous,
|
formation ont le même code : <tt>{
|
||||||
sinon les calculs d'ECTS seront erronés !</span></div>"""
|
', '.join([
|
||||||
|
'<a class="stdlink" href="' + url_for( "notes.ue_edit", scodoc_dept=g.scodoc_dept, ue_id=ue["ue_id"] )
|
||||||
|
+ '">' + ue["acronyme"] + " (code " + ue["ue_code"] + ")</a>"
|
||||||
|
for ue in ues_with_duplicated_code ])
|
||||||
|
}</tt>.
|
||||||
|
Il faut corriger cela, sinon les capitalisations et ECTS seront
|
||||||
|
erronés !</span></div>"""
|
||||||
)
|
)
|
||||||
|
|
||||||
# Description de la formation
|
# Description de la formation
|
||||||
@ -930,8 +941,8 @@ def _ue_table_ues(
|
|||||||
|
|
||||||
if cur_ue_semestre_id != ue["semestre_id"]:
|
if cur_ue_semestre_id != ue["semestre_id"]:
|
||||||
cur_ue_semestre_id = ue["semestre_id"]
|
cur_ue_semestre_id = ue["semestre_id"]
|
||||||
if iue > 0:
|
# if iue > 0:
|
||||||
H.append("</ul>")
|
# H.append("</ul>")
|
||||||
if ue["semestre_id"] == sco_codes_parcours.UE_SEM_DEFAULT:
|
if ue["semestre_id"] == sco_codes_parcours.UE_SEM_DEFAULT:
|
||||||
lab = "Pas d'indication de semestre:"
|
lab = "Pas d'indication de semestre:"
|
||||||
else:
|
else:
|
||||||
@ -953,7 +964,6 @@ def _ue_table_ues(
|
|||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
H.append(arrow_none)
|
H.append(arrow_none)
|
||||||
iue += 1
|
|
||||||
ue["acro_titre"] = str(ue["acronyme"])
|
ue["acro_titre"] = str(ue["acronyme"])
|
||||||
if ue["titre"] != ue["acronyme"]:
|
if ue["titre"] != ue["acronyme"]:
|
||||||
ue["acro_titre"] += " " + str(ue["titre"])
|
ue["acro_titre"] += " " + str(ue["titre"])
|
||||||
@ -1001,6 +1011,14 @@ def _ue_table_ues(
|
|||||||
delete_disabled_icon,
|
delete_disabled_icon,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
if (iue >= len(ues) - 1) or ue["semestre_id"] != ues[iue + 1]["semestre_id"]:
|
||||||
|
H.append(
|
||||||
|
f"""</ul><ul><li><a href="{url_for('notes.ue_create', scodoc_dept=g.scodoc_dept,
|
||||||
|
formation_id=ue['formation_id'], semestre_idx=ue['semestre_id'])
|
||||||
|
}">Ajouter une UE dans le semestre {ue['semestre_id'] or ''}</a></li></ul>"""
|
||||||
|
)
|
||||||
|
iue += 1
|
||||||
|
|
||||||
return "\n".join(H)
|
return "\n".join(H)
|
||||||
|
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ from app.scodoc.sco_exceptions import ScoValueError
|
|||||||
|
|
||||||
|
|
||||||
def apo_semset_maq_status(
|
def apo_semset_maq_status(
|
||||||
semset_id="",
|
semset_id: int,
|
||||||
allow_missing_apo=False,
|
allow_missing_apo=False,
|
||||||
allow_missing_decisions=False,
|
allow_missing_decisions=False,
|
||||||
allow_missing_csv=False,
|
allow_missing_csv=False,
|
||||||
@ -65,7 +65,7 @@ def apo_semset_maq_status(
|
|||||||
):
|
):
|
||||||
"""Page statut / tableau de bord"""
|
"""Page statut / tableau de bord"""
|
||||||
if not semset_id:
|
if not semset_id:
|
||||||
raise ValueError("invalid null semset_id")
|
raise ScoValueError("invalid null semset_id")
|
||||||
semset = sco_semset.SemSet(semset_id=semset_id)
|
semset = sco_semset.SemSet(semset_id=semset_id)
|
||||||
semset.fill_formsemestres()
|
semset.fill_formsemestres()
|
||||||
# autorise export meme si etudiants Apo manquants:
|
# autorise export meme si etudiants Apo manquants:
|
||||||
|
@ -405,7 +405,6 @@ def formsemestre_evaluations_cal(formsemestre_id):
|
|||||||
"""Page avec calendrier de toutes les evaluations de ce semestre"""
|
"""Page avec calendrier de toutes les evaluations de ce semestre"""
|
||||||
formsemestre = FormSemestre.query.get_or_404(formsemestre_id)
|
formsemestre = FormSemestre.query.get_or_404(formsemestre_id)
|
||||||
nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
|
nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
|
||||||
sem = formsemestre.to_dict()
|
|
||||||
|
|
||||||
evals = nt.get_evaluations_etats()
|
evals = nt.get_evaluations_etats()
|
||||||
nb_evals = len(evals)
|
nb_evals = len(evals)
|
||||||
@ -416,8 +415,8 @@ def formsemestre_evaluations_cal(formsemestre_id):
|
|||||||
|
|
||||||
today = time.strftime("%Y-%m-%d")
|
today = time.strftime("%Y-%m-%d")
|
||||||
|
|
||||||
year = int(sem["annee_debut"])
|
year = formsemestre.date_debut.year
|
||||||
if sem["mois_debut_ord"] < 8:
|
if formsemestre.date_debut.month < 8:
|
||||||
year -= 1 # calendrier septembre a septembre
|
year -= 1 # calendrier septembre a septembre
|
||||||
events = {} # (day, halfday) : event
|
events = {} # (day, halfday) : event
|
||||||
for e in evals:
|
for e in evals:
|
||||||
@ -537,11 +536,10 @@ def formsemestre_evaluations_delai_correction(formsemestre_id, format="html"):
|
|||||||
"""Experimental: un tableau indiquant pour chaque évaluation
|
"""Experimental: un tableau indiquant pour chaque évaluation
|
||||||
le nombre de jours avant la publication des notes.
|
le nombre de jours avant la publication des notes.
|
||||||
|
|
||||||
N'indique pas les évaluations de ratrapage ni celles des modules de bonus/malus.
|
N'indique pas les évaluations de rattrapage ni celles des modules de bonus/malus.
|
||||||
"""
|
"""
|
||||||
formsemestre = FormSemestre.query.get_or_404(formsemestre_id)
|
formsemestre = FormSemestre.query.get_or_404(formsemestre_id)
|
||||||
nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
|
nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
|
||||||
sem = formsemestre.to_dict()
|
|
||||||
|
|
||||||
evals = nt.get_evaluations_etats()
|
evals = nt.get_evaluations_etats()
|
||||||
T = []
|
T = []
|
||||||
@ -607,7 +605,7 @@ def formsemestre_evaluations_delai_correction(formsemestre_id, format="html"):
|
|||||||
origin="Généré par %s le " % sco_version.SCONAME
|
origin="Généré par %s le " % sco_version.SCONAME
|
||||||
+ scu.timedate_human_repr()
|
+ scu.timedate_human_repr()
|
||||||
+ "",
|
+ "",
|
||||||
filename=scu.make_filename("evaluations_delais_" + sem["titreannee"]),
|
filename=scu.make_filename("evaluations_delais_" + formsemestre.titre_annee()),
|
||||||
)
|
)
|
||||||
return tab.make_page(format=format)
|
return tab.make_page(format=format)
|
||||||
|
|
||||||
@ -635,9 +633,7 @@ def evaluation_describe(evaluation_id="", edit_in_place=True):
|
|||||||
'<span class="evallink"><a class="stdlink" href="evaluation_listenotes?moduleimpl_id=%s">voir toutes les notes du module</a></span>'
|
'<span class="evallink"><a class="stdlink" href="evaluation_listenotes?moduleimpl_id=%s">voir toutes les notes du module</a></span>'
|
||||||
% moduleimpl_id
|
% moduleimpl_id
|
||||||
)
|
)
|
||||||
mod_descr = (
|
mod_descr = '<a href="moduleimpl_status?moduleimpl_id=%s">%s %s</a> <span class="resp">(resp. <a title="%s">%s</a>)</span> %s' % (
|
||||||
'<a href="moduleimpl_status?moduleimpl_id=%s">%s %s</a> <span class="resp">(resp. <a title="%s">%s</a>)</span> %s'
|
|
||||||
% (
|
|
||||||
moduleimpl_id,
|
moduleimpl_id,
|
||||||
Mod["code"] or "",
|
Mod["code"] or "",
|
||||||
Mod["titre"] or "?",
|
Mod["titre"] or "?",
|
||||||
@ -645,7 +641,6 @@ def evaluation_describe(evaluation_id="", edit_in_place=True):
|
|||||||
resp,
|
resp,
|
||||||
link,
|
link,
|
||||||
)
|
)
|
||||||
)
|
|
||||||
|
|
||||||
etit = E["description"] or ""
|
etit = E["description"] or ""
|
||||||
if etit:
|
if etit:
|
||||||
|
@ -1286,7 +1286,11 @@ def check_formation_ues(formation_id):
|
|||||||
for x in ue_multiples[ue["ue_id"]]
|
for x in ue_multiples[ue["ue_id"]]
|
||||||
]
|
]
|
||||||
slist = ", ".join(
|
slist = ", ".join(
|
||||||
["%(titreannee)s (<em>semestre %(semestre_id)s</em>)" % s for s in sems]
|
[
|
||||||
|
"""%(titreannee)s (<em>semestre <b class="fontred">%(semestre_id)s</b></em>)"""
|
||||||
|
% s
|
||||||
|
for s in sems
|
||||||
|
]
|
||||||
)
|
)
|
||||||
H.append("<li><b>%s</b> : %s</li>" % (ue["acronyme"], slist))
|
H.append("<li><b>%s</b> : %s</li>" % (ue["acronyme"], slist))
|
||||||
H.append("</ul></div>")
|
H.append("</ul></div>")
|
||||||
|
@ -305,7 +305,10 @@ def moduleimpl_inscriptions_stats(formsemestre_id):
|
|||||||
if can_change:
|
if can_change:
|
||||||
c_link = (
|
c_link = (
|
||||||
'<a class="discretelink" href="moduleimpl_inscriptions_edit?moduleimpl_id=%s">%s</a>'
|
'<a class="discretelink" href="moduleimpl_inscriptions_edit?moduleimpl_id=%s">%s</a>'
|
||||||
% (mod["moduleimpl_id"], mod["descri"])
|
% (
|
||||||
|
mod["moduleimpl_id"],
|
||||||
|
mod["descri"] or "<i>(inscrire des étudiants)</i>",
|
||||||
|
)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
c_link = mod["descri"]
|
c_link = mod["descri"]
|
||||||
|
@ -1707,6 +1707,9 @@ ul.notes_ue_list {
|
|||||||
li.notes_ue_list {
|
li.notes_ue_list {
|
||||||
margin-top: 9px;
|
margin-top: 9px;
|
||||||
list-style-type: none;
|
list-style-type: none;
|
||||||
|
border: 1px solid maroon;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding-bottom: 5px;
|
||||||
}
|
}
|
||||||
span.ue_type_1 {
|
span.ue_type_1 {
|
||||||
color: green;
|
color: green;
|
||||||
@ -1749,6 +1752,7 @@ ul.notes_matiere_list {
|
|||||||
background-color: rgb(220,220,220);
|
background-color: rgb(220,220,220);
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
|
border-top: 1px solid maroon;
|
||||||
}
|
}
|
||||||
|
|
||||||
ul.notes_module_list {
|
ul.notes_module_list {
|
||||||
|
@ -18,10 +18,12 @@
|
|||||||
<a href="{{ url_for('notes.refcomp_table', scodoc_dept=g.scodoc_dept, ) }}">
|
<a href="{{ url_for('notes.refcomp_table', scodoc_dept=g.scodoc_dept, ) }}">
|
||||||
Liste des référentiels de compétences chargés</a>
|
Liste des référentiels de compétences chargés</a>
|
||||||
</li>
|
</li>
|
||||||
|
{% if formation is not none %}
|
||||||
<li>
|
<li>
|
||||||
<a href="{{ url_for('notes.refcomp_assoc_formation', scodoc_dept=g.scodoc_dept, formation_id=formation.id) }}">
|
<a href="{{ url_for('notes.refcomp_assoc_formation', scodoc_dept=g.scodoc_dept, formation_id=formation.id) }}">
|
||||||
Association à la formation {{ formation.acronyme }}</a>
|
Association à la formation {{ formation.acronyme }}</a>
|
||||||
</li>
|
</li>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -65,6 +65,13 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
|
{% if mod.ue.type != 0 and mod.module_type != 0 %}
|
||||||
|
<span class="warning" title="Une UE de type spécial ne
|
||||||
|
devrait contenir que des modules standards">
|
||||||
|
type incompatible avec son UE de rattachement !
|
||||||
|
</span>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
<span class="sco_tag_edit"><form><textarea data-module_id="{{mod.id}}"
|
<span class="sco_tag_edit"><form><textarea data-module_id="{{mod.id}}"
|
||||||
class="{% if tag_editable %}module_tag_editor{% else %}module_tag_editor_ro{% endif %}">{{mod.tags|join(', ', attribute='title')}}</textarea></form></span>
|
class="{% if tag_editable %}module_tag_editor{% else %}module_tag_editor_ro{% endif %}">{{mod.tags|join(', ', attribute='title')}}</textarea></form></span>
|
||||||
|
|
||||||
|
@ -48,6 +48,9 @@
|
|||||||
}}">modifier</a>
|
}}">modifier</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
{% if ue.type == 1 and ue.modules.count() == 0 %}
|
||||||
|
<span class="warning" title="pas de module, donc pas de bonus calculé">aucun module rattaché !</span>
|
||||||
|
{% endif %}
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# -*- mode: python -*-
|
# -*- mode: python -*-
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
SCOVERSION = "9.1.58"
|
SCOVERSION = "9.1.61"
|
||||||
|
|
||||||
SCONAME = "ScoDoc"
|
SCONAME = "ScoDoc"
|
||||||
|
|
||||||
|
@ -93,6 +93,8 @@ fi
|
|||||||
# nginx:
|
# nginx:
|
||||||
mkdir -p "$slash"/etc/nginx/sites-available || die "can't mkdir nginx config"
|
mkdir -p "$slash"/etc/nginx/sites-available || die "can't mkdir nginx config"
|
||||||
cp -p "$SCODOC_DIR"/tools/etc/scodoc9.nginx "$slash"/etc/nginx/sites-available/scodoc9.nginx.distrib || die "can't copy nginx config"
|
cp -p "$SCODOC_DIR"/tools/etc/scodoc9.nginx "$slash"/etc/nginx/sites-available/scodoc9.nginx.distrib || die "can't copy nginx config"
|
||||||
|
mkdir -p "$slash"/etc/nginx/conf.d || die "can't mkdir nginx conf.d"
|
||||||
|
cp -p "$SCODOC_DIR"/tools/etc/scodoc9-nginx-timeout.conf "$slash"/etc/nginx/conf.d/ || die "can't copy nginx timeout config"
|
||||||
|
|
||||||
# systemd
|
# systemd
|
||||||
mkdir -p "$slash"/etc/systemd/system/ || die "can't mkdir systemd config"
|
mkdir -p "$slash"/etc/systemd/system/ || die "can't mkdir systemd config"
|
||||||
|
5
tools/etc/scodoc9-nginx-timeout.conf
Normal file
5
tools/etc/scodoc9-nginx-timeout.conf
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# Reglage des timeout du frontal nginx pour ScoDoc 9 (>= 9.1.59)
|
||||||
|
|
||||||
|
proxy_read_timeout 400;
|
||||||
|
proxy_connect_timeout 400;
|
||||||
|
proxy_send_timeout 400;
|
Loading…
Reference in New Issue
Block a user