from flask import Blueprint, render_template, request, flash, jsonify, redirect, url_for, Response from services.smartschool_api import SmartschoolService from config import Config from services.google_service import GoogleAdminService from blueprints.auth import login_required from rechten import recht_vereist from services.coaccounts_service import CoAccountsService from tenancy import huidige_school # Definieer de blueprint ss_bp = Blueprint('smartschool', __name__) @ss_bp.route('/coaccount-overzicht', methods=['GET']) @login_required @recht_vereist('smartschool_activiteit') def coaccount_overzicht(): """Alle co-accounts van alle leerlingen (klas, leerling, laatste aanmelding). Standaard enkel wie nog nooit aanmeldde. De gegevens worden op de achtergrond opgehaald als ze ouder zijn dan een dag.""" svc = CoAccountsService() rows, fout, laatst = [], None, None ingesteld = huidige_school().heeft('SS_API_PLATFORM', 'SS_API_PW') try: svc.ensure_tables() if ingesteld and svc.verouderd(): svc.sync_op_achtergrond() rows, laatst = svc.alle(), svc.laatst_opgehaald() except Exception as e: fout = f"Gegevens konden niet gelezen worden: {e}" return render_template('smartschool_activiteit.html', rows=rows, fout=fout, laatst=laatst, ingesteld=ingesteld, status=svc.status, nooit=sum(1 for r in rows if not r['Laatste_login']), leerlingen=len({r['Internnummer'] for r in rows})) @ss_bp.route('/coaccount-overzicht/ophalen', methods=['POST']) @login_required @recht_vereist('smartschool_activiteit') def coaccount_ophalen(): if not huidige_school().heeft('SS_API_PLATFORM', 'SS_API_PW'): flash("Smartschool is nog niet ingesteld voor deze school (🔌 Koppelingen › Smartschool).", "error") elif CoAccountsService().sync_op_achtergrond(): flash("Co-accounts worden opgehaald uit Smartschool. Dit kan enkele minuten duren.", "info") else: flash("Er loopt al een ophaling.", "warning") return redirect(url_for('smartschool.coaccount_overzicht')) @ss_bp.route('/coaccount-overzicht/status.json', methods=['GET']) @login_required @recht_vereist('smartschool_activiteit') def coaccount_status(): s = CoAccountsService().status return jsonify(bezig=s['bezig'], voortgang=s['voortgang'], totaal=s['totaal'], fout=s['fout'], resultaat=s['resultaat']) @ss_bp.route('/coaccount-overzicht/export.csv', methods=['GET']) @login_required @recht_vereist('smartschool_activiteit') def coaccount_export(): """CSV met dezelfde filters als de tabel: ?nooit=1 (enkel nog nooit aangemeld) en ?zoek=...""" import csv, io from datetime import date rows = CoAccountsService().alle() if request.args.get('nooit') == '1': rows = [r for r in rows if not r['Laatste_login']] zoek = (request.args.get('zoek') or '').strip().lower() if zoek: velden = ('Klas', 'Leerling_voornaam', 'Leerling_naam', 'Gebruikersnaam', 'Internnummer', 'Voornaam', 'Naam', 'Email') rows = [r for r in rows if zoek in ' '.join(str(r[v] or '') for v in velden).lower()] buf = io.StringIO() w = csv.writer(buf, delimiter=';') # ; zodat Excel (Belgische instellingen) de kolommen meteen splitst w.writerow(['Klas', 'Leerling naam', 'Leerling voornaam', 'Internnummer', 'Co-account voornaam', 'Co-account naam', 'Type', 'E-mail', 'Laatste aanmelding']) for r in rows: w.writerow([r['Klas'] or '', r['Leerling_naam'] or '', r['Leerling_voornaam'] or '', r['Internnummer'], r['Voornaam'] or '', r['Naam'] or '', r['Type'] or '', r['Email'] or '', r['Laatste_login'].strftime('%d-%m-%Y %H:%M') if r['Laatste_login'] else 'Nooit']) naam = f"co-accounts{'_nooit_aangemeld' if request.args.get('nooit') == '1' else ''}_{date.today():%Y%m%d}.csv" return Response('\ufeff' + buf.getvalue(), mimetype='text/csv; charset=utf-8', headers={'Content-Disposition': f'attachment; filename={naam}'}) @ss_bp.route('/send-reminder-email', methods=['POST']) @login_required @recht_vereist('smartschool_activiteit') def send_reminder(): data = request.json email = data.get('email') subject = data.get('subject') message_body = data.get('message') if not email or "@" not in email: return jsonify({"status": "error", "message": "Geen geldig e-mailadres gevonden voor dit co-account."}), 400 email_service = GoogleAdminService() success, msg = email_service.send_custom_mail(email, subject, message_body) if success: return jsonify({"status": "success", "message": msg}) else: return jsonify({"status": "error", "message": f"Fout bij verzenden: {msg}"}), 500