You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kmftools/delfland/ppo-insight/ppo_insight.py

240 lines
7.5 KiB

import os
import io
import sqlite3
import re
from datetime import datetime
import pandas as pd
from dotenv import load_dotenv
from flask import Flask, request, render_template, redirect, url_for, flash, Response
from werkzeug.utils import secure_filename
env_path = "./.env"
load_dotenv(env_path)
UPLOAD_FOLDER = os.getenv("UPLOAD_FOLDER", "uploads")
DATABASE = "data.db"
ALLOWED_EXTENSIONS = {"xlsx"}
app = Flask(__name__)
app.config["UPLOAD_FOLDER"] = UPLOAD_FOLDER
app.secret_key = "9f2a1d3e4c5b6a7d8e9f0a1b2c3d4e5f"
def init_db():
with sqlite3.connect(DATABASE) as conn:
cursor = conn.cursor()
cursor.execute("""
CREATE TABLE IF NOT EXISTS onderhoud (
id INTEGER PRIMARY KEY AUTOINCREMENT,
Object_code TEXT,
Object_omschrijving TEXT,
Afdeling_object TEXT,
PO_Code TEXT,
Omschrijving_PO TEXT,
Vervaldatum TEXT,
Frequentie INTEGER,
UOM TEXT,
PO_schema_Niet_gebruikt TEXT,
Cluster TEXT,
Locatie TEXT,
Locatie_omschrijving TEXT,
Klasse_object TEXT,
Categorie TEXT
)
""")
conn.commit()
def allowed_file(filename):
return "." in filename and filename.rsplit(".", 1)[1].lower() in ALLOWED_EXTENSIONS
@app.route("/download", methods=["GET"])
def download_excel():
x_str = request.args.get("x")
if not x_str:
flash("Geen datum opgegeven voor download.", "danger")
return redirect(url_for("upload_file"))
try:
x = datetime.strptime(x_str, "%Y-%m-%d")
except ValueError:
flash("Ongeldige datum opgegeven.", "danger")
return redirect(url_for("upload_file"))
result = get_extrapolation(x)
if not result:
flash("Geen resultaten beschikbaar voor de geselecteerde datum.", "warning")
return redirect(url_for("upload_file"))
df = pd.DataFrame(result)
# Verwijder de Vervaldatum kolom
if 'Vervaldatum' in df.columns:
df = df.drop(columns=['Vervaldatum'])
# df.rename(columns={"Begindatum": "Vervaldatum"}, inplace=True)
output = io.BytesIO()
with pd.ExcelWriter(output, engine="openpyxl") as writer:
df.to_excel(writer, index=False,
sheet_name=f"Extrapolatie_{x.strftime('%Y-%m-%d')}")
output.seek(0)
filename = f"extrapolatie_{x.strftime('%Y-%m-%d')}.xlsx"
return Response(
output,
mimetype="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
headers={"Content-Disposition": f"attachment; filename={filename}"}
)
@app.route("/", methods=["GET", "POST"])
def upload_file():
if request.method == "POST":
if "file" not in request.files:
flash("Geen bestand geselecteerd", "danger")
return redirect(request.url)
file = request.files["file"]
if file.filename == "":
flash("Geen bestand geselecteerd", "danger")
return redirect(request.url)
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
filepath = os.path.join(app.config["UPLOAD_FOLDER"], filename)
file.save(filepath)
process_excel(filepath)
flash("Bestand geüpload en verwerkt! <a href='" +
url_for("show_result") + "'>Bekijk de resultaten</a>", "success")
return redirect(url_for("upload_file"))
return render_template("index.html")
@app.route("/debug_db", methods=["GET"])
def debug_db():
with sqlite3.connect(DATABASE) as conn:
cursor = conn.cursor()
cursor.execute("SELECT * FROM onderhoud")
columns = [desc[0] for desc in cursor.description]
rows = cursor.fetchall()
return render_template("debug.html", columns=columns, rows=rows)
def clean_column_name(name):
# Vervangt alle niet-alfanumerieke tekens door "_"
return re.sub(r"\W+", "_", name)
def process_excel(filepath):
df = pd.read_excel(filepath)
# Kolomnamen normaliseren
df.columns = [clean_column_name(col) for col in df.columns]
with sqlite3.connect(DATABASE) as conn:
cursor = conn.cursor()
cursor.execute("DELETE FROM onderhoud") # Leeg de tabel eerst
df.to_sql("onderhoud", conn, if_exists="append", index=False)
# Debug: Controleer of de records echt zijn toegevoegd
cursor.execute("SELECT COUNT(*) FROM onderhoud")
count = cursor.fetchone()[0]
# Controleer of data correct is ingevoerd
print(f"Aantal records in de database: {count}")
@app.route("/extrapolate", methods=["GET", "POST"])
def show_result():
# Haal de huidige datum op voor de standaardwaarde
today = datetime.today().strftime('%Y-%m-%d')
x_str = request.form.get("selected_date")
try:
x = datetime.strptime(x_str, "%Y-%m-%d") if x_str else datetime.today()
except ValueError:
flash("Ongeldige datum ingevoerd.", "danger")
return redirect(url_for("upload_file"))
result = get_extrapolation(x)
return render_template("resultaat.html", result=result, selected_date=x_str, today=today)
def get_extrapolation(x):
if x is None:
return []
today = datetime.today()
with sqlite3.connect(DATABASE) as conn:
cursor = conn.cursor()
cursor.execute("""
SELECT Object_code, Object_omschrijving, Afdeling_object, PO_Code, Omschrijving_PO,
Vervaldatum, Frequentie, UOM, PO_schema_Niet_gebruikt, Cluster, Locatie,
Locatie_omschrijving, Klasse_object, Categorie
FROM onderhoud
""")
columns = [desc[0] for desc in cursor.description]
rows = cursor.fetchall()
raw_data = [dict(zip(columns, row)) for row in rows]
result = []
for row in raw_data:
vervaldatum = row.get("Vervaldatum")
uom = row.get("UOM")
frequentie = row.get("Frequentie", 0)
if vervaldatum:
extrapolated_dates = extrapolate_vervaldatum(
vervaldatum, uom, frequentie, x)
for i, date in enumerate(extrapolated_dates):
new_row = row.copy()
begindatum = pd.to_datetime(date)
if begindatum <= today:
new_row["Overtijd"] = "Ja"
else:
new_row["Overtijd"] = "Nee"
new_row["Begindatum"] = date
if i == 0:
new_row["Parent"] = "*"
else:
new_row["Parent"] = ""
result.append(new_row)
return result
def extrapolate_vervaldatum(vervaldatum, uom, frequentie, x):
vervaldatum = pd.to_datetime(str(vervaldatum), errors="coerce")
if pd.isna(vervaldatum):
return []
result = []
while vervaldatum <= x:
result.append(vervaldatum.strftime("%Y-%m-%d"))
if uom == "D":
vervaldatum += pd.DateOffset(days=frequentie)
# vervaldatum += pd.DateOffset(weeks=frequentie // 7)
# vervaldatum += pd.DateOffset(months=frequentie // 30)
elif uom == "W":
vervaldatum += pd.DateOffset(weeks=frequentie)
elif uom == "M":
vervaldatum += pd.DateOffset(months=frequentie)
elif uom == "Y":
vervaldatum += pd.DateOffset(years=frequentie)
else:
break
if vervaldatum > x:
break
return result
if __name__ == "__main__":
os.makedirs(UPLOAD_FOLDER, exist_ok=True)
init_db()
app.run(debug=True)