- Modifi comportement Batch
- Ajout description assiduite
This commit is contained in:
parent
b30d5eb996
commit
02ec55ca18
@ -39,7 +39,8 @@ def assiduite(assiduite_id: int = None):
|
|||||||
"moduleimpl_id": 3,
|
"moduleimpl_id": 3,
|
||||||
"date_debut": "2022-10-31T08:00+01:00",
|
"date_debut": "2022-10-31T08:00+01:00",
|
||||||
"date_fin": "2022-10-31T10:00+01:00",
|
"date_fin": "2022-10-31T10:00+01:00",
|
||||||
"etat": "retard"
|
"etat": "retard",
|
||||||
|
"desc": "une description",
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -258,21 +259,13 @@ def count_assiduites_formsemestre(
|
|||||||
return jsonify(scass.get_assiduites_stats(assiduites, metric, filter))
|
return jsonify(scass.get_assiduites_stats(assiduites, metric, filter))
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/assiduite/<int:etudid>/create", methods=["POST"], defaults={"batch": False})
|
@bp.route("/assiduite/<int:etudid>/create", methods=["POST"])
|
||||||
@api_web_bp.route(
|
@api_web_bp.route("/assiduite/<int:etudid>/create", methods=["POST"])
|
||||||
"/assiduite/<int:etudid>/create", methods=["POST"], defaults={"batch": False}
|
|
||||||
)
|
|
||||||
@bp.route(
|
|
||||||
"/assiduite/<int:etudid>/create/batch", methods=["POST"], defaults={"batch": True}
|
|
||||||
)
|
|
||||||
@api_web_bp.route(
|
|
||||||
"/assiduite/<int:etudid>/create/batch", methods=["POST"], defaults={"batch": True}
|
|
||||||
)
|
|
||||||
@scodoc
|
@scodoc
|
||||||
@login_required
|
@login_required
|
||||||
@permission_required(Permission.ScoView)
|
@permission_required(Permission.ScoView)
|
||||||
# @permission_required(Permission.ScoAssiduiteChange)
|
# @permission_required(Permission.ScoAssiduiteChange)
|
||||||
def create(etudid: int = None, batch: bool = False):
|
def create(etudid: int = None):
|
||||||
"""
|
"""
|
||||||
Création d'une assiduité pour l'étudiant (etudid)
|
Création d'une assiduité pour l'étudiant (etudid)
|
||||||
La requête doit avoir un content type "application/json":
|
La requête doit avoir un content type "application/json":
|
||||||
@ -292,26 +285,17 @@ def create(etudid: int = None, batch: bool = False):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
etud: Identite = Identite.query.filter_by(id=etudid).first_or_404()
|
etud: Identite = Identite.query.filter_by(id=etudid).first_or_404()
|
||||||
if batch:
|
|
||||||
errors: dict[int, str] = {}
|
|
||||||
success: dict[
|
|
||||||
int,
|
|
||||||
] = {}
|
|
||||||
for i, data in enumerate(request.get_json(force=True).get("batch")):
|
|
||||||
code, obj = create_singular(data, etud)
|
|
||||||
if code == 404:
|
|
||||||
errors[i] = obj
|
|
||||||
else:
|
|
||||||
success[i] = obj
|
|
||||||
|
|
||||||
return jsonify({"errors": errors, "success": success})
|
errors: dict[int, str] = {}
|
||||||
|
success: dict[int, object] = {}
|
||||||
else:
|
for i, data in enumerate(request.get_json(force=True)):
|
||||||
code, obj = create_singular(request.get_json(force=True), etud)
|
code, obj = create_singular(data, etud)
|
||||||
if code == 404:
|
if code == 404:
|
||||||
return json_error(code, obj)
|
errors[i] = obj
|
||||||
else:
|
else:
|
||||||
return jsonify(obj)
|
success[i] = obj
|
||||||
|
|
||||||
|
return jsonify({"errors": errors, "success": success})
|
||||||
|
|
||||||
|
|
||||||
def create_singular(
|
def create_singular(
|
||||||
@ -357,6 +341,10 @@ def create_singular(
|
|||||||
if moduleimpl is None:
|
if moduleimpl is None:
|
||||||
errors.append("param 'moduleimpl_id': invalide")
|
errors.append("param 'moduleimpl_id': invalide")
|
||||||
|
|
||||||
|
# cas 5 : desc
|
||||||
|
|
||||||
|
desc:str = data.get("desc", None)
|
||||||
|
|
||||||
if errors != []:
|
if errors != []:
|
||||||
err: str = ", ".join(errors)
|
err: str = ", ".join(errors)
|
||||||
return (404, err)
|
return (404, err)
|
||||||
@ -382,48 +370,27 @@ def create_singular(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/assiduite/delete", methods=["POST"], defaults={"batch": False})
|
@bp.route("/assiduite/delete", methods=["POST"])
|
||||||
@api_web_bp.route("/assiduite/delete", methods=["POST"], defaults={"batch": False})
|
@api_web_bp.route("/assiduite/delete", methods=["POST"])
|
||||||
@bp.route(
|
|
||||||
"/assiduite/delete/batch",
|
|
||||||
methods=["POST"],
|
|
||||||
defaults={"batch": True},
|
|
||||||
)
|
|
||||||
@api_web_bp.route(
|
|
||||||
"/assiduite/delete/batch",
|
|
||||||
methods=["POST"],
|
|
||||||
defaults={"batch": True},
|
|
||||||
)
|
|
||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoView)
|
@permission_required(Permission.ScoView)
|
||||||
# @permission_required(Permission.ScoAssiduiteChange)
|
# @permission_required(Permission.ScoAssiduiteChange)
|
||||||
def delete(batch: bool = False):
|
def delete():
|
||||||
"""
|
"""
|
||||||
Suppression d'une assiduité à partir de son id
|
Suppression d'une assiduité à partir de son id
|
||||||
"""
|
"""
|
||||||
if batch:
|
assiduites: list[int] = request.get_json(force=True)
|
||||||
assiduites: list[int] = request.get_json(force=True).get("batch", [])
|
output = {"errors": {}, "success": {}}
|
||||||
output = {"errors": {}, "success": {}}
|
|
||||||
|
|
||||||
for i, ass in enumerate(assiduites):
|
for i, ass in enumerate(assiduites):
|
||||||
code, msg = delete_singular(ass, db)
|
code, msg = delete_singular(ass, db)
|
||||||
if code == 404:
|
|
||||||
output["errors"][f"{i}"] = msg
|
|
||||||
else:
|
|
||||||
output["success"][f"{i}"] = {"OK": True}
|
|
||||||
db.session.commit()
|
|
||||||
return jsonify(output)
|
|
||||||
|
|
||||||
else:
|
|
||||||
code, msg = delete_singular(
|
|
||||||
request.get_json(force=True).get("assiduite_id", -1), db
|
|
||||||
)
|
|
||||||
if code == 404:
|
if code == 404:
|
||||||
return json_error(code, msg)
|
output["errors"][f"{i}"] = msg
|
||||||
if code == 200:
|
else:
|
||||||
db.session.commit()
|
output["success"][f"{i}"] = {"OK": True}
|
||||||
return jsonify({"OK": True})
|
db.session.commit()
|
||||||
|
return jsonify(output)
|
||||||
|
|
||||||
|
|
||||||
def delete_singular(assiduite_id: int, db):
|
def delete_singular(assiduite_id: int, db):
|
||||||
@ -470,16 +437,17 @@ def edit(assiduite_id: int):
|
|||||||
if moduleimpl_id is not False:
|
if moduleimpl_id is not False:
|
||||||
if moduleimpl_id is not None:
|
if moduleimpl_id is not None:
|
||||||
moduleimpl = ModuleImpl.query.filter_by(id=int(moduleimpl_id)).first()
|
moduleimpl = ModuleImpl.query.filter_by(id=int(moduleimpl_id)).first()
|
||||||
if moduleimpl is None:
|
if moduleimpl is None:
|
||||||
errors.append("param 'moduleimpl_id': invalide")
|
errors.append("param 'moduleimpl_id': invalide")
|
||||||
else:
|
|
||||||
if not moduleimpl.est_inscrit(
|
|
||||||
Identite.query.filter_by(id=assiduite.etudid).first()
|
|
||||||
):
|
|
||||||
errors.append("param 'moduleimpl_id': etud non inscrit")
|
|
||||||
else:
|
else:
|
||||||
assiduite.moduleimpl_id = moduleimpl_id
|
if not moduleimpl.est_inscrit(
|
||||||
|
Identite.query.filter_by(id=assiduite.etudid).first()
|
||||||
|
):
|
||||||
|
errors.append("param 'moduleimpl_id': etud non inscrit")
|
||||||
|
else:
|
||||||
|
assiduite.moduleimpl_id = moduleimpl_id
|
||||||
|
else:
|
||||||
|
assiduite.moduleimpl_id = moduleimpl_id
|
||||||
if errors != []:
|
if errors != []:
|
||||||
err: str = ", ".join(errors)
|
err: str = ", ".join(errors)
|
||||||
return json_error(404, err)
|
return json_error(404, err)
|
||||||
|
@ -14,6 +14,7 @@ class Assiduite(db.Model):
|
|||||||
Représente une assiduité:
|
Représente une assiduité:
|
||||||
- une plage horaire lié à un état et un étudiant
|
- une plage horaire lié à un état et un étudiant
|
||||||
- un module si spécifiée
|
- un module si spécifiée
|
||||||
|
- une description si spécifiée
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__tablename__ = "assiduites"
|
__tablename__ = "assiduites"
|
||||||
@ -40,6 +41,8 @@ class Assiduite(db.Model):
|
|||||||
)
|
)
|
||||||
etat = db.Column(db.Integer, nullable=False)
|
etat = db.Column(db.Integer, nullable=False)
|
||||||
|
|
||||||
|
desc = db.Column(db.Text)
|
||||||
|
|
||||||
def to_dict(self) -> dict:
|
def to_dict(self) -> dict:
|
||||||
data = {
|
data = {
|
||||||
"assiduite_id": self.assiduite_id,
|
"assiduite_id": self.assiduite_id,
|
||||||
@ -48,6 +51,7 @@ class Assiduite(db.Model):
|
|||||||
"date_debut": self.date_debut,
|
"date_debut": self.date_debut,
|
||||||
"date_fin": self.date_fin,
|
"date_fin": self.date_fin,
|
||||||
"etat": self.etat,
|
"etat": self.etat,
|
||||||
|
"desc": self.desc,
|
||||||
}
|
}
|
||||||
return data
|
return data
|
||||||
|
|
||||||
@ -59,6 +63,7 @@ class Assiduite(db.Model):
|
|||||||
date_fin: datetime,
|
date_fin: datetime,
|
||||||
etat: EtatAssiduite,
|
etat: EtatAssiduite,
|
||||||
moduleimpl: ModuleImpl = None,
|
moduleimpl: ModuleImpl = None,
|
||||||
|
description: str = None,
|
||||||
) -> object or int:
|
) -> object or int:
|
||||||
"""Créer une nouvelle assiduité pour l'étudiant"""
|
"""Créer une nouvelle assiduité pour l'étudiant"""
|
||||||
# Vérification de non duplication des périodes
|
# Vérification de non duplication des périodes
|
||||||
@ -88,6 +93,7 @@ class Assiduite(db.Model):
|
|||||||
etat=etat,
|
etat=etat,
|
||||||
etudiant=etud,
|
etudiant=etud,
|
||||||
moduleimpl_id=moduleimpl.id,
|
moduleimpl_id=moduleimpl.id,
|
||||||
|
desc=description,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
raise ScoValueError("L'étudiant n'est pas inscrit au moduleimpl")
|
raise ScoValueError("L'étudiant n'est pas inscrit au moduleimpl")
|
||||||
@ -97,6 +103,7 @@ class Assiduite(db.Model):
|
|||||||
date_fin=date_fin,
|
date_fin=date_fin,
|
||||||
etat=etat,
|
etat=etat,
|
||||||
etudiant=etud,
|
etudiant=etud,
|
||||||
|
desc=description,
|
||||||
)
|
)
|
||||||
|
|
||||||
return nouv_assiduite
|
return nouv_assiduite
|
||||||
@ -134,12 +141,12 @@ class Justificatif(db.Model):
|
|||||||
raison = db.Column(db.Text())
|
raison = db.Column(db.Text())
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Les documents liés à l'étudiant sont dans
|
Les justificatifs sont enregistrés dans
|
||||||
<archivedir>/docetuds/<dept_id>/<etudid>/<YYYY-MM-DD-HH-MM-SS>
|
<archivedir>/justificatifs/<dept_id>/<etudid>/<nom_fichier.extension>
|
||||||
|
|
||||||
d'après sco_archives.py
|
d'après sco_archives.py#JustificatifArchiver
|
||||||
"""
|
"""
|
||||||
fichier = db.Column(db.Date())
|
fichier = db.Column(db.Text())
|
||||||
|
|
||||||
def to_dict(self) -> dict:
|
def to_dict(self) -> dict:
|
||||||
data = {
|
data = {
|
||||||
|
@ -1,82 +0,0 @@
|
|||||||
"""Ajout Modeles Assiduites Justificatifs
|
|
||||||
|
|
||||||
Revision ID: 530594458193
|
|
||||||
Revises: 3c12f5850cff
|
|
||||||
Create Date: 2022-12-19 13:56:28.597632
|
|
||||||
|
|
||||||
"""
|
|
||||||
from alembic import op
|
|
||||||
import sqlalchemy as sa
|
|
||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
|
||||||
revision = "530594458193"
|
|
||||||
down_revision = "3c12f5850cff"
|
|
||||||
branch_labels = None
|
|
||||||
depends_on = None
|
|
||||||
|
|
||||||
|
|
||||||
def upgrade():
|
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
|
||||||
op.create_table(
|
|
||||||
"justificatifs",
|
|
||||||
sa.Column("justifid", sa.Integer(), nullable=False),
|
|
||||||
sa.Column(
|
|
||||||
"date_debut",
|
|
||||||
sa.DateTime(timezone=True),
|
|
||||||
server_default=sa.text("now()"),
|
|
||||||
nullable=False,
|
|
||||||
),
|
|
||||||
sa.Column(
|
|
||||||
"date_fin",
|
|
||||||
sa.DateTime(timezone=True),
|
|
||||||
server_default=sa.text("now()"),
|
|
||||||
nullable=False,
|
|
||||||
),
|
|
||||||
sa.Column("etudid", sa.Integer(), nullable=False),
|
|
||||||
sa.Column("etat", sa.Integer(), nullable=True),
|
|
||||||
sa.Column("raison", sa.Text(), nullable=True),
|
|
||||||
sa.Column("fichier", sa.Integer(), nullable=True),
|
|
||||||
sa.ForeignKeyConstraint(["etudid"], ["identite.id"], ondelete="CASCADE"),
|
|
||||||
sa.PrimaryKeyConstraint("justifid"),
|
|
||||||
)
|
|
||||||
op.create_index(
|
|
||||||
op.f("ix_justificatifs_etudid"), "justificatifs", ["etudid"], unique=False
|
|
||||||
)
|
|
||||||
op.create_table(
|
|
||||||
"assiduites",
|
|
||||||
sa.Column("id", sa.Integer(), nullable=False),
|
|
||||||
sa.Column(
|
|
||||||
"date_debut",
|
|
||||||
sa.DateTime(timezone=True),
|
|
||||||
server_default=sa.text("now()"),
|
|
||||||
nullable=False,
|
|
||||||
),
|
|
||||||
sa.Column(
|
|
||||||
"date_fin",
|
|
||||||
sa.DateTime(timezone=True),
|
|
||||||
server_default=sa.text("now()"),
|
|
||||||
nullable=False,
|
|
||||||
),
|
|
||||||
sa.Column("moduleimpl_id", sa.Integer(), nullable=True),
|
|
||||||
sa.Column("etudid", sa.Integer(), nullable=False),
|
|
||||||
sa.Column("etat", sa.Integer(), nullable=False),
|
|
||||||
sa.ForeignKeyConstraint(["etudid"], ["identite.id"], ondelete="CASCADE"),
|
|
||||||
sa.ForeignKeyConstraint(
|
|
||||||
["moduleimpl_id"], ["notes_moduleimpl.id"], ondelete="SET NULL"
|
|
||||||
),
|
|
||||||
sa.PrimaryKeyConstraint("id"),
|
|
||||||
)
|
|
||||||
op.create_index(
|
|
||||||
op.f("ix_assiduites_etudid"), "assiduites", ["etudid"], unique=False
|
|
||||||
)
|
|
||||||
# ### end Alembic commands ###
|
|
||||||
|
|
||||||
|
|
||||||
def downgrade():
|
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
|
||||||
op.drop_index(op.f("ix_assiduites_etudid"), table_name="assiduites")
|
|
||||||
op.drop_table("assiduites")
|
|
||||||
op.drop_index(op.f("ix_justificatifs_etudid"), table_name="justificatifs")
|
|
||||||
op.drop_table("justificatifs")
|
|
||||||
# ### end Alembic commands ###
|
|
@ -1,82 +0,0 @@
|
|||||||
"""Ajout Modeles Assiduites Justificatifs
|
|
||||||
|
|
||||||
Revision ID: 685fe5c55439
|
|
||||||
Revises: 3c12f5850cff
|
|
||||||
Create Date: 2022-12-26 09:00:54.750859
|
|
||||||
|
|
||||||
"""
|
|
||||||
from alembic import op
|
|
||||||
import sqlalchemy as sa
|
|
||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
|
||||||
revision = "685fe5c55439"
|
|
||||||
down_revision = "3c12f5850cff"
|
|
||||||
branch_labels = None
|
|
||||||
depends_on = None
|
|
||||||
|
|
||||||
|
|
||||||
def upgrade():
|
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
|
||||||
op.create_table(
|
|
||||||
"justificatifs",
|
|
||||||
sa.Column("justifid", sa.Integer(), nullable=False),
|
|
||||||
sa.Column(
|
|
||||||
"date_debut",
|
|
||||||
sa.DateTime(timezone=True),
|
|
||||||
server_default=sa.text("now()"),
|
|
||||||
nullable=False,
|
|
||||||
),
|
|
||||||
sa.Column(
|
|
||||||
"date_fin",
|
|
||||||
sa.DateTime(timezone=True),
|
|
||||||
server_default=sa.text("now()"),
|
|
||||||
nullable=False,
|
|
||||||
),
|
|
||||||
sa.Column("etudid", sa.Integer(), nullable=False),
|
|
||||||
sa.Column("etat", sa.Integer(), nullable=True),
|
|
||||||
sa.Column("raison", sa.Text(), nullable=True),
|
|
||||||
sa.Column("fichier", sa.Date(), nullable=True),
|
|
||||||
sa.ForeignKeyConstraint(["etudid"], ["identite.id"], ondelete="CASCADE"),
|
|
||||||
sa.PrimaryKeyConstraint("justifid"),
|
|
||||||
)
|
|
||||||
op.create_index(
|
|
||||||
op.f("ix_justificatifs_etudid"), "justificatifs", ["etudid"], unique=False
|
|
||||||
)
|
|
||||||
op.create_table(
|
|
||||||
"assiduites",
|
|
||||||
sa.Column("id", sa.Integer(), nullable=False),
|
|
||||||
sa.Column(
|
|
||||||
"date_debut",
|
|
||||||
sa.DateTime(timezone=True),
|
|
||||||
server_default=sa.text("now()"),
|
|
||||||
nullable=False,
|
|
||||||
),
|
|
||||||
sa.Column(
|
|
||||||
"date_fin",
|
|
||||||
sa.DateTime(timezone=True),
|
|
||||||
server_default=sa.text("now()"),
|
|
||||||
nullable=False,
|
|
||||||
),
|
|
||||||
sa.Column("moduleimpl_id", sa.Integer(), nullable=True),
|
|
||||||
sa.Column("etudid", sa.Integer(), nullable=False),
|
|
||||||
sa.Column("etat", sa.Integer(), nullable=False),
|
|
||||||
sa.ForeignKeyConstraint(["etudid"], ["identite.id"], ondelete="CASCADE"),
|
|
||||||
sa.ForeignKeyConstraint(
|
|
||||||
["moduleimpl_id"], ["notes_moduleimpl.id"], ondelete="SET NULL"
|
|
||||||
),
|
|
||||||
sa.PrimaryKeyConstraint("id"),
|
|
||||||
)
|
|
||||||
op.create_index(
|
|
||||||
op.f("ix_assiduites_etudid"), "assiduites", ["etudid"], unique=False
|
|
||||||
)
|
|
||||||
# ### end Alembic commands ###
|
|
||||||
|
|
||||||
|
|
||||||
def downgrade():
|
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
|
||||||
op.drop_index(op.f("ix_assiduites_etudid"), table_name="assiduites")
|
|
||||||
op.drop_table("assiduites")
|
|
||||||
op.drop_index(op.f("ix_justificatifs_etudid"), table_name="justificatifs")
|
|
||||||
op.drop_table("justificatifs")
|
|
||||||
# ### end Alembic commands ###
|
|
@ -0,0 +1,55 @@
|
|||||||
|
"""Modèle Assiduites et Justificatifs
|
||||||
|
|
||||||
|
Revision ID: 943eb2deb22e
|
||||||
|
Revises: 25e3ca6cc063
|
||||||
|
Create Date: 2023-01-30 14:08:47.214916
|
||||||
|
|
||||||
|
"""
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = '943eb2deb22e'
|
||||||
|
down_revision = '25e3ca6cc063'
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.create_table('justificatifs',
|
||||||
|
sa.Column('justif_id', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('date_debut', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=False),
|
||||||
|
sa.Column('date_fin', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=False),
|
||||||
|
sa.Column('etudid', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('etat', sa.Integer(), nullable=True),
|
||||||
|
sa.Column('raison', sa.Text(), nullable=True),
|
||||||
|
sa.Column('fichier', sa.Text(), nullable=True),
|
||||||
|
sa.ForeignKeyConstraint(['etudid'], ['identite.id'], ondelete='CASCADE'),
|
||||||
|
sa.PrimaryKeyConstraint('justif_id')
|
||||||
|
)
|
||||||
|
op.create_index(op.f('ix_justificatifs_etudid'), 'justificatifs', ['etudid'], unique=False)
|
||||||
|
op.create_table('assiduites',
|
||||||
|
sa.Column('id', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('date_debut', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=False),
|
||||||
|
sa.Column('date_fin', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=False),
|
||||||
|
sa.Column('moduleimpl_id', sa.Integer(), nullable=True),
|
||||||
|
sa.Column('etudid', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('etat', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('desc', sa.Text(), nullable=True),
|
||||||
|
sa.ForeignKeyConstraint(['etudid'], ['identite.id'], ondelete='CASCADE'),
|
||||||
|
sa.ForeignKeyConstraint(['moduleimpl_id'], ['notes_moduleimpl.id'], ondelete='SET NULL'),
|
||||||
|
sa.PrimaryKeyConstraint('id')
|
||||||
|
)
|
||||||
|
op.create_index(op.f('ix_assiduites_etudid'), 'assiduites', ['etudid'], unique=False)
|
||||||
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.drop_index(op.f('ix_assiduites_etudid'), table_name='assiduites')
|
||||||
|
op.drop_table('assiduites')
|
||||||
|
op.drop_index(op.f('ix_justificatifs_etudid'), table_name='justificatifs')
|
||||||
|
op.drop_table('justificatifs')
|
||||||
|
# ### end Alembic commands ###
|
@ -21,6 +21,7 @@ ASSIDUITES_FIELDS = {
|
|||||||
"date_debut": str,
|
"date_debut": str,
|
||||||
"date_fin": str,
|
"date_fin": str,
|
||||||
"etat": str,
|
"etat": str,
|
||||||
|
"desc": str,
|
||||||
}
|
}
|
||||||
|
|
||||||
CREATE_FIELD = {"assiduite_id": int}
|
CREATE_FIELD = {"assiduite_id": int}
|
||||||
@ -34,7 +35,7 @@ TO_REMOVE = []
|
|||||||
def check_fields(data, fields=ASSIDUITES_FIELDS):
|
def check_fields(data, fields=ASSIDUITES_FIELDS):
|
||||||
assert set(data.keys()) == set(fields.keys())
|
assert set(data.keys()) == set(fields.keys())
|
||||||
for key in data:
|
for key in data:
|
||||||
if key == "moduleimpl_id":
|
if key in ("moduleimpl_id", "desc"):
|
||||||
assert isinstance(data[key], fields[key]) or data[key] is None
|
assert isinstance(data[key], fields[key]) or data[key] is None
|
||||||
else:
|
else:
|
||||||
assert isinstance(data[key], fields[key])
|
assert isinstance(data[key], fields[key])
|
||||||
@ -62,7 +63,7 @@ def check_failure_post(path, headers, data, err=None):
|
|||||||
raise APIError("Le GET n'aurait pas du fonctionner")
|
raise APIError("Le GET n'aurait pas du fonctionner")
|
||||||
|
|
||||||
|
|
||||||
def create_data(etat: str, day: str, module=None):
|
def create_data(etat: str, day: str, module: int = None, desc: str = None):
|
||||||
data = {
|
data = {
|
||||||
"date_debut": f"2022-01-{day}T08:00",
|
"date_debut": f"2022-01-{day}T08:00",
|
||||||
"date_fin": f"2022-01-{day}T10:00",
|
"date_fin": f"2022-01-{day}T10:00",
|
||||||
@ -71,6 +72,8 @@ def create_data(etat: str, day: str, module=None):
|
|||||||
|
|
||||||
if module is not None:
|
if module is not None:
|
||||||
data["moduleimpl_id"] = module
|
data["moduleimpl_id"] = module
|
||||||
|
if desc is not None:
|
||||||
|
data["desc"] = desc
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
@ -187,48 +190,53 @@ def test_route_count_formsemestre_assiduites(api_headers):
|
|||||||
|
|
||||||
def test_route_create(api_headers):
|
def test_route_create(api_headers):
|
||||||
|
|
||||||
# -== Sans batch ==-
|
# -== Unique ==-
|
||||||
|
|
||||||
# Bon fonctionnement
|
# Bon fonctionnement
|
||||||
data = create_data("present", "01")
|
data = create_data("present", "01")
|
||||||
|
|
||||||
res = POST_JSON(f"/assiduite/{ETUDID}/create", data, api_headers)
|
res = POST_JSON(f"/assiduite/{ETUDID}/create", [data], api_headers)
|
||||||
check_fields(res, CREATE_FIELD)
|
check_fields(res, BATCH_FIELD)
|
||||||
TO_REMOVE.append(res["assiduite_id"])
|
assert len(res["success"]) == 1
|
||||||
|
|
||||||
data2 = create_data("absent", "02", MODULE)
|
TO_REMOVE.append(res["success"]["0"]["assiduite_id"])
|
||||||
res = POST_JSON(f"/assiduite/{ETUDID}/create", data2, api_headers)
|
|
||||||
check_fields(res, CREATE_FIELD)
|
data2 = create_data("absent", "02", MODULE, "desc")
|
||||||
TO_REMOVE.append(res["assiduite_id"])
|
res = POST_JSON(f"/assiduite/{ETUDID}/create", [data2], api_headers)
|
||||||
|
check_fields(res, BATCH_FIELD)
|
||||||
|
assert len(res["success"]) == 1
|
||||||
|
|
||||||
|
TO_REMOVE.append(res["success"]["0"]["assiduite_id"])
|
||||||
|
|
||||||
# Mauvais fonctionnement
|
# Mauvais fonctionnement
|
||||||
check_failure_post(f"/assiduite/{FAUX}/create", api_headers, data)
|
check_failure_post(f"/assiduite/{FAUX}/create", api_headers, [data])
|
||||||
check_failure_post(
|
|
||||||
f"/assiduite/{ETUDID}/create",
|
res = POST_JSON(f"/assiduite/{ETUDID}/create", [data], api_headers)
|
||||||
api_headers,
|
check_fields(res, BATCH_FIELD)
|
||||||
data,
|
assert len(res["errors"]) == 1
|
||||||
err="Duplication des assiduités (la période rentrée rentre en conflit avec une assiduité enregistrée)",
|
assert (
|
||||||
)
|
res["errors"]["0"]
|
||||||
check_failure_post(
|
== "Duplication des assiduités (la période rentrée rentre en conflit avec une assiduité enregistrée)"
|
||||||
f"/assiduite/{ETUDID}/create",
|
|
||||||
api_headers,
|
|
||||||
create_data("absent", "03", FAUX),
|
|
||||||
err="param 'moduleimpl_id': invalide",
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# -== Avec batch ==-
|
res = POST_JSON(
|
||||||
|
f"/assiduite/{ETUDID}/create", [create_data("absent", "03", FAUX)], api_headers
|
||||||
|
)
|
||||||
|
check_fields(res, BATCH_FIELD)
|
||||||
|
assert len(res["errors"]) == 1
|
||||||
|
assert res["errors"]["0"] == "param 'moduleimpl_id': invalide"
|
||||||
|
|
||||||
|
# -== Multiple ==-
|
||||||
|
|
||||||
# Bon Fonctionnement
|
# Bon Fonctionnement
|
||||||
|
|
||||||
etats = ["present", "absent", "retard"]
|
etats = ["present", "absent", "retard"]
|
||||||
data = {
|
data = [
|
||||||
"batch": [
|
create_data(etats[d % 3], 10 + d, MODULE if d % 2 else None)
|
||||||
create_data(etats[d % 3], 10 + d, MODULE if d % 2 else None)
|
for d in range(randint(3, 5))
|
||||||
for d in range(randint(3, 5))
|
]
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
res = POST_JSON(f"/assiduite/{ETUDID}/create/batch", data, api_headers)
|
res = POST_JSON(f"/assiduite/{ETUDID}/create", data, api_headers)
|
||||||
check_fields(res, BATCH_FIELD)
|
check_fields(res, BATCH_FIELD)
|
||||||
for dat in res["success"]:
|
for dat in res["success"]:
|
||||||
check_fields(res["success"][dat], CREATE_FIELD)
|
check_fields(res["success"][dat], CREATE_FIELD)
|
||||||
@ -236,16 +244,14 @@ def test_route_create(api_headers):
|
|||||||
|
|
||||||
# Mauvais Fonctionnement
|
# Mauvais Fonctionnement
|
||||||
|
|
||||||
data2 = {
|
data2 = [
|
||||||
"batch": [
|
create_data("present", "01"),
|
||||||
create_data("present", "01"),
|
create_data("present", "25", FAUX),
|
||||||
create_data("present", "25", FAUX),
|
create_data("blabla", 26),
|
||||||
create_data("blabla", 26),
|
create_data("absent", 32),
|
||||||
create_data("absent", 32),
|
]
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
res = POST_JSON(f"/assiduite/{ETUDID}/create/batch", data2, api_headers)
|
res = POST_JSON(f"/assiduite/{ETUDID}/create", data2, api_headers)
|
||||||
check_fields(res, BATCH_FIELD)
|
check_fields(res, BATCH_FIELD)
|
||||||
assert len(res["errors"]) == 4
|
assert len(res["errors"]) == 4
|
||||||
|
|
||||||
@ -286,43 +292,41 @@ def test_route_edit(api_headers):
|
|||||||
|
|
||||||
|
|
||||||
def test_route_delete(api_headers):
|
def test_route_delete(api_headers):
|
||||||
# -== Sans batch ==-
|
# -== Unique ==-
|
||||||
|
|
||||||
# Bon fonctionnement
|
# Bon fonctionnement
|
||||||
data = {"assiduite_id": TO_REMOVE[0]}
|
data = TO_REMOVE[0]
|
||||||
|
|
||||||
res = POST_JSON(f"/assiduite/delete", data, api_headers)
|
res = POST_JSON(f"/assiduite/delete", [data], api_headers)
|
||||||
assert res == {"OK": True}
|
check_fields(res, BATCH_FIELD)
|
||||||
|
for dat in res["success"]:
|
||||||
|
assert res["success"][dat] == {"OK": True}
|
||||||
|
|
||||||
# Mauvais fonctionnement
|
# Mauvais fonctionnement
|
||||||
check_failure_post(
|
res = POST_JSON(f"/assiduite/delete", [data], api_headers)
|
||||||
f"/assiduite/delete",
|
check_fields(res, BATCH_FIELD)
|
||||||
api_headers,
|
assert len(res["errors"]) == 1
|
||||||
{"assiduite_id": FAUX},
|
|
||||||
err="Assiduite non existante",
|
# -== Multiple ==-
|
||||||
)
|
|
||||||
# -== Avec batch ==-
|
|
||||||
|
|
||||||
# Bon Fonctionnement
|
# Bon Fonctionnement
|
||||||
|
|
||||||
data = {"batch": TO_REMOVE[1:]}
|
data = TO_REMOVE[1:]
|
||||||
|
|
||||||
res = POST_JSON(f"/assiduite/delete/batch", data, api_headers)
|
res = POST_JSON(f"/assiduite/delete", data, api_headers)
|
||||||
check_fields(res, BATCH_FIELD)
|
check_fields(res, BATCH_FIELD)
|
||||||
for dat in res["success"]:
|
for dat in res["success"]:
|
||||||
assert res["success"][dat] == {"OK": True}
|
assert res["success"][dat] == {"OK": True}
|
||||||
|
|
||||||
# Mauvais Fonctionnement
|
# Mauvais Fonctionnement
|
||||||
|
|
||||||
data2 = {
|
data2 = [
|
||||||
"batch": [
|
FAUX,
|
||||||
FAUX,
|
FAUX + 1,
|
||||||
FAUX + 1,
|
FAUX + 2,
|
||||||
FAUX + 2,
|
]
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
res = POST_JSON(f"/assiduite/delete/batch", data2, api_headers)
|
res = POST_JSON(f"/assiduite/delete", data2, api_headers)
|
||||||
check_fields(res, BATCH_FIELD)
|
check_fields(res, BATCH_FIELD)
|
||||||
assert len(res["errors"]) == 3
|
assert len(res["errors"]) == 3
|
||||||
|
|
||||||
|
@ -124,8 +124,6 @@ def editer_supprimer_assiduiter(etuds: list[Identite], moduleimpls: list[int]):
|
|||||||
- Vérification de la suppression des assiduitées
|
- Vérification de la suppression des assiduitées
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from sqlalchemy.exc import IntegrityError
|
|
||||||
|
|
||||||
ass1: Assiduite = etuds[0].assiduites.first()
|
ass1: Assiduite = etuds[0].assiduites.first()
|
||||||
ass2: Assiduite = etuds[1].assiduites.first()
|
ass2: Assiduite = etuds[1].assiduites.first()
|
||||||
ass3: Assiduite = etuds[2].assiduites.first()
|
ass3: Assiduite = etuds[2].assiduites.first()
|
||||||
@ -173,42 +171,53 @@ def ajouter_assiduites(
|
|||||||
"deb": "2022-09-03T08:00+01:00",
|
"deb": "2022-09-03T08:00+01:00",
|
||||||
"fin": "2022-09-03T10:00+01:00",
|
"fin": "2022-09-03T10:00+01:00",
|
||||||
"moduleimpl": None,
|
"moduleimpl": None,
|
||||||
|
"desc": None,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"etat": scu.EtatAssiduite.PRESENT,
|
"etat": scu.EtatAssiduite.PRESENT,
|
||||||
"deb": "2023-01-03T08:00+01:00",
|
"deb": "2023-01-03T08:00+01:00",
|
||||||
"fin": "2023-01-03T10:00+01:00",
|
"fin": "2023-01-03T10:00+01:00",
|
||||||
"moduleimpl": moduleimpls[2],
|
"moduleimpl": moduleimpls[2],
|
||||||
|
"desc": None,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"etat": scu.EtatAssiduite.ABSENT,
|
"etat": scu.EtatAssiduite.ABSENT,
|
||||||
"deb": "2022-09-03T10:00:01+01:00",
|
"deb": "2022-09-03T10:00:01+01:00",
|
||||||
"fin": "2022-09-03T11:00+01:00",
|
"fin": "2022-09-03T11:00+01:00",
|
||||||
"moduleimpl": moduleimpls[0],
|
"moduleimpl": moduleimpls[0],
|
||||||
|
"desc": None,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"etat": scu.EtatAssiduite.ABSENT,
|
"etat": scu.EtatAssiduite.ABSENT,
|
||||||
"deb": "2022-09-03T14:00:00+01:00",
|
"deb": "2022-09-03T14:00:00+01:00",
|
||||||
"fin": "2022-09-03T15:00+01:00",
|
"fin": "2022-09-03T15:00+01:00",
|
||||||
"moduleimpl": moduleimpls[1],
|
"moduleimpl": moduleimpls[1],
|
||||||
|
"desc": "Description",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"etat": scu.EtatAssiduite.RETARD,
|
"etat": scu.EtatAssiduite.RETARD,
|
||||||
"deb": "2023-01-03T11:00:01+01:00",
|
"deb": "2023-01-03T11:00:01+01:00",
|
||||||
"fin": "2023-01-03T12:00+01:00",
|
"fin": "2023-01-03T12:00+01:00",
|
||||||
"moduleimpl": moduleimpls[3],
|
"moduleimpl": moduleimpls[3],
|
||||||
|
"desc": None,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"etat": scu.EtatAssiduite.RETARD,
|
"etat": scu.EtatAssiduite.RETARD,
|
||||||
"deb": "2023-01-04T11:00:01+01:00",
|
"deb": "2023-01-04T11:00:01+01:00",
|
||||||
"fin": "2023-01-04T12:00+01:00",
|
"fin": "2023-01-04T12:00+01:00",
|
||||||
"moduleimpl": moduleimpls[3],
|
"moduleimpl": moduleimpls[3],
|
||||||
|
"desc": "Description",
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
assiduites = [
|
assiduites = [
|
||||||
Assiduite.create_assiduite(
|
Assiduite.create_assiduite(
|
||||||
etud, ass["deb"], ass["fin"], ass["etat"], ass["moduleimpl"]
|
etud,
|
||||||
|
ass["deb"],
|
||||||
|
ass["fin"],
|
||||||
|
ass["etat"],
|
||||||
|
ass["moduleimpl"],
|
||||||
|
ass["desc"],
|
||||||
)
|
)
|
||||||
for ass in obj_assiduites
|
for ass in obj_assiduites
|
||||||
]
|
]
|
||||||
@ -225,6 +234,7 @@ def ajouter_assiduites(
|
|||||||
"deb": "2023-01-04T11:00:01+01:00",
|
"deb": "2023-01-04T11:00:01+01:00",
|
||||||
"fin": "2023-01-04T12:00+01:00",
|
"fin": "2023-01-04T12:00+01:00",
|
||||||
"moduleimpl": moduleimpls[3],
|
"moduleimpl": moduleimpls[3],
|
||||||
|
"desc": "Description",
|
||||||
}
|
}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -234,6 +244,7 @@ def ajouter_assiduites(
|
|||||||
test_assiduite["fin"],
|
test_assiduite["fin"],
|
||||||
test_assiduite["etat"],
|
test_assiduite["etat"],
|
||||||
test_assiduite["moduleimpl"],
|
test_assiduite["moduleimpl"],
|
||||||
|
test_assiduite["desc"],
|
||||||
)
|
)
|
||||||
except ScoValueError as excp:
|
except ScoValueError as excp:
|
||||||
assert (
|
assert (
|
||||||
@ -247,6 +258,7 @@ def ajouter_assiduites(
|
|||||||
test_assiduite["fin"],
|
test_assiduite["fin"],
|
||||||
test_assiduite["etat"],
|
test_assiduite["etat"],
|
||||||
test_assiduite["moduleimpl"],
|
test_assiduite["moduleimpl"],
|
||||||
|
test_assiduite["desc"],
|
||||||
)
|
)
|
||||||
except ScoValueError as excp:
|
except ScoValueError as excp:
|
||||||
assert excp.args[0] == "L'étudiant n'est pas inscrit au moduleimpl"
|
assert excp.args[0] == "L'étudiant n'est pas inscrit au moduleimpl"
|
||||||
|
Loading…
Reference in New Issue
Block a user