ppo insighty nieuwe algoritme en html

celery-integration
peter.fong 9 months ago
parent 05c3eedfcd
commit a5d4a7799b

@ -29,9 +29,7 @@
},
"postCreateCommand": "find /workspace -type f -name 'requirements.txt' -exec pip install --no-cache-dir -r {} \\;",
"remoteUser": "root",
"mounts": [
"source=${localWorkspaceFolder},target=/workspace,type=bind"
],
"mounts": ["source=${localWorkspaceFolder},target=/workspace,type=bind"],
"runArgs": ["--entrypoint", "bash"],
"settings": {
"python.pythonPath": "/usr/local/bin/python"

@ -0,0 +1,30 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Attach to Chrome",
"port": 9222,
"request": "attach",
"type": "chrome",
"webRoot": "${workspaceFolder}"
},
{
"name": "Python Debugger: Remote Attach",
"type": "debugpy",
"request": "attach",
"connect": {
"host": "0.0.0.0:5678",
"port": 5678
},
"pathMappings": [
{
"localRoot": "${workspaceFolder}",
"remoteRoot": "."
}
]
}
]
}

@ -1,12 +1,15 @@
import os
import io
import debugpy
from datetime import datetime
import pandas as pd
from flask import Flask, request, render_template, redirect, url_for, flash
from werkzeug.utils import secure_filename
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
from flask import Response
import io
from datetime import datetime
env_path = "./.env"
load_dotenv(env_path)
@ -82,6 +85,62 @@ def download_excel():
)
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()
@ -119,23 +178,24 @@ def getextrapolation(extrapolateYears):
result = []
for row in raw_data:
vervaldatum = row.get("Vervaldatum")
vervaldatum = pd.to_datetime(vervaldatum, errors="coerce")
vervaldatum = row.get("Vervaldatum")
uom = row.get("UOM")
frequentie = row.get("Frequentie", 0)
if pd.notna(vervaldatum) and vervaldatum < today:
vervaldatum = today # Zet op vandaag
if vervaldatum:
extrapolated_dates = extrapolate_vervaldatum(
vervaldatum, uom, frequentie, extrapolateYears)
for i in range(extrapolateYears + 1):
for date in extrapolated_dates:
new_row = row.copy()
new_row["Vervaldatum"] = date
if pd.notna(vervaldatum):
new_row["Vervaldatum"] = (
vervaldatum + pd.DateOffset(years=i)
).strftime("%Y-%m-%d")
new_row["Overtijd"] = ""
if pd.to_datetime(date) < today:
new_row["Overtijd"] = "ja"
else:
new_row["Vervaldatum"] = None
new_row["Overtijd"] = "Nee"
result.append(new_row)
return result
@ -204,5 +264,9 @@ def process_excel(filepath):
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)

@ -5,14 +5,17 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Resultaat</title>
<!-- Bootstrap CSS toevoegen -->
<!-- Bootstrap CSS -->
<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">
<style>
/* Verklein de fontgrootte en de padding van de tabel */
.table-sm th, .table-sm td {
padding: 0.3rem;
font-size: 0.85rem; /* Verklein de tekst */
font-size: 0.85rem;
}
</style>
</head>
@ -35,9 +38,10 @@
<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>
<!-- Resultaat Tabel -->
<table class="table table-sm table-bordered table-striped mt-3">
<!-- Resultaat Tabel met ID voor DataTables -->
<table id="resultTable" class="table table-sm table-bordered table-striped mt-3">
<thead class="thead-dark">
<tr>
<th>Object_code</th>
@ -54,11 +58,12 @@
<th>Locatie_omschrijving</th>
<th>Klasse_object</th>
<th>Categorie</th>
<th>Overtijd</th>
</tr>
</thead>
<tbody>
{% for row in result %}
<tr>
<tr class="object-row" data-object-code="{{ row['Object_code'] }}">
<td>{{ row['Object_code'] }}</td>
<td>{{ row['Object_omschrijving'] }}</td>
<td>{{ row['Afdeling_object'] }}</td>
@ -73,16 +78,88 @@
<td>{{ row['Locatie_omschrijving'] }}</td>
<td>{{ row['Klasse_object'] }}</td>
<td>{{ row['Categorie'] }}</td>
<td>{{ row['Overtijd'] }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<!-- Bootstrap JS toevoegen -->
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<!-- Bootstrap JS -->
<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://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>
$(document).ready(function () {
// Initialiseer de DataTable, maar zonder standaard sortering
var table = $('#resultTable').DataTable({
"paging": true, // Activeer paginering
"searching": true, // Activeer zoekfunctionaliteit
"ordering": true, // Activeer sorteren
"info": true, // Toon informatie over het aantal rijen
"lengthMenu": [10, 25, 50, 100], // Aantal rijen per pagina
"order": [], // Geen standaard sortering bij het laden
"language": {
"lengthMenu": "Toon _MENU_ resultaten per pagina",
"zeroRecords": "Geen resultaten gevonden",
"info": "Pagina _PAGE_ van _PAGES_",
"infoEmpty": "Geen records beschikbaar",
"infoFiltered": "(gefilterd uit _MAX_ total records)",
"search": "Zoeken:",
"paginate": {
"first": "Eerste",
"last": "Laatste",
"next": "Volgende",
"previous": "Vorige"
}
}
});
// Functie om een unieke kleur te genereren voor elke Object_code
function generateColor(objectCode) {
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
// Willekeurige verzadiging en lichtheid voor meer variatie
const saturation = Math.floor(Math.random() * 10) + 60; // Verhouding van 60% tot 100%
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
}
// Highlight rijen met dezelfde Object_code en dynamisch gegenereerde kleur
var objectCodeColors = {}; // Opslag voor de gegenereerde kleuren per Object_code
function applyColors() {
$('.object-row').each(function () {
var objectCode = $(this).data('object-code');
if (!objectCodeColors[objectCode]) {
objectCodeColors[objectCode] = generateColor(objectCode); // Genereer een nieuwe kleur
}
// Toepassen van de dynamische kleur
$(this).css('background-color', objectCodeColors[objectCode]);
});
}
// Kleurtoewijzing toepassen bij het eerste laden van de DataTable
applyColors();
// Herbereken de kleuren telkens na een zoek- of filteractie
table.on('draw', function () {
applyColors();
});
// Resetknop functionaliteit
$('#resetTable').on('click', function () {
table.search('').columns().search('').draw(); // Verwijdert alle filters
table.order([0, 'asc']).draw(); // Reset sortering (eerste kolom, oplopend)
table.page(0).draw('page'); // Ga terug naar de eerste pagina
});
});
</script>
</body>
</html>

@ -2,3 +2,4 @@ paho-mqtt
mysql-connector-python
python-dotenv
requests
debugpy
Loading…
Cancel
Save