from flask import Blueprint, render_template, request, session, redirect, url_for, flash from database import execute_query, get_db_connection from blueprints.auth import login_required from rechten import recht_vereist from services.google_service import GoogleAdminService from services.sync_service import SyncService, InformatSmartschoolSync from config import Config students_bp = Blueprint('students', __name__) #----------------------------------------------- # --- ROUTE: INVENTARIS LEERLINGEN --- #----------------------------------------------- @students_bp.route('/inventaris', methods=["GET", "POST"]) @login_required @recht_vereist('leerlingen_bekijken') def inventaris_leerlingen(): query = request.form.get('query') if request.method == 'POST' else request.args.get('query') toon_vertrokken = (request.form.get('vertrokken') if request.method == 'POST' else request.args.get('vertrokken')) == '1' from services.sync_service import zorg_vertrokken_kolom zorg_vertrokken_kolom() # De basis-query waarin we de tabellen 'Leerlingen' (l) en 'Schooljaar' (s) aan elkaar koppelen basis_sql = """ SELECT l.Internnummer, l.Gebruikersnaam, l.Voornaam, l.Naam, l.SS_nummer, l.Google_adres, l.Vertrokken_op, s.Schooljaar AS Schooljaar -- Hier halen we de tekst (bijv. '2025-2026') op! FROM Leerlingen l LEFT JOIN Schooljaar s ON l.Schooljaar_ID = s.Schooljaar_ID """ voorwaarden, params = [], [] if query: voorwaarden.append("(l.Gebruikersnaam LIKE %s OR l.Internnummer LIKE %s OR l.Naam LIKE %s OR l.Voornaam LIKE %s)") params += [f"%{query}%"] * 4 if not toon_vertrokken: voorwaarden.append("l.Vertrokken_op IS NULL") sql = basis_sql + (" WHERE " + " AND ".join(voorwaarden) if voorwaarden else "") data = execute_query(sql, tuple(params)) vertrokken = (execute_query("SELECT COUNT(*) AS n FROM Leerlingen WHERE Vertrokken_op IS NOT NULL") or [{'n': 0}])[0]['n'] return render_template('Inventaris_Leerlingen.html', results=data, query=query, toon_vertrokken=toon_vertrokken, aantal_vertrokken=vertrokken) #---------------------------------------- # --- ROUTE: BEWERK GEBRUIKER --- #---------------------------------------- @students_bp.route("/bewerk_gebruiker", methods=["POST"]) @login_required @recht_vereist('leerlingen_bekijken') def bewerk_gebruiker(): print("bewerken wordt uitgevoerd") internnummer = request.form.get("internnummer") gebruikersnaam = request.form.get("gebruikersnaam") ss_nummer = request.form.get("ss_nummer") google_adres = request.form.get('google_adres') naam= request.form.get('naam') voornaam= request.form.get('voornaam') query = request.form.get("query", "") if not internnummer: flash("Fout: Geen internnummer ontvangen.", "error") return redirect(url_for("students.inventaris_leerlingen")) sql = "UPDATE Leerlingen SET Gebruikersnaam = %s, SS_nummer = %s, Google_adres = %s, Naam = %s, Voornaam= %s WHERE Internnummer = %s" rows_affected = execute_query(sql, (gebruikersnaam, ss_nummer, google_adres, naam, voornaam, internnummer ), commit=True) if rows_affected: flash(f"Gegevens voor {internnummer} succesvol bijgewerkt!", "success") else: flash("Er zijn geen wijzigingen opgeslagen.", "info") return redirect(url_for("students.inventaris_leerlingen", query=query)) #---------------------------------------------------- # --- ROUTE: SYNC GOOGLE ACCOUNTS --- #---------------------------------------------------- @students_bp.route("/sync_google_accounts", methods=["GET", "POST"]) @login_required @recht_vereist('leerlingen_synchroniseren') def sync_google_accounts(): """Maakt Google accounts aan voor leerlingen die er nog geen hebben.""" google = GoogleAdminService() # Haal leerlingen op die nog geen email (SS_nummer) hebben lln_zonder_mail = execute_query("SELECT Internnummer, Gebruikersnaam FROM Leerlingen WHERE SS_nummer IS NULL OR SS_nummer = ''") created_count = 0 error_count = 0 for lln in lln_zonder_mail: gebruikersnaam_db = lln['Gebruikersnaam'] # Splits naam (bijv: "Janssens.Jan") if "." in gebruikersnaam_db: achternaam, voornaam = gebruikersnaam_db.split(".", 1) else: achternaam, voornaam = gebruikersnaam_db, "lln" # Genereer wachtwoord (bijv: 12345Jan) password = f"{lln['Internnummer']}{voornaam.capitalize()}" # Gebruik je service om de gebruiker aan te maken success, message = google.create_user( first_name=voornaam, last_name=achternaam, password=password, org_unit_path=google.conf.OU_NEW_STUDENTS ) if success: # Update database met het nieuwe emailadres email = f"{voornaam.lower()}.{achternaam.lower()}@{google.conf.SCHOOL_DOMAIN}" execute_query("UPDATE Leerlingen SET SS_nummer = %s WHERE Internnummer = %s", (email, lln['Internnummer']), commit=True) created_count += 1 else: print(f"Fout voor {gebruikersnaam_db}: {message}") error_count += 1 flash(f"Sync voltooid: {created_count} accounts aangemaakt, {error_count} fouten.", "success") return redirect(url_for("students.inventaris_leerlingen")) #------------------------------------------------------------------- # --- ROUTE: SYNC INFORMAT (Gebruikmakend van SyncService) --- #------------------------------------------------------------------- @students_bp.route("/sync_informat", methods=["GET", "POST"]) @login_required @recht_vereist('leerlingen_synchroniseren') def sync_informat(): """Haalt de nieuwste leerlinggegevens op uit Informat.""" #syncer = SyncService() syncer = InformatSmartschoolSync() #success, result = syncer.sync_leerlingen_informat() success, result = syncer.sync_actieve_leerlingen() if success: flash(f"Synchronisatie gelukt: {result['melding']}", "success") if result.get('smartschool_fout'): flash("Smartschool kon niet bevraagd worden, dus gebruikersnamen en Smartschool-nummers zijn niet " f"aangepast (enkel de gegevens uit Informat). Reden: {result['smartschool_fout']}", "warning") else: flash(f"Synchronisatie mislukt: {result}", "error") return redirect(url_for("students.inventaris_leerlingen")) #------------------------------------------------------------------- # --- Leerling manueel toevoegen #------------------------------------------------------------------- @students_bp.route('/registreer_leerling', methods=['POST']) @login_required @recht_vereist('leerlingen_synchroniseren') def registreer_leerling(): print('Toevoegen gestart') # 1. Haal de gegevens uit het formulier op internnummer = request.form.get('inter_id') gebruikersnaam = request.form.get('gebruikersnaam') ss_nummer = request.form.get('ss_nummer') google_adres = request.form.get('google_adres') schooljaar_id= Config.SCHOOLYEAR[:4] naam= request.form.get('naam') voornaam= request.form.get('voornaam') # 2. Validatie if not internnummer or not gebruikersnaam: flash('Zowel Internnummer als Gebruikersnaam zijn vereist.', 'danger') return redirect(url_for('students.inventaris_leerlingen')) # 3. Opslaan in de database try: # We gebruiken geparametriseerde queries (%s) om SQL-injectie te voorkomen sql = "INSERT INTO Leerlingen (Internnummer, Gebruikersnaam, Naam, Voornaam, SS_nummer, Google_adres, Schooljaar_ID) " \ "VALUES (%s, %s, %s, %s, %s, %s, %s)" params = (internnummer, gebruikersnaam,naam, voornaam, ss_nummer,google_adres, schooljaar_id) execute_query(sql, params, commit=True) flash(f'Leerling {gebruikersnaam} (ID: {internnummer}) succesvol toegevoegd aan de database!', 'success') except Exception as e: # Als bijvoorbeeld het internnummer al bestaat (Duplicate Entry) print(f"Database error: {e}") flash('Fout bij het registreren: Mogelijk bestaat dit Internnummer al.', 'danger') # 4. Keer terug naar het overzicht return redirect(url_for('students.inventaris_leerlingen'))