refinement RS1.1

celery-integration
peter.fong 9 months ago
parent 48266fed67
commit 919263c962

@ -9,7 +9,6 @@ from werkzeug.utils import secure_filename
from database import get_db_connection from database import get_db_connection
env_path = "./.env" env_path = "./.env"
load_dotenv(env_path) load_dotenv(env_path)
@ -41,13 +40,12 @@ def upload_file():
filename = secure_filename(file.filename) filename = secure_filename(file.filename)
filepath = os.path.join(app.config["UPLOAD_FOLDER"], filename) filepath = os.path.join(app.config["UPLOAD_FOLDER"], filename)
file.save(filepath) file.save(filepath)
process_excel(filepath)
flash( flash(
"Bestand geüpload en verwerkt! <a href='" "Bestand geüpload en verwerkt! <a href='" +
+ url_for("show_result") url_for("show_result") + "'>Bekijk de resultaten</a>",
+ "'>Bekijk de resultaten</a>",
"success", "success",
) )
process_excel(filepath)
return redirect(url_for("upload_file")) return redirect(url_for("upload_file"))
return render_template("index.html") return render_template("index.html")
@ -55,28 +53,37 @@ def upload_file():
@app.route("/extrapolate", methods=["GET", "POST"]) @app.route("/extrapolate", methods=["GET", "POST"])
def show_result(): def show_result():
x = request.form.get("x", 1, type=int) x_str = request.form.get("selected_date")
result = getextrapolation(x) print(x_str)
try:
if x_str is not None:
x = datetime.strptime(x_str, "%Y-%m-%d")
else:
# Handle the case where x_str is None, for example:
x = None # or raise an exception or use a default date
flash("Ongeldige datum ingevoerd.", "danger")
except ValueError:
flash("Ongeldige datum ingevoerd.", "danger")
return redirect(url_for("upload_file"))
# Geef de resultaten door aan het HTML-template result = getextrapolation(x)
return render_template("resultaat.html", result=result, x=x) return render_template("resultaat.html", result=result, selected_date=x_str)
@app.route("/download", methods=["GET"]) @app.route("/download", methods=["GET"])
def download_excel(): def download_excel():
x = request.args.get("x", 1, type=int) x_str = request.args.get("x")
x = datetime.strptime(x_str, "%Y-%m-%d")
result = getextrapolation(x) result = getextrapolation(x)
df = pd.DataFrame(result) df = pd.DataFrame(result)
output = io.BytesIO() output = io.BytesIO()
with pd.ExcelWriter(output, engine="openpyxl") as writer: with pd.ExcelWriter(output, engine="openpyxl") as writer:
df.to_excel(writer, index=False, sheet_name=f"Extrapolatie_{x}jaar") df.to_excel(writer, index=False,
sheet_name=f"Extrapolatie_{x.strftime('%Y-%m-%d')}")
output.seek(0) output.seek(0)
filename = f"extrapolatie_{x}jaar.xlsx" filename = f"extrapolatie_{x.strftime('%Y-%m-%d')}.xlsx"
return Response( return Response(
output, output,
mimetype="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", mimetype="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
@ -84,200 +91,72 @@ def download_excel():
) )
def extrapolate_vervaldatum(vervaldatum, uom, frequentie, extrapolate_years): def extrapolate_vervaldatum(vervaldatum, uom, frequentie, x):
today = pd.Timestamp.today().normalize() if vervaldatum is None or pd.isna(vervaldatum):
vervaldatum = pd.to_datetime(vervaldatum, errors="coerce") print("Ongeldige vervaldatum:", vervaldatum)
return [] # Geef een lege lijst terug in plaats van een fout te veroorzaken
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
vervaldatum = pd.to_datetime(str(vervaldatum), errors="coerce")
def extrapolate_vervaldatum_assheet(vervaldatum, uom, frequentie, extrapolate_years): if pd.isna(vervaldatum): # Extra controle als de conversie mislukt
today = pd.Timestamp.today().normalize() print("Kon datum niet omzetten:", vervaldatum)
vervaldatum = pd.to_datetime(vervaldatum, errors="coerce") return []
result = [] 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)
while vervaldatum <= x:
result.append(vervaldatum.strftime("%Y-%m-%d"))
if uom == "D":
vervaldatum += pd.DateOffset(days=frequentie)
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: else:
continue # Onbekende UOM, overslaan print("Onbekende eenheid:", uom)
break # Voorkom oneindige lus bij een onbekende eenheid
# 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 return result
def getextrapolation(extrapolateYears): def getextrapolation(x):
if x is None:
print("Geen geldige datum opgegeven voor extrapolatie.")
return []
conn, cursor = get_db_connection() conn, cursor = get_db_connection()
cursor.execute("""
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
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 FROM onderhoud
""" """)
)
columns = [desc[0] for desc in cursor.description] columns = [desc[0] for desc in cursor.description]
rows = cursor.fetchall() rows = cursor.fetchall()
cursor.close() cursor.close()
conn.close() conn.close()
raw_data = [dict(zip(columns, row)) for row in rows] raw_data = [dict(zip(columns, row)) for row in rows]
today = pd.Timestamp.today().normalize()
result = [] result = []
for row in raw_data:
for row in raw_data:
vervaldatum = row.get("Vervaldatum") vervaldatum = row.get("Vervaldatum")
uom = row.get("UOM") uom = row.get("UOM")
frequentie = row.get("Frequentie", 0) frequentie = row.get("Frequentie", 0)
if vervaldatum: if vervaldatum:
extrapolated_dates = extrapolate_vervaldatum( extrapolated_dates = extrapolate_vervaldatum(
vervaldatum, uom, frequentie, extrapolateYears) vervaldatum, uom, frequentie, x)
for date in extrapolated_dates: for date in extrapolated_dates:
new_row = row.copy() new_row = row.copy()
new_row["Vervaldatum"] = date 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) result.append(new_row)
return result 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(
"""
truncate table onderhoud
"""
)
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
)
"""
)
cursor.execute(
"SELECT Object_code, Omschrijving_PO, Vervaldatum FROM onderhoud")
existing_records = set(cursor.fetchall())
for _, row in df.iterrows():
for column in row.index:
if pd.isna(row[column]):
row[column] = ""
record = (row["Object code"],
row["Omschrijving PO"], row["Vervaldatum"])
if record not in existing_records:
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"],
),
)
existing_records.add(record)
conn.commit()
cursor.close()
conn.close()
if __name__ == "__main__": if __name__ == "__main__":
os.makedirs(UPLOAD_FOLDER, exist_ok=True) os.makedirs(UPLOAD_FOLDER, exist_ok=True)
app.run(debug=True) app.run(debug=True)

@ -4,15 +4,10 @@
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Resultaat</title> <title>Resultaat</title>
<!-- Bootstrap CSS -->
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet" /> <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet" />
<!-- DataTables CSS -->
<link rel="stylesheet" href="https://cdn.datatables.net/1.13.6/css/jquery.dataTables.min.css"> <link rel="stylesheet" href="https://cdn.datatables.net/1.13.6/css/jquery.dataTables.min.css">
<link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<style> <style>
/* Verklein de fontgrootte en de padding van de tabel */
.table-sm th, .table-sm td { .table-sm th, .table-sm td {
padding: 0.3rem; padding: 0.3rem;
font-size: 0.85rem; font-size: 0.85rem;
@ -22,30 +17,21 @@
<body> <body>
<div class="container mt-5"> <div class="container mt-5">
<h1>Resultaten van de query</h1> <h1>Resultaten van de query</h1>
<!-- Link terug naar uploadpagina -->
<a href="{{ url_for('upload_file') }}" class="btn btn-secondary mt-3">Terug naar upload</a> <a href="{{ url_for('upload_file') }}" class="btn btn-secondary mt-3">Terug naar upload</a>
<!-- Formulier voor het instellen van x -->
<form method="POST" class="mt-3"> <form method="POST" class="mt-3">
<div class="form-group"> <div class="form-group">
<label for="x">Aantal jaren vooruitkijken (x):</label> <label for="datepicker">Selecteer een extrapoleer einddatum:</label>
<input type="number" id="x" name="x" value="{{ x }}" min="1" class="form-control w-auto d-inline"> <input type="text" id="datepicker" name="selected_date" value="{{ selected_date }}" class="form-control w-auto d-inline">
<button type="submit" class="btn btn-primary">Update</button> <button type="submit" class="btn btn-primary">Extrapoleer!</button>
</div> </div>
</form> </form>
<a href="{{ url_for('download_excel', x=selected_date) }}" class="btn btn-success">Download als Excel ({{ selected_date }})</a>
<a href="{{ url_for('download_excel', x=x) }}" class="btn btn-success">
Download als Excel ({{ x }} jaar)
</a>
<button id="resetTable" class="btn btn-warning mt-2">Reset tabel</button> <button id="resetTable" class="btn btn-warning mt-2">Reset tabel</button>
<!-- Resultaat Tabel met ID voor DataTables -->
<table id="resultTable" class="table table-sm table-bordered table-striped mt-3"> <table id="resultTable" class="table table-sm table-bordered table-striped mt-3">
<thead class="thead-dark"> <thead class="thead-dark">
<tr> <tr>
<th>Object_code</th> <th>Object_code</th>
<th>Object_omschrijving__</th> <th>Object_omschrijving</th>
<th>Afdeling_object</th> <th>Afdeling_object</th>
<th>PO_Code</th> <th>PO_Code</th>
<th>Omschrijving_PO</th> <th>Omschrijving_PO</th>
@ -84,32 +70,32 @@
</tbody> </tbody>
</table> </table>
</div> </div>
<!-- Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.5.4/dist/umd/popper.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.5.4/dist/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
<!-- DataTables JS -->
<script src="https://cdn.datatables.net/1.13.6/js/jquery.dataTables.min.js"></script> <script src="https://cdn.datatables.net/1.13.6/js/jquery.dataTables.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script> <script>
$(document).ready(function () { $(document).ready(function () {
// Initialiseer de DataTable, maar zonder standaard sortering $("#datepicker").datepicker({
dateFormat: "yy-mm-dd",
changeMonth: true,
changeYear: true
});
var table = $('#resultTable').DataTable({ var table = $('#resultTable').DataTable({
"paging": true, // Activeer paginering "paging": true,
"searching": true, // Activeer zoekfunctionaliteit "searching": true,
"ordering": true, // Activeer sorteren "ordering": true,
"info": true, // Toon informatie over het aantal rijen "info": true,
"lengthMenu": [15, 30, 60, 100], // Aantal rijen per pagina "lengthMenu": [15, 30, 60, 100],
"order": [], // Geen standaard sortering bij het laden "order": [],
"language": { "language": {
"lengthMenu": "Toon _MENU_ resultaten per pagina", "lengthMenu": "Toon _MENU_ resultaten per pagina",
"zeroRecords": "Geen resultaten gevonden", "zeroRecords": "Geen resultaten gevonden",
"info": "Pagina _PAGE_ van _PAGES_", "info": "Pagina _PAGE_ van _PAGES_",
"infoEmpty": "Geen records beschikbaar", "infoEmpty": "Geen records beschikbaar",
"infoFiltered": "(gefilterd uit _MAX_ total records)", "infoFiltered": "(gefilterd uit _MAX_ total records)",
"search": "filter:", "search": "Filter:",
"paginate": { "paginate": {
"first": "Eerste", "first": "Eerste",
"last": "Laatste", "last": "Laatste",
@ -118,47 +104,32 @@
} }
} }
}); });
// Functie om een unieke kleur te genereren voor elke Object_code
function generateColor(objectCode) { function generateColor(objectCode) {
const hash = Array.from(objectCode).reduce((acc, char) => acc + char.charCodeAt(0), 0); const hash = Array.from(objectCode).reduce((acc, char) => acc + char.charCodeAt(0), 0);
const hue = hash % 360; // Kleurtoewijzing op basis van de sum van char codes const hue = hash % 360;
const saturation = Math.floor(Math.random() * 10) + 60;
// Willekeurige verzadiging en lichtheid voor meer variatie const lightness = Math.floor(Math.random() * 20) + 40;
const saturation = Math.floor(Math.random() * 10) + 60; // Verhouding van 60% tot 100% return `hsl(${hue}, ${saturation}%, ${lightness}%)`;
const lightness = Math.floor(Math.random() * 20) + 40; // Verhouding van 40% tot 60%
return `hsl(${hue}, ${saturation}%, ${lightness}%)`; // HSL-kleur met variabele verzadiging en lichtheid
} }
var objectCodeColors = {};
// Highlight rijen met dezelfde Object_code en dynamisch gegenereerde kleur
var objectCodeColors = {}; // Opslag voor de gegenereerde kleuren per Object_code
function applyColors() { function applyColors() {
$('.object-row').each(function () { $('.object-row').each(function () {
var objectCode = $(this).data('object-code'); var objectCode = $(this).data('object-code');
if (!objectCodeColors[objectCode]) { if (!objectCodeColors[objectCode]) {
objectCodeColors[objectCode] = generateColor(objectCode); // Genereer een nieuwe kleur objectCodeColors[objectCode] = generateColor(objectCode);
} }
// Toepassen van de dynamische kleur
$(this).css('background-color', objectCodeColors[objectCode]); $(this).css('background-color', objectCodeColors[objectCode]);
$(this).css("border", "2px solid " + objectCodeColors[objectCode]); $(this).css("border", "2px solid " + objectCodeColors[objectCode]);
}); });
} }
// Kleurtoewijzing toepassen bij het eerste laden van de DataTable
applyColors(); applyColors();
// Herbereken de kleuren telkens na een zoek- of filteractie
table.on('draw', function () { table.on('draw', function () {
applyColors(); applyColors();
}); });
// Resetknop functionaliteit
$('#resetTable').on('click', function () { $('#resetTable').on('click', function () {
table.search('').columns().search('').draw(); // Verwijdert alle filters table.search('').columns().search('').draw();
table.order([0, 'asc']).draw(); // Reset sortering (eerste kolom, oplopend) table.order([0, 'asc']).draw();
table.page(0).draw('page'); // Ga terug naar de eerste pagina table.page(0).draw('page');
}); });
}); });
</script> </script>

Loading…
Cancel
Save