Initial commit

This commit is contained in:
Kristof committed 2026-10-14 12:29:29 +02:00
commit 536ff43ce4
158 files changed
+30355

No files matched your search

+104
View File
@@ -0,0 +1,104 @@
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