PIVOT 1.1.0
This commit is contained in:
commit
8a53234eb6
161 files changed
+31109
No files matched your search
@@ -0,0 +1,100 @@
|
||||
"""
|
||||
Beheer › Database: tabellen van de school aanvullen vanuit Excel.
|
||||
|
||||
Toestellen:
|
||||
GET /beheer/database/toestellen → pagina (upload + sjabloon)
|
||||
GET /beheer/database/toestellen/sjabloon.xlsx → sjabloon downloaden
|
||||
POST /beheer/database/toestellen/controleren → Excel lezen en voorbeeld tonen (niets bewaard)
|
||||
POST /beheer/database/toestellen/importeren → bevestigen: het voorbeeld uitvoeren
|
||||
"""
|
||||
import json
|
||||
|
||||
from flask import Blueprint, render_template, request, Response, redirect, url_for, flash, session
|
||||
|
||||
from blueprints.auth import login_required
|
||||
from database import execute_query
|
||||
from rechten import recht_vereist, log
|
||||
from services import toestellen_import as ti
|
||||
from tenancy import huidige_school
|
||||
|
||||
database_bp = Blueprint('database_beheer', __name__)
|
||||
|
||||
|
||||
@database_bp.route('/toestellen', methods=['GET'])
|
||||
@login_required
|
||||
@recht_vereist('database_toestellen')
|
||||
def toestellen():
|
||||
try:
|
||||
aantal = execute_query("SELECT COUNT(*) AS n FROM Toestellen")[0]['n']
|
||||
except Exception:
|
||||
aantal = None
|
||||
return render_template('database_toestellen.html', plan=None, aantal=aantal, kolommen=ti.KOLOMMEN,
|
||||
statussen=ti.STATUSSEN, max_rijen=ti.MAX_RIJEN)
|
||||
|
||||
|
||||
@database_bp.route('/toestellen/sjabloon.xlsx', methods=['GET'])
|
||||
@login_required
|
||||
@recht_vereist('database_toestellen')
|
||||
def toestellen_sjabloon():
|
||||
school = huidige_school()
|
||||
data = ti.maak_sjabloon(school.naam)
|
||||
return Response(data, mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
headers={'Content-Disposition': f"attachment; filename=Sjabloon_toestellen_{school.code}.xlsx"})
|
||||
|
||||
|
||||
@database_bp.route('/toestellen/controleren', methods=['POST'])
|
||||
@login_required
|
||||
@recht_vereist('database_toestellen')
|
||||
def toestellen_controleren():
|
||||
terug = redirect(url_for('database_beheer.toestellen'))
|
||||
bestand = request.files.get('bestand')
|
||||
if not bestand or not bestand.filename:
|
||||
flash("Kies eerst een Excel-bestand.", "error")
|
||||
return terug
|
||||
if not bestand.filename.lower().endswith(('.xlsx', '.xlsm')):
|
||||
flash("Enkel Excel-bestanden (.xlsx) kunnen ingelezen worden. Sla een .xls of .csv eerst op als .xlsx.", "error")
|
||||
return terug
|
||||
modus = 'overschrijven' if request.form.get('modus') == 'overschrijven' else 'aanvullen'
|
||||
try:
|
||||
rijen, onbekend = ti.lees_excel(bestand)
|
||||
except ti.ImportFout as e:
|
||||
flash(str(e), "error")
|
||||
return terug
|
||||
if not rijen:
|
||||
flash("Het bestand bevat geen toestellen (enkel kolomkoppen of lege rijen).", "warning")
|
||||
return terug
|
||||
try:
|
||||
plan = ti.maak_plan(rijen, modus)
|
||||
except Exception as e:
|
||||
flash(f"Controleren mislukt: {e}", "error")
|
||||
return terug
|
||||
return render_template('database_toestellen.html', plan=plan, bestandsnaam=bestand.filename, onbekend=onbekend,
|
||||
rijen_json=json.dumps(rijen, ensure_ascii=False), kolommen=ti.KOLOMMEN,
|
||||
statussen=ti.STATUSSEN, max_rijen=ti.MAX_RIJEN, aantal=None)
|
||||
|
||||
|
||||
@database_bp.route('/toestellen/importeren', methods=['POST'])
|
||||
@login_required
|
||||
@recht_vereist('database_toestellen')
|
||||
def toestellen_importeren():
|
||||
terug = redirect(url_for('database_beheer.toestellen'))
|
||||
modus = 'overschrijven' if request.form.get('modus') == 'overschrijven' else 'aanvullen'
|
||||
try:
|
||||
rijen = json.loads(request.form.get('rijen') or '[]')
|
||||
if not isinstance(rijen, list) or len(rijen) > ti.MAX_RIJEN or not all(isinstance(r, dict) for r in rijen):
|
||||
raise ValueError
|
||||
except ValueError:
|
||||
flash("De gegevens van het voorbeeld zijn ongeldig. Upload het bestand opnieuw.", "error")
|
||||
return terug
|
||||
try:
|
||||
plan, nieuw, bijgewerkt = ti.voer_uit(rijen, modus, session.get('user'))
|
||||
except Exception as e:
|
||||
flash(f"Importeren mislukt, er is niets bewaard: {e}", "error")
|
||||
return terug
|
||||
t = plan['tellers']
|
||||
log(f"Toestellen geïmporteerd uit Excel: {nieuw} nieuw, {bijgewerkt} bijgewerkt ({modus})")
|
||||
ongewijzigd = f", {t['ongewijzigd']} ongewijzigd" if t['ongewijzigd'] else ""
|
||||
flash(f"Import klaar: {nieuw} toestel(len) toegevoegd, {bijgewerkt} bijgewerkt{ongewijzigd}.", "success")
|
||||
if t['fout']:
|
||||
flash(f"{t['fout']} rij(en) met een fout werden overgeslagen.", "warning")
|
||||
return terug
|
||||
Reference in new issue
Block a user