Fix: table association responsables FormSemestre

This commit is contained in:
Emmanuel Viennet 2025-02-03 17:16:18 +01:00
parent c983d0ae7f
commit 313d76bc8d
4 changed files with 113 additions and 2 deletions

View File

@ -236,11 +236,16 @@ class FormSemestre(models.ScoDocModel):
def create_formsemestre(cls, args: dict, silent=False) -> "FormSemestre":
"""Création d'un formsemestre, avec toutes les valeurs par défaut
et notification (sauf si silent).
Arguments:
- responsables peut être une liste de User ou de user_id.
Crée la partition par défaut.
Commit all changes.
"""
# was sco_formsemestre.do_formsemestre_create
if "dept_id" not in args:
args["dept_id"] = g.scodoc_dept_id
if "formation_id" not in args:
raise ScoValueError("create_formsemestre: no formation_id")
formsemestre: "FormSemestre" = cls.create_from_dict(args)
db.session.flush()
for etape in args.get("etapes") or []:
@ -1475,8 +1480,9 @@ notes_formsemestre_responsables = db.Table(
"formsemestre_id",
db.Integer,
db.ForeignKey("notes_formsemestre.id"),
primary_key=True,
),
db.Column("responsable_id", db.Integer, db.ForeignKey("user.id")),
db.Column("responsable_id", db.Integer, db.ForeignKey("user.id"), primary_key=True),
)

View File

@ -0,0 +1,66 @@
"""responsables_assoc_unicity
Revision ID: e0824c4f1b0b
Revises: bc85a55e63e1
Create Date: 2025-02-03 16:45:13.082716
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = "e0824c4f1b0b"
down_revision = "bc85a55e63e1"
branch_labels = None
depends_on = None
def upgrade():
# Suppression des doublons dans la table d'association notes_formsemestre_responsables
op.execute(
"""
WITH duplicates AS (
SELECT
formsemestre_id,
responsable_id,
ctid AS row_identifier,
row_number() OVER (
PARTITION BY formsemestre_id, responsable_id
ORDER BY ctid
) AS rn
FROM notes_formsemestre_responsables
)
DELETE FROM notes_formsemestre_responsables
WHERE ctid IN (
SELECT row_identifier FROM duplicates WHERE rn > 1
);
"""
)
with op.batch_alter_table(
"notes_formsemestre_responsables", schema=None
) as batch_op:
batch_op.alter_column(
"formsemestre_id", existing_type=sa.INTEGER(), nullable=False
)
batch_op.alter_column(
"responsable_id", existing_type=sa.INTEGER(), nullable=False
)
batch_op.create_unique_constraint(
"uq_notes_formsemestre_responsables", ["formsemestre_id", "responsable_id"]
)
def downgrade():
with op.batch_alter_table(
"notes_formsemestre_responsables", schema=None
) as batch_op:
batch_op.alter_column(
"responsable_id", existing_type=sa.INTEGER(), nullable=True
)
batch_op.alter_column(
"formsemestre_id", existing_type=sa.INTEGER(), nullable=True
)
batch_op.drop_constraint("uq_notes_formsemestre_responsables", type_="unique")

View File

@ -3,7 +3,7 @@
"Infos sur version ScoDoc"
SCOVERSION = "9.7.59"
SCOVERSION = "9.7.60"
SCONAME = "ScoDoc"

View File

@ -8,6 +8,7 @@ import pytest
import app
from app import db
from app.auth.models import User
from app.formations import edit_ue, formation_versions
from app.models import Formation, FormSemestre, FormSemestreDescription
from app.scodoc import (
@ -207,6 +208,44 @@ def test_formsemestre_misc_views(test_client):
# pas de test des indicateurs de suivi BUT
def test_formsemestre_edit(test_client):
"""Test modification formsemestre"""
u1 = User.query.first()
u2 = User(user_name="un_autre_responsable")
db.session.add(u2)
formation = Formation(
dept_id=1,
acronyme="FORM",
titre="Formation",
titre_officiel="La formation test",
)
db.session.add(formation)
db.session.flush()
formsemestre = FormSemestre.create_formsemestre(
{
"dept_id": 1,
"titre": "test edit",
"date_debut": "2024-08-01",
"date_fin": "2024-08-31",
"formation_id": formation.id,
"responsables": [u1, -1, -1, -1],
},
silent=True,
)
assert formsemestre
assert formsemestre.responsables[0].user_name == u1.user_name
assert formsemestre.from_dict({"responsables": [u2.id, u1, -1, -1]})
db.session.commit()
assert len(formsemestre.responsables) == 2
assert sorted(u.user_name for u in formsemestre.responsables) == sorted(
[u1.user_name, u2.user_name]
)
u3 = User(user_name="un_troisieme_responsable")
assert formsemestre.from_dict({"responsables": [u3]})
db.session.commit()
assert len(formsemestre.responsables) == 1
def test_formsemestre_description(test_client):
"""Test FormSemestreDescription"""
app.set_sco_dept(DEPT)