from flask import Blueprint, jsonify, request from server.permissions import admin_or_higher from server.database import Session from models.models import AcademicPeriod from datetime import datetime academic_periods_bp = Blueprint( 'academic_periods', __name__, url_prefix='/api/academic_periods') @academic_periods_bp.route('', methods=['GET']) def list_academic_periods(): session = Session() try: periods = session.query(AcademicPeriod).order_by( AcademicPeriod.start_date.asc()).all() return jsonify({ 'periods': [p.to_dict() for p in periods] }) finally: session.close() @academic_periods_bp.route('/active', methods=['GET']) def get_active_academic_period(): session = Session() try: period = session.query(AcademicPeriod).filter( AcademicPeriod.is_active == True).first() if not period: return jsonify({'period': None}), 200 return jsonify({'period': period.to_dict()}), 200 finally: session.close() @academic_periods_bp.route('/for_date', methods=['GET']) def get_period_for_date(): """ Returns the academic period that covers the provided date (YYYY-MM-DD). If multiple match, prefer the one with the latest start_date. """ date_str = request.args.get('date') if not date_str: return jsonify({'error': 'Missing required query param: date (YYYY-MM-DD)'}), 400 try: target = datetime.strptime(date_str, '%Y-%m-%d').date() except ValueError: return jsonify({'error': 'Invalid date format. Expected YYYY-MM-DD'}), 400 session = Session() try: period = ( session.query(AcademicPeriod) .filter(AcademicPeriod.start_date <= target, AcademicPeriod.end_date >= target) .order_by(AcademicPeriod.start_date.desc()) .first() ) return jsonify({'period': period.to_dict() if period else None}), 200 finally: session.close() @academic_periods_bp.route('/active', methods=['POST']) @admin_or_higher def set_active_academic_period(): data = request.get_json(silent=True) or {} period_id = data.get('id') if period_id is None: return jsonify({'error': 'Missing required field: id'}), 400 session = Session() try: target = session.query(AcademicPeriod).get(period_id) if not target: return jsonify({'error': 'AcademicPeriod not found'}), 404 # Deactivate all, then activate target session.query(AcademicPeriod).filter(AcademicPeriod.is_active == True).update( {AcademicPeriod.is_active: False} ) target.is_active = True session.commit() session.refresh(target) return jsonify({'period': target.to_dict()}), 200 finally: session.close()