diff --git a/app/models/modules.py b/app/models/modules.py index 1a79c430..e309db1c 100644 --- a/app/models/modules.py +++ b/app/models/modules.py @@ -6,7 +6,7 @@ from app.models import APO_CODE_STR_LEN from app.models.but_refcomp import ApcParcours, app_critiques_modules, parcours_modules from app.scodoc import sco_utils as scu from app.scodoc.sco_codes_parcours import UE_SPORT -from app.scodoc.sco_utils import ModuleType +from app.scodoc.sco_utils import ModuleType, abbrev_prenom class Module(db.Model): @@ -69,6 +69,37 @@ class Module(db.Model): return f"""""" + def clone(self): + """Create a new copy of this module.""" + mod = Module( + titre=self.titre, + abbrev=self.abbrev, + code=self.code + "-copie", + heures_cours=self.heures_cours, + heures_td=self.heures_td, + heures_tp=self.heures_tp, + coefficient=self.coefficient, + ects=self.ects, + ue_id=self.ue_id, + matiere_id=self.matiere_id, + formation_id=self.formation_id, + semestre_id=self.semestre_id, + numero=self.numero, # il est conseillé de renuméroter + code_apogee="", # volontairement vide pour éviter les erreurs + module_type=self.module_type, + ) + + # Les tags: + for tag in self.tags: + mod.tags.append(tag) + # Les parcours + for parcour in self.parcours: + mod.parcours.append(parcour) + # Les AC + for app_critique in self.app_critiques: + mod.app_critiques.append(app_critique) + return mod + def to_dict(self, convert_objects=False, with_matiere=False, with_ue=False) -> dict: """If convert_objects, convert all attributes to native types (suitable jor json encoding). diff --git a/app/models/ues.py b/app/models/ues.py index 0de7e83b..a832375b 100644 --- a/app/models/ues.py +++ b/app/models/ues.py @@ -64,6 +64,28 @@ class UniteEns(db.Model): self.semestre_idx} { 'EXTERNE' if self.is_external else ''})>""" + def clone(self): + """Create a new copy of this ue. + Ne copie pas le code, ni le code Apogée, ni les liens au réf. de comp. + (parcours et niveau). + """ + ue = UniteEns( + formation_id=self.formation_id, + acronyme=self.acronyme + "-copie", + numero=self.numero, + titre=self.titre, + semestre_idx=self.semestre_idx, + type=self.type, + ue_code="", # ne duplique pas le code + ects=self.ects, + is_external=self.is_external, + code_apogee="", # ne copie pas les codes Apo + coefficient=self.coefficient, + coef_rcue=self.coef_rcue, + color=self.color, + ) + return ue + def to_dict(self, convert_objects=False, with_module_ue_coefs=True): """as a dict, with the same conversions as in ScoDoc7 (except ECTS: keep None) diff --git a/app/scodoc/sco_edit_module.py b/app/scodoc/sco_edit_module.py index ce78ca86..af714119 100644 --- a/app/scodoc/sco_edit_module.py +++ b/app/scodoc/sco_edit_module.py @@ -776,7 +776,18 @@ def module_edit( ) # if tf[0] == 0: - return "\n".join(H) + tf[1] + html_sco_header.sco_footer() + return ( + "\n".join(H) + + tf[1] + + f""" +
+ + +
+ """ + if not create + else "" + html_sco_header.sco_footer() + ) elif tf[0] == -1: return flask.redirect( url_for( diff --git a/app/scodoc/sco_edit_ue.py b/app/scodoc/sco_edit_ue.py index 5c61b64a..9d9eadf5 100644 --- a/app/scodoc/sco_edit_ue.py +++ b/app/scodoc/sco_edit_ue.py @@ -471,11 +471,21 @@ def ue_edit(ue_id=None, create=False, formation_id=None, default_semestre_idx=No modules_div += """""" else: modules_div = "" + if ue: + clone_form = f""" +
+ + +
+ """ + else: + clone_form = "" bonus_div = """
""" ue_div = """
""" return ( "\n".join(H) + tf[1] + + clone_form + niveau_competence_div + modules_div + bonus_div diff --git a/app/static/css/scodoc.css b/app/static/css/scodoc.css index 22e0395a..6e1e7104 100644 --- a/app/static/css/scodoc.css +++ b/app/static/css/scodoc.css @@ -2259,6 +2259,21 @@ ul.notes_module_list { list-style-type: none; } +input#tf_submit, +input#tf_cancel { + padding: 8px 20px; + font-size: 16px; + border-radius: 8px; +} + +input#tf_submit { + border: 2px solid #c50000; +} + +form.clone_form { + margin-top: 12px; +} + /*Choix niveau dans form edit UE */ div.ue_choix_niveau { background-color: rgb(191, 242, 255); diff --git a/app/views/notes.py b/app/views/notes.py index 64645dcb..14d530c2 100644 --- a/app/views/notes.py +++ b/app/views/notes.py @@ -580,6 +580,27 @@ def module_tag_set(): return sco_tag_module.module_tag_set(module_id, taglist) +@bp.route("/module_clone", methods=["POST"]) +@scodoc +@permission_required(Permission.ScoChangeFormation) +def module_clone(): + """Clone existing module""" + module_id = int(request.form.get("module_id")) + module = Module.query.get_or_404(module_id) + module2 = module.clone() + db.session.add(module2) + db.session.commit() + flash(f"Module {module.code} dupliqué") + return flask.redirect( + url_for( + "notes.ue_table", + scodoc_dept=g.scodoc_dept, + semestre_idx=module.semestre_id, + formation_id=module.formation_id, + ) + ) + + # @bp.route("/") @bp.route("/index_html") @@ -754,6 +775,27 @@ sco_publish( sco_publish("/ue_move", sco_edit_formation.ue_move, Permission.ScoChangeFormation) +@bp.route("/ue_clone", methods=["POST"]) +@scodoc +@permission_required(Permission.ScoChangeFormation) +def ue_clone(): + """Clone existing UE""" + ue_id = int(request.form.get("ue_id")) + ue = UniteEns.query.get_or_404(ue_id) + ue2 = ue.clone() + db.session.add(ue2) + db.session.commit() + flash(f"UE {ue.acronyme} dupliquée") + return flask.redirect( + url_for( + "notes.ue_table", + scodoc_dept=g.scodoc_dept, + semestre_idx=ue.semestre_idx, + formation_id=ue.formation_id, + ) + ) + + # --- Semestres de formation diff --git a/sco_version.py b/sco_version.py index 541bd6f8..58a1f1f9 100644 --- a/sco_version.py +++ b/sco_version.py @@ -1,7 +1,7 @@ # -*- mode: python -*- # -*- coding: utf-8 -*- -SCOVERSION = "9.4.0" +SCOVERSION = "9.4.01" SCONAME = "ScoDoc"