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
env_path = "./.env"
load_dotenv(env_path)
@ -41,13 +40,12 @@ def upload_file():
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>",
"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")
@ -55,28 +53,37 @@ def upload_file():
@app.route("/extrapolate", methods=["GET", "POST"])
def show_result():
x = request.form.get("x", 1, type=int)
result = getextrapolation(x)
x_str = request.form.get("selected_date")
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
return render_template("resultaat.html", result=result, x=x)
result = getextrapolation(x)
return render_template("resultaat.html", result=result, selected_date=x_str)
@app.route("/download", methods=["GET"])
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)
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")
df.to_excel(writer, index=False,
sheet_name=f"Extrapolatie_{x.strftime('%Y-%m-%d')}")
output.seek(0)
filename = f"extrapolatie_{x}jaar.xlsx"
filename = f"extrapolatie_{x.strftime('%Y-%m-%d')}.xlsx"
return Response(
output,
mimetype="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
@ -84,200 +91,72 @@ 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(vervaldatum, uom, frequentie, x):
if vervaldatum is None or pd.isna(vervaldatum):
print("Ongeldige vervaldatum:", vervaldatum)
return [] # Geef een lege lijst terug in plaats van een fout te veroorzaken
vervaldatum = pd.to_datetime(str(vervaldatum), errors="coerce")
def extrapolate_vervaldatum_assheet(vervaldatum, uom, frequentie, extrapolate_years):
today = pd.Timestamp.today().normalize()
vervaldatum = pd.to_datetime(vervaldatum, errors="coerce")
if pd.isna(vervaldatum): # Extra controle als de conversie mislukt
print("Kon datum niet omzetten:", vervaldatum)
return []
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:
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"))
print("Onbekende eenheid:", uom)
break # Voorkom oneindige lus bij een onbekende eenheid
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()
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
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:
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)
vervaldatum, uom, frequentie, x)
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(
"""
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__":
os.makedirs(UPLOAD_FOLDER, exist_ok=True)
app.run(debug=True)

@ -4,15 +4,10 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Resultaat</title>
<!-- 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">
<link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<style>
/* Verklein de fontgrootte en de padding van de tabel */
.table-sm th, .table-sm td {
padding: 0.3rem;
font-size: 0.85rem;
@ -22,30 +17,21 @@
<body>
<div class="container mt-5">
<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>
<!-- Formulier voor het instellen van x -->
<form method="POST" class="mt-3">
<div class="form-group">
<label for="x">Aantal jaren vooruitkijken (x):</label>
<input type="number" id="x" name="x" value="{{ x }}" min="1" class="form-control w-auto d-inline">
<button type="submit" class="btn btn-primary">Update</button>
<label for="datepicker">Selecteer een extrapoleer einddatum:</label>
<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">Extrapoleer!</button>
</div>
</form>
<a href="{{ url_for('download_excel', x=x) }}" class="btn btn-success">
Download als Excel ({{ x }} jaar)
</a>
<a href="{{ url_for('download_excel', x=selected_date) }}" class="btn btn-success">Download als Excel ({{ selected_date }})</a>
<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">
<thead class="thead-dark">
<tr>
<th>Object_code</th>
<th>Object_omschrijving__</th>
<th>Object_omschrijving</th>
<th>Afdeling_object</th>
<th>PO_Code</th>
<th>Omschrijving_PO</th>
@ -84,32 +70,32 @@
</tbody>
</table>
</div>
<!-- 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 src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script>
$(document).ready(function () {
// Initialiseer de DataTable, maar zonder standaard sortering
$("#datepicker").datepicker({
dateFormat: "yy-mm-dd",
changeMonth: true,
changeYear: true
});
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": [15, 30, 60, 100], // Aantal rijen per pagina
"order": [], // Geen standaard sortering bij het laden
"paging": true,
"searching": true,
"ordering": true,
"info": true,
"lengthMenu": [15, 30, 60, 100],
"order": [],
"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": "filter:",
"search": "Filter:",
"paginate": {
"first": "Eerste",
"last": "Laatste",
@ -118,47 +104,32 @@
}
}
});
// 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
const hue = hash % 360;
const saturation = Math.floor(Math.random() * 10) + 60;
const lightness = Math.floor(Math.random() * 20) + 40;
return `hsl(${hue}, ${saturation}%, ${lightness}%)`;
}
// Highlight rijen met dezelfde Object_code en dynamisch gegenereerde kleur
var objectCodeColors = {}; // Opslag voor de gegenereerde kleuren per Object_code
var objectCodeColors = {};
function applyColors() {
$('.object-row').each(function () {
var objectCode = $(this).data('object-code');
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("border", "2px solid " + 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
table.search('').columns().search('').draw();
table.order([0, 'asc']).draw();
table.page(0).draw('page');
});
});
</script>

Loading…
Cancel
Save