from datetime import date
from flask import Blueprint, render_template, request, abort, redirect, url_for, flash
from flask_login import login_required, current_user
from app.models import db, Intern, Attendance, User
from app.services.statistics import intern_stats, monthly_calendar
from app.utils import parse_period
interns_bp = Blueprint("interns", __name__, url_prefix="/interns")
def _can_access(intern: Intern) -> bool:
return current_user.is_center or intern.mentor_id == current_user.id
@interns_bp.route("/")
@login_required
def list_interns():
# Показываем архив только по запросу ?archive=1
show_archive = request.args.get("archive") == "1"
q = Intern.query.filter_by(is_archived=show_archive)
if current_user.is_center:
mentor_id = request.args.get("mentor_id", type=int)
if mentor_id:
q = q.filter_by(mentor_id=mentor_id)
else:
q = q.filter_by(mentor_id=current_user.id)
interns = q.order_by(Intern.full_name).all()
mentors = User.query.filter_by(role="mentor").order_by(User.full_name).all() if current_user.is_center else []
return render_template("interns/list.html", interns=interns, mentors=mentors, show_archive=show_archive)
@interns_bp.route("/<int:intern_id>")
@login_required
def detail(intern_id: int):
intern = Intern.query.get_or_404(intern_id)
if not _can_access(intern): abort(403)
today = date.today()
year = request.args.get("year", today.year, type=int)
month = request.args.get("month", today.month, type=int)
if month < 1: month, year = 12, year - 1
elif month > 12: month, year = 1, year + 1
weeks = monthly_calendar(year, month)
records = Attendance.query.filter_by(intern_id=intern_id).all()
att_map = {r.date.day: r for r in records if r.date.year == year and r.date.month == month}
date_from, date_to = parse_period(default_days=30)
stats_period = intern_stats(intern_id, date_from, date_to)
stats_all = intern_stats(intern_id)
prev_year, prev_month = (year, month - 1) if month > 1 else (year - 1, 12)
next_year, next_month = (year, month + 1) if month < 12 else (year + 1, 1)
return render_template(
"interns/detail.html",
intern=intern, weeks=weeks, year=year, month=month, att_map=att_map,
stats_period=stats_period, stats_all=stats_all, today=today,
date_from=date_from, date_to=date_to,
prev_year=prev_year, prev_month=prev_month, next_year=next_year, next_month=next_month,
)
# --- НОВЫЕ МАРШРУТЫ ДЛЯ ЦЕНТРА ---
@interns_bp.route("/<int:intern_id>/assign", methods=["POST"])
@login_required
def assign_mentor(intern_id: int):
if not current_user.is_center: abort(403)
intern = Intern.query.get_or_404(intern_id)
mentor_id = request.form.get("mentor_id", type=int)
if mentor_id:
intern.mentor_id = mentor_id
db.session.commit()
flash("Наставник успешно изменен", "success")
return redirect(request.referrer or url_for("main.dashboard"))
@interns_bp.route("/<int:intern_id>/archive", methods=["POST"])
@login_required
def archive_intern(intern_id: int):
if not current_user.is_center: abort(403)
intern = Intern.query.get_or_404(intern_id)
intern.is_archived = True
db.session.commit()
flash("Стажёр перемещён в архив", "info")
return redirect(request.referrer or url_for("main.dashboard"))