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.
273 lines
8.2 KiB
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)
|