forked from ScoDoc/ScoDoc
index semestre dans les UE
This commit is contained in:
parent
4182fd494c
commit
14ab816bee
@ -7,6 +7,7 @@ from app.models import APO_CODE_STR_LEN
|
|||||||
from app.models import SHORT_STR_LEN
|
from app.models import SHORT_STR_LEN
|
||||||
from app.scodoc import sco_utils as scu
|
from app.scodoc import sco_utils as scu
|
||||||
from app.scodoc.sco_utils import ModuleType
|
from app.scodoc.sco_utils import ModuleType
|
||||||
|
from app.scodoc import sco_codes_parcours
|
||||||
|
|
||||||
|
|
||||||
class Formation(db.Model):
|
class Formation(db.Model):
|
||||||
@ -39,6 +40,10 @@ class Formation(db.Model):
|
|||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"<{self.__class__.__name__}(id={self.id}, dept_id={self.dept_id}, acronyme='{self.acronyme}')>"
|
return f"<{self.__class__.__name__}(id={self.id}, dept_id={self.dept_id}, acronyme='{self.acronyme}')>"
|
||||||
|
|
||||||
|
def get_parcours(self):
|
||||||
|
"""get l'instance de TypeParcours de cette formation"""
|
||||||
|
return sco_codes_parcours.get_parcours_from_code(self.type_parcours)
|
||||||
|
|
||||||
|
|
||||||
class UniteEns(db.Model):
|
class UniteEns(db.Model):
|
||||||
"""Unité d'Enseignement (UE)"""
|
"""Unité d'Enseignement (UE)"""
|
||||||
@ -51,6 +56,11 @@ class UniteEns(db.Model):
|
|||||||
acronyme = db.Column(db.Text(), nullable=False)
|
acronyme = db.Column(db.Text(), nullable=False)
|
||||||
numero = db.Column(db.Integer) # ordre de présentation
|
numero = db.Column(db.Integer) # ordre de présentation
|
||||||
titre = db.Column(db.Text())
|
titre = db.Column(db.Text())
|
||||||
|
# Le semestre_idx n'est pas un id mais le numéro du semestre: 1, 2, ...
|
||||||
|
# En ScoDoc7 et pour les formations classiques, il est NULL
|
||||||
|
# (le numéro du semestre étant alors déterminé par celui des modules de l'UE)
|
||||||
|
# Pour les formations APC, il est obligatoire (de 1 à 6 pour le BUT):
|
||||||
|
semestre_idx = db.Column(db.Integer, nullable=True, index=True)
|
||||||
# Type d'UE: 0 normal ("fondamentale"), 1 "sport", 2 "projet et stage (LP)",
|
# Type d'UE: 0 normal ("fondamentale"), 1 "sport", 2 "projet et stage (LP)",
|
||||||
# 4 "élective"
|
# 4 "élective"
|
||||||
type = db.Column(db.Integer, default=0, server_default="0")
|
type = db.Column(db.Integer, default=0, server_default="0")
|
||||||
|
@ -51,7 +51,7 @@ def TrivialFormulator(
|
|||||||
allow_null : if true, field can be left empty (default true)
|
allow_null : if true, field can be left empty (default true)
|
||||||
type : 'string', 'int', 'float' (default to string), 'list' (only for hidden)
|
type : 'string', 'int', 'float' (default to string), 'list' (only for hidden)
|
||||||
readonly : default False. if True, no form element, display current value.
|
readonly : default False. if True, no form element, display current value.
|
||||||
convert_numbers: covert int and float values (from string)
|
convert_numbers: convert int and float values (from string)
|
||||||
allowed_values : list of possible values (default: any value)
|
allowed_values : list of possible values (default: any value)
|
||||||
validator : function validating the field (called with (value,field)).
|
validator : function validating the field (called with (value,field)).
|
||||||
min_value : minimum value (for floats and ints)
|
min_value : minimum value (for floats and ints)
|
||||||
|
@ -32,7 +32,7 @@ import flask
|
|||||||
from flask import g, url_for, request
|
from flask import g, url_for, request
|
||||||
from flask_login import current_user
|
from flask_login import current_user
|
||||||
|
|
||||||
from app.models.formations import UniteEns
|
from app.models.formations import Formation, UniteEns
|
||||||
import app.scodoc.notesdb as ndb
|
import app.scodoc.notesdb as ndb
|
||||||
import app.scodoc.sco_utils as scu
|
import app.scodoc.sco_utils as scu
|
||||||
from app.scodoc.sco_utils import ModuleType
|
from app.scodoc.sco_utils import ModuleType
|
||||||
@ -66,6 +66,7 @@ _ueEditor = ndb.EditableTable(
|
|||||||
"acronyme",
|
"acronyme",
|
||||||
"numero",
|
"numero",
|
||||||
"titre",
|
"titre",
|
||||||
|
"semestre_idx",
|
||||||
"type",
|
"type",
|
||||||
"ue_code",
|
"ue_code",
|
||||||
"ects",
|
"ects",
|
||||||
@ -82,6 +83,7 @@ _ueEditor = ndb.EditableTable(
|
|||||||
"numero": ndb.int_null_is_zero,
|
"numero": ndb.int_null_is_zero,
|
||||||
"ects": ndb.float_null_is_null,
|
"ects": ndb.float_null_is_null,
|
||||||
"coefficient": ndb.float_null_is_zero,
|
"coefficient": ndb.float_null_is_zero,
|
||||||
|
"semestre_idx": ndb.int_null_is_null,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -195,7 +197,7 @@ def ue_create(formation_id=None):
|
|||||||
|
|
||||||
|
|
||||||
def ue_edit(ue_id=None, create=False, formation_id=None):
|
def ue_edit(ue_id=None, create=False, formation_id=None):
|
||||||
"""Modification ou creation d'une UE"""
|
"""Modification ou création d'une UE"""
|
||||||
from app.scodoc import sco_formations
|
from app.scodoc import sco_formations
|
||||||
|
|
||||||
create = int(create)
|
create = int(create)
|
||||||
@ -212,25 +214,25 @@ def ue_edit(ue_id=None, create=False, formation_id=None):
|
|||||||
title = "Création d'une UE"
|
title = "Création d'une UE"
|
||||||
initvalues = {}
|
initvalues = {}
|
||||||
submitlabel = "Créer cette UE"
|
submitlabel = "Créer cette UE"
|
||||||
Fol = sco_formations.formation_list(args={"formation_id": formation_id})
|
formation = Formation.query.get(formation_id)
|
||||||
if not Fol:
|
if not formation:
|
||||||
raise ScoValueError(
|
raise ScoValueError(f"Formation inexistante ! (id={formation_id})")
|
||||||
"Formation %s inexistante ! (si vous avez suivi un lien valide, merci de signaler le problème)"
|
parcours = formation.get_parcours()
|
||||||
% formation_id
|
is_apc = parcours.APC_SAE
|
||||||
)
|
semestres_indices = list(range(1, parcours.NB_SEM + 1))
|
||||||
Fo = Fol[0]
|
|
||||||
parcours = sco_codes_parcours.get_parcours_from_code(Fo["type_parcours"])
|
|
||||||
|
|
||||||
H = [
|
H = [
|
||||||
html_sco_header.sco_header(page_title=title, javascripts=["js/edit_ue.js"]),
|
html_sco_header.sco_header(page_title=title, javascripts=["js/edit_ue.js"]),
|
||||||
"<h2>" + title,
|
"<h2>" + title,
|
||||||
" (formation %(acronyme)s, version %(version)s)</h2>" % Fo,
|
f" (formation {formation.acronyme}, version {formation.version})</h2>",
|
||||||
"""
|
"""
|
||||||
<p class="help">Les UE sont des groupes de modules dans une formation donnée, utilisés pour l'évaluation (on calcule des moyennes par UE et applique des seuils ("barres")).
|
<p class="help">Les UE sont des groupes de modules dans une formation donnée,
|
||||||
</p>
|
utilisés pour la validation (on calcule des moyennes par UE et applique des
|
||||||
|
seuils ("barres")).
|
||||||
|
</p>
|
||||||
|
|
||||||
<p class="help">Note: L'UE n'a pas de coefficient associé. Seuls les <em>modules</em> ont des coefficients.
|
<p class="help">Note: sauf exception, l'UE n'a pas de coefficient associé.
|
||||||
</p>""",
|
Seuls les <em>modules</em> ont des coefficients.
|
||||||
|
</p>""",
|
||||||
]
|
]
|
||||||
|
|
||||||
ue_types = parcours.ALLOWED_UE_TYPES
|
ue_types = parcours.ALLOWED_UE_TYPES
|
||||||
@ -252,6 +254,18 @@ def ue_edit(ue_id=None, create=False, formation_id=None):
|
|||||||
"type": "int",
|
"type": "int",
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
"semestre_idx",
|
||||||
|
{
|
||||||
|
"input_type": "menu",
|
||||||
|
"type": "int",
|
||||||
|
"allow_null": True,
|
||||||
|
"title": parcours.SESSION_NAME.capitalize(),
|
||||||
|
"explanation": "%s de l'UE dans la formation" % parcours.SESSION_NAME,
|
||||||
|
"labels": ["non spécifié"] + [str(x) for x in semestres_indices],
|
||||||
|
"allowed_values": [""] + semestres_indices,
|
||||||
|
},
|
||||||
|
),
|
||||||
(
|
(
|
||||||
"type",
|
"type",
|
||||||
{
|
{
|
||||||
@ -276,11 +290,12 @@ def ue_edit(ue_id=None, create=False, formation_id=None):
|
|||||||
"size": 4,
|
"size": 4,
|
||||||
"type": "float",
|
"type": "float",
|
||||||
"title": "Coefficient",
|
"title": "Coefficient",
|
||||||
"explanation": """les coefficients d'UE ne sont utilisés que lorsque
|
"explanation": """les coefficients d'UE ne sont utilisés que
|
||||||
l'option <em>Utiliser les coefficients d'UE pour calculer la moyenne générale</em>
|
lorsque l'option <em>Utiliser les coefficients d'UE pour calculer
|
||||||
est activée. Par défaut, le coefficient d'une UE est simplement la somme des
|
la moyenne générale</em> est activée. Par défaut, le coefficient
|
||||||
coefficients des modules dans lesquels l'étudiant a des notes.
|
d'une UE est simplement la somme des coefficients des modules dans
|
||||||
""",
|
lesquels l'étudiant a des notes.
|
||||||
|
""",
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@ -308,30 +323,13 @@ def ue_edit(ue_id=None, create=False, formation_id=None):
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
if parcours.UE_IS_MODULE:
|
|
||||||
# demande le semestre pour creer le module immediatement:
|
|
||||||
semestres_indices = list(range(1, parcours.NB_SEM + 1))
|
|
||||||
fw.append(
|
|
||||||
(
|
|
||||||
"semestre_id",
|
|
||||||
{
|
|
||||||
"input_type": "menu",
|
|
||||||
"type": "int",
|
|
||||||
"title": parcours.SESSION_NAME.capitalize(),
|
|
||||||
"explanation": "%s de début du module dans la formation"
|
|
||||||
% parcours.SESSION_NAME,
|
|
||||||
"labels": [str(x) for x in semestres_indices],
|
|
||||||
"allowed_values": semestres_indices,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
)
|
|
||||||
if create and not parcours.UE_IS_MODULE:
|
if create and not parcours.UE_IS_MODULE:
|
||||||
fw.append(
|
fw.append(
|
||||||
(
|
(
|
||||||
"create_matiere",
|
"create_matiere",
|
||||||
{
|
{
|
||||||
"input_type": "boolcheckbox",
|
"input_type": "boolcheckbox",
|
||||||
"default": False,
|
"default": True,
|
||||||
"title": "Créer matière identique",
|
"title": "Créer matière identique",
|
||||||
"explanation": "créer immédiatement une matière dans cette UE (utile si on n'utilise pas de matières)",
|
"explanation": "créer immédiatement une matière dans cette UE (utile si on n'utilise pas de matières)",
|
||||||
},
|
},
|
||||||
@ -353,13 +351,10 @@ def ue_edit(ue_id=None, create=False, formation_id=None):
|
|||||||
if not tf[2]["ue_code"]:
|
if not tf[2]["ue_code"]:
|
||||||
del tf[2]["ue_code"]
|
del tf[2]["ue_code"]
|
||||||
if not tf[2]["numero"]:
|
if not tf[2]["numero"]:
|
||||||
if not "semestre_id" in tf[2]:
|
|
||||||
tf[2]["semestre_id"] = 0
|
|
||||||
# numero regroupant par semestre ou année:
|
# numero regroupant par semestre ou année:
|
||||||
tf[2]["numero"] = next_ue_numero(
|
tf[2]["numero"] = next_ue_numero(
|
||||||
formation_id, int(tf[2]["semestre_id"] or 0)
|
formation_id, int(tf[2]["semestre_idx"])
|
||||||
)
|
)
|
||||||
|
|
||||||
ue_id = do_ue_create(tf[2])
|
ue_id = do_ue_create(tf[2])
|
||||||
if parcours.UE_IS_MODULE or tf[2]["create_matiere"]:
|
if parcours.UE_IS_MODULE or tf[2]["create_matiere"]:
|
||||||
matiere_id = sco_edit_matiere.do_matiere_create(
|
matiere_id = sco_edit_matiere.do_matiere_create(
|
||||||
@ -375,7 +370,7 @@ def ue_edit(ue_id=None, create=False, formation_id=None):
|
|||||||
"ue_id": ue_id,
|
"ue_id": ue_id,
|
||||||
"matiere_id": matiere_id,
|
"matiere_id": matiere_id,
|
||||||
"formation_id": formation_id,
|
"formation_id": formation_id,
|
||||||
"semestre_id": tf[2]["semestre_id"],
|
"semestre_id": tf[2]["semestre_idx"],
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
@ -388,16 +383,20 @@ def ue_edit(ue_id=None, create=False, formation_id=None):
|
|||||||
|
|
||||||
|
|
||||||
def _add_ue_semestre_id(ues):
|
def _add_ue_semestre_id(ues):
|
||||||
"""ajoute semestre_id dans les ue, en regardant le premier module de chacune.
|
"""ajoute semestre_id dans les ue, en regardant
|
||||||
|
semestre_idx ou à défaut le premier module de chacune.
|
||||||
Les UE sans modules se voient attribuer le numero UE_SEM_DEFAULT (1000000),
|
Les UE sans modules se voient attribuer le numero UE_SEM_DEFAULT (1000000),
|
||||||
qui les place à la fin de la liste.
|
qui les place à la fin de la liste.
|
||||||
"""
|
"""
|
||||||
for ue in ues:
|
for ue in ues:
|
||||||
Modlist = sco_edit_module.module_list(args={"ue_id": ue["ue_id"]})
|
if ue["semestre_idx"] is not None:
|
||||||
if Modlist:
|
ue["semestre_id"] = ue["semestre_idx"]
|
||||||
ue["semestre_id"] = Modlist[0]["semestre_id"]
|
|
||||||
else:
|
else:
|
||||||
ue["semestre_id"] = 1000000
|
modules = sco_edit_module.module_list(args={"ue_id": ue["ue_id"]})
|
||||||
|
if modules:
|
||||||
|
ue["semestre_id"] = modules[0]["semestre_id"]
|
||||||
|
else:
|
||||||
|
ue["semestre_id"] = 1000000
|
||||||
|
|
||||||
|
|
||||||
def next_ue_numero(formation_id, semestre_id=None):
|
def next_ue_numero(formation_id, semestre_id=None):
|
||||||
|
30
migrations/versions/c8efc54586d8_ue_semestre_idx.py
Normal file
30
migrations/versions/c8efc54586d8_ue_semestre_idx.py
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
"""UE.semestre_idx
|
||||||
|
|
||||||
|
Revision ID: c8efc54586d8
|
||||||
|
Revises: 6cfc21a7ae1b
|
||||||
|
Create Date: 2021-11-14 17:35:39.602613
|
||||||
|
|
||||||
|
"""
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = 'c8efc54586d8'
|
||||||
|
down_revision = '6cfc21a7ae1b'
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.add_column('notes_ue', sa.Column('semestre_idx', sa.Integer(), nullable=True))
|
||||||
|
op.create_index(op.f('ix_notes_ue_semestre_idx'), 'notes_ue', ['semestre_idx'], unique=False)
|
||||||
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.drop_index(op.f('ix_notes_ue_semestre_idx'), table_name='notes_ue')
|
||||||
|
op.drop_column('notes_ue', 'semestre_idx')
|
||||||
|
# ### end Alembic commands ###
|
Loading…
Reference in New Issue
Block a user