feat: abm comisiones, hitos, links virtuales, eliminacion usuarios y roles bedelia y alumno

This commit is contained in:
Carlos Tello
2026-09-03 04:34:54 -03:00
parent 8809ff3410
commit f3a4b5875e
10 changed files with 1297 additions and 361 deletions
+51
View File
@@ -179,6 +179,36 @@ def user_toggle(id):
return redirect(url_for('admin.users_list'))
@admin_bp.route('/users/delete/<int:id>', methods=['POST'])
@admin_required
def user_delete(id):
"""Delete a user account"""
if id == current_user.id:
flash(_('No puedes eliminar tu propia cuenta mientras estás en sesión activa.'), 'error')
return redirect(url_for('admin.users_list'))
user = User.query.get_or_404(id)
# Protect sole system administrator
if user.is_admin():
admin_count = User.query.filter(User.role.ilike('%ADMIN%'), User.is_active == True).count()
if admin_count <= 1:
flash(_('No es posible eliminar al único administrador activo del sistema.'), 'error')
return redirect(url_for('admin.users_list'))
# Unassign user from commissions as teacher
from app.models.subject import Commission
Commission.query.filter_by(teacher_id=id).update({'teacher_id': None})
name = user.name
email = user.email
db.session.delete(user)
db.session.commit()
flash(_('El usuario "%(name)s" (%(email)s) ha sido eliminado del sistema.', name=name, email=email), 'success')
return redirect(url_for('admin.users_list'))
# ---------------------------------------------------------
# ROLES & PERMISSIONS MANAGEMENT (FortiGate Matrix)
# ---------------------------------------------------------
@@ -467,6 +497,27 @@ def milestone_type_toggle(id):
return redirect(url_for('admin.milestone_types_list'))
@admin_bp.route('/milestone-types/delete/<int:id>', methods=['POST'])
@permission_required('milestone_types', 'read_write')
def milestone_type_delete(id):
"""Delete a milestone type if unused, or deactivate with notice"""
item = MilestoneType.query.get_or_404(id)
from app.models.milestone import AcademicMilestone
milestone_count = AcademicMilestone.query.filter_by(milestone_type_id=id).count()
if milestone_count > 0:
item.is_active = False
db.session.commit()
flash(_('La tipificación "%(name)s" tiene %(count)d hitos registrados. Se ha desactivado para conservar el historial académico.', name=item.name, count=milestone_count), 'warning')
else:
name = item.name
db.session.delete(item)
db.session.commit()
flash(_('Tipificación "%(name)s" eliminada permanentemente.', name=name), 'success')
return redirect(url_for('admin.milestone_types_list'))
@admin_bp.route('/api/milestone-types')
@login_required
def api_milestone_types():