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

273 lines
8.2 KiB

import os
import io
import debugpy
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
from database import get_db_connection
env_path = "./.env"
load_dotenv(env_path)
UPLOAD_FOLDER = os.getenv("UPLOAD_FOLDER")
ALLOWED_EXTENSIONS = {"xlsx"}
app = Flask(__name__)
app.config["UPLOAD_FOLDER"] = UPLOAD_FOLDER
app.secret_key = "9f2a1d3e4c5b6a7d8e9f0a1b2c3d4e5f"
def allowed_file(filename):
return "." in filename and filename.rsplit(".", 1)[1].lower() in ALLOWED_EXTENSIONS
@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)
flash(
"Bestand geüpload en verwerkt! <a href='"
+ url_for("show_result")
+ "'>Bekijk de resultaten</a>",
"success",
)
process_excel(filepath)
return redirect(url_for("upload_file"))
return render_template("index.html")
@app.route("/extrapolate", methods=["GET", "POST"])
def show_result():
x = request.form.get("x", 1, type=int)
result = getextrapolation(x)
# Geef de resultaten door aan het HTML-template
return render_template("resultaat.html", result=result, x=x)
@app.route("/download", methods=["GET"])
def download_excel():
x = request.args.get("x", 1, type=int)
result = getextrapolation(x)
df = pd.DataFrame(result)
output = io.BytesIO()
with pd.ExcelWriter(output, engine="openpyxl") as writer:
df.to_excel(writer, index=False, sheet_name=f"Extrapolatie_{x}jaar")
output.seek(0)
filename = f"extrapolatie_{x}jaar.xlsx"
return Response(
output,
mimetype="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
headers={"Content-Disposition": f"attachment; filename={filename}"},
)
def extrapolate_vervaldatum(vervaldatum, uom, frequentie, extrapolate_years):
today = pd.Timestamp.today().normalize()
vervaldatum = pd.to_datetime(vervaldatum, errors="coerce")
result = []
for i in range(extrapolate_years + 1):
if uom == "D": # Dagelijks
months_to_add = round(frequentie * i / 30.44)
new_date = vervaldatum + pd.DateOffset(months=months_to_add)
# new_date = vervaldatum + pd.DateOffset(days=frequentie * i)
elif uom == "M": # Maandelijks
new_date = vervaldatum + pd.DateOffset(months=int(frequentie * i))
elif uom == "Y": # Jaarlijks
new_date = vervaldatum + pd.DateOffset(years=int(frequentie * i))
else:
continue # Onbekende UOM, overslaan
if new_date <= today + pd.DateOffset(years=extrapolate_years):
result.append(new_date.strftime("%Y-%m-%d"))
return result
def extrapolate_vervaldatum_assheet(vervaldatum, uom, frequentie, extrapolate_years):
today = pd.Timestamp.today().normalize()
vervaldatum = pd.to_datetime(vervaldatum, errors="coerce")
result = []
for i in range(extrapolate_years + 1):
if uom == "D": # Dagelijks
years_to_add = (frequentie * i) / 365 # Omrekenen naar jaren
# Afronden naar het dichtstbijzijnde jaar
rounded_years = round(years_to_add)
new_date = vervaldatum + pd.DateOffset(years=rounded_years)
elif uom == "M": # Maandelijks
years_to_add = (frequentie * i) / 12 # Omrekenen naar jaren
# Afronden naar het dichtstbijzijnde jaar
rounded_years = round(years_to_add)
new_date = vervaldatum + pd.DateOffset(years=rounded_years)
elif uom == "Y": # Jaarlijks
# Afronden naar het dichtstbijzijnde jaar
rounded_years = round(frequentie * i)
new_date = vervaldatum + pd.DateOffset(years=rounded_years)
else:
continue # Onbekende UOM, overslaan
# Controle of de nieuwe datum binnen het bereik valt
if new_date <= today + pd.DateOffset(years=extrapolate_years):
result.append(new_date.strftime("%Y-%m-%d"))
return result
def getextrapolation(extrapolateYears):
conn, cursor = get_db_connection()
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()
cursor.close()
conn.close()
raw_data = [dict(zip(columns, row)) for row in rows]
today = pd.Timestamp.today().normalize()
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, extrapolateYears)
for date in extrapolated_dates:
new_row = row.copy()
new_row["Vervaldatum"] = date
new_row["Overtijd"] = ""
if pd.to_datetime(date) < today:
new_row["Overtijd"] = "ja"
else:
new_row["Overtijd"] = "Nee"
result.append(new_row)
return result
def process_excel(filepath):
df = pd.read_excel(filepath, engine="openpyxl")
df.columns = df.columns.str.strip()
conn, cursor = get_db_connection()
cursor.execute(
"""
CREATE TABLE IF NOT EXISTS onderhoud (
id INT AUTO_INCREMENT PRIMARY KEY,
Object_code VARCHAR(50),
Object_omschrijving TEXT,
Afdeling_object VARCHAR(100),
PO_Code VARCHAR(50),
Omschrijving_PO TEXT,
Vervaldatum DATE,
Frequentie INT,
UOM TEXT,
PO_schema_Niet_gebruikt TEXT,
Cluster TEXT,
Locatie TEXT,
Locatie_omschrijving TEXT,
Klasse_object TEXT,
Categorie TEXT
)
"""
)
for _, row in df.iterrows():
for column in row.index:
if pd.isna(row[column]):
row[column] = ""
cursor.execute(
"""
INSERT INTO onderhoud
(Object_code, Object_omschrijving, Afdeling_object, PO_Code, Omschrijving_PO, Vervaldatum, Frequentie,
UOM, PO_schema_Niet_gebruikt, Cluster, Locatie, Locatie_omschrijving, Klasse_object, Categorie)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
""",
(
row["Object code"],
row["Object omschrijving"],
row["Afdeling object"],
row["PO Code"],
row["Omschrijving PO"],
row["Vervaldatum"],
row["Frequentie"],
row["UOM"],
row["PO-schema Niet gebruikt"],
row["Cluster"],
row["Locatie"],
row["Locatie omschrijving"],
row["Klasse object"],
row["Categorie"],
),
)
conn.commit()
cursor.close()
conn.close()
if __name__ == "__main__":
if os.getenv("FLASK_DEBUG") == "1":
print("⏳ Wachten op debugger...")
debugpy.listen(("0.0.0.0", 5678)) # Luistert op poort 5678
debugpy.wait_for_client() # Wacht op een debugger
os.makedirs(UPLOAD_FOLDER, exist_ok=True)
app.run(debug=True)