Auftragsübersicht anpassen
Build und Push Docker Image / build-and-push (push) Successful in 11s

This commit is contained in:
2026-08-27 11:52:24 +02:00
parent d6c066e18f
commit 455f513f6e
5 changed files with 74 additions and 24 deletions
+14 -10
View File
@@ -151,16 +151,20 @@ location /app/wdm-performance/ {
(.xlsx) oder CSV-Datei per Drag & Drop oder Dateiauswahl bulk-anlegen,
siehe eigener Abschnitt unten
- **Auftragsübersicht**: alle Aufträge (inkl. Artikel, Maschinenname),
standardmäßig nur offen/pausiert (umschaltbar auf "Alle"), optional nach
Maschine gefiltert, löschbar und (mit Einschränkungen) bearbeitbar:
- **Status und Priorität sind hier nicht editierbar** (nur informativ
angezeigt) Status ändert sich ausschließlich über die eigentlichen
Maschinen-Aktionen (Start/Pause/Beenden), Priorität ausschließlich über
die Drag & Drop-Seite "Auftragspriorität".
- **Aktive Aufträge werden angezeigt, können aber nicht bearbeitet
werden** ein Bearbeitungsversuch (auch ein direkter POST) wird mit
einer Fehlermeldung abgelehnt, solange der Auftrag gerade an der
Maschine läuft.
standardmäßig offen/pausiert **und aktiv** (umschaltbar auf "Alle", zeigt
dann zusätzlich auch abgeschlossene Aufträge), optional nach Maschine
gefiltert, löschbar und (mit Einschränkungen) bearbeitbar:
- **Status ist hier manuell änderbar** (z.B. um einen versehentlich
abgeschlossenen Auftrag wieder auf "Offen" zu setzen) **"Aktiv" ist als
Zielwert bewusst ausgeschlossen**, das passiert ausschließlich über die
eigentlichen Maschinen-Aktionen (Start/Pause/Beenden). **Priorität bleibt
weiterhin nicht editierbar**, dafür gibt es die Drag & Drop-Seite
"Auftragspriorität".
- **Aktive Aufträge werden angezeigt, können aber weder bearbeitet noch
gelöscht werden** Bearbeiten- und Löschen-Button werden für sie in der
Liste durch einen Hinweistext ersetzt; ein direkter POST-Versuch (am UI
vorbei) wird serverseitig ebenfalls abgelehnt, solange der Auftrag gerade
an der Maschine läuft.
- Editierbar bleiben Maschine (inkl. automatischem Umhängen der kompletten
MDE-Buchungshistorie auf die neue Maschine), Auftragsnummer, Artikel,
Produktionsmenge und Stück/Stunde.
+1 -1
View File
@@ -1 +1 @@
1.0.0
1.0.1
+41 -10
View File
@@ -58,6 +58,11 @@ STATUS_LABEL = {
"abgeschlossen": "Abgeschlossen",
}
STATUS_OPTIONEN = [("offen", "Offen"), ("aktiv", "Aktiv"), ("pause", "Pausiert"), ("abgeschlossen", "Abgeschlossen")]
# In der Auftragsübersicht darf der Status manuell gesetzt werden (z.B. um einen
# Auftrag versehentlich abgeschlossenen wieder zu öffnen) - "aktiv" ist hier
# aber bewusst ausgeschlossen, das passiert ausschließlich über die
# Start-Aktion an der Maschine selbst.
STATUS_OPTIONEN_BEARBEITBAR = [(wert, label) for wert, label in STATUS_OPTIONEN if wert != "aktiv"]
# Anzahl Zeilen, auf die MDE-/Auftragslisten ausgelegt sind (kein hartes Limit,
# aber Referenzgröße für Layout/Performance-Überlegungen).
@@ -705,7 +710,11 @@ def leitstand_uebersicht():
bedingungen.append('maschine_id = %s')
params.append(filter_maschine_id)
if filter_status == "offen_pause":
bedingungen.append("status IN ('offen', 'pause')")
# "aktiv" wird hier bewusst mit angezeigt (nur informativ, nicht
# bearbeitbar/löschbar - siehe leitstand_uebersicht_bearbeiten
# bzw. leitstand_uebersicht_loeschen), damit laufende Aufträge in
# der Übersicht nicht verschwinden.
bedingungen.append("status IN ('offen', 'pause', 'aktiv')")
where_sql = (" WHERE " + " AND ".join(bedingungen)) if bedingungen else ""
cur.execute(
@@ -735,12 +744,14 @@ def leitstand_uebersicht():
@app.route("/start_uebersicht/<int:auftrag_id>/bearbeiten", methods=["GET", "POST"])
def leitstand_uebersicht_bearbeiten(auftrag_id):
"""Auftrag bearbeiten. Status und Priorität (sid) sind hier bewusst NICHT
editierbar - Status ändert sich nur über die eigentlichen Maschinen-
Aktionen (Start/Pause/Beenden), Priorität nur über die Drag&Drop-Seite
"Auftragspriorität". Aktive Aufträge werden nur angezeigt, eine
Bearbeitung wird komplett verweigert (Fehlermeldung), da sie gerade an
der Maschine läuft."""
"""Auftrag bearbeiten. Der Status ist hier manuell änderbar (z.B. um einen
versehentlich abgeschlossenen Auftrag wieder auf "offen" zu setzen) -
"aktiv" ist als Zielwert bewusst ausgeschlossen, das passiert
ausschließlich über die eigentlichen Maschinen-Aktionen (Start/Pause/
Beenden). Priorität (sid) ist weiterhin NICHT editierbar, dafür gibt es
die Drag&Drop-Seite "Auftragspriorität". Aktive Aufträge werden nur
angezeigt, eine Bearbeitung wird komplett verweigert (Fehlermeldung), da
sie gerade an der Maschine läuft."""
filter_maschine_id = request.args.get("maschine_id") or request.form.get("maschine_id_filter") or ""
filter_status = request.args.get("status") or request.form.get("status_filter") or "offen_pause"
with db.get_cursor() as cur:
@@ -759,6 +770,7 @@ def leitstand_uebersicht_bearbeiten(auftrag_id):
"leitstand_uebersicht_bearbeiten.html", title="Auftrag bearbeiten",
auftrag=alt, maschinen=maschinen, gesperrt=True,
status_anzeige=STATUS_LABEL.get(alt["status"], alt["status"]),
status_optionen=STATUS_OPTIONEN_BEARBEITBAR,
filter_maschine_id=filter_maschine_id, filter_status=filter_status,
error="Dieser Auftrag ist aktuell aktiv und kann deshalb nicht bearbeitet werden. "
"Bitte an der Maschine erst pausieren oder beenden.",
@@ -770,6 +782,7 @@ def leitstand_uebersicht_bearbeiten(auftrag_id):
soll_h = request.form.get("soll_h")
artikel = (request.form.get("artikel") or "").strip() or None
neue_maschine_id = request.form.get("maschine_id")
neuer_status = request.form.get("status")
error = None
einheiten_f = soll_h_f = None
@@ -782,6 +795,10 @@ def leitstand_uebersicht_bearbeiten(auftrag_id):
if not error and not auftragsnummer:
error = "Auftragsnummer darf nicht leer sein."
gueltige_status = {wert for wert, _ in STATUS_OPTIONEN_BEARBEITBAR}
if not error and neuer_status not in gueltige_status:
error = "Ungültiger Status."
if not error:
if not neue_maschine_id:
error = "Maschine muss ausgewählt werden."
@@ -806,17 +823,27 @@ def leitstand_uebersicht_bearbeiten(auftrag_id):
auftrag["sid_fmt"] = fmt_num(alt["sid"])
auftrag["artikel"] = artikel
auftrag["maschine_id"] = neue_maschine_id or alt["maschine_id"]
auftrag["status"] = neuer_status if neuer_status in gueltige_status else alt["status"]
return render_template(
"leitstand_uebersicht_bearbeiten.html", title="Auftrag bearbeiten",
auftrag=auftrag, maschinen=maschinen,
status_anzeige=STATUS_LABEL.get(alt["status"], alt["status"]),
status_optionen=STATUS_OPTIONEN_BEARBEITBAR,
filter_maschine_id=filter_maschine_id, filter_status=filter_status, error=error,
)
# Wurde der Status auf "abgeschlossen" geändert (oder war er das
# schon und bleibt es), Endzeitpunkt entsprechend setzen bzw.
# beibehalten - beim (Wieder-)Öffnen wird er zurückgesetzt.
if neuer_status == "abgeschlossen":
ende_wert = alt["ende"] if alt["status"] == "abgeschlossen" else now_ts()
else:
ende_wert = None
cur.execute(
'UPDATE "Auftraege" SET auftragsnummer = %s, einheiten = %s, soll_h = %s, '
'artikel = %s, maschine_id = %s WHERE id = %s',
(auftragsnummer, einheiten_f, soll_h_f, artikel, neue_maschine_id, auftrag_id),
'artikel = %s, maschine_id = %s, status = %s, aktiv = false, ende = %s WHERE id = %s',
(auftragsnummer, einheiten_f, soll_h_f, artikel, neue_maschine_id, neuer_status, ende_wert, auftrag_id),
)
# Maschine und/oder Auftragsnummer geändert? Dann muss die MDE-Historie
# (dort per maschine_id + Auftragsnummer verknüpft) mitgezogen werden.
@@ -835,6 +862,7 @@ def leitstand_uebersicht_bearbeiten(auftrag_id):
"leitstand_uebersicht_bearbeiten.html", title="Auftrag bearbeiten",
auftrag=alt, maschinen=maschinen,
status_anzeige=STATUS_LABEL.get(alt["status"], alt["status"]),
status_optionen=STATUS_OPTIONEN_BEARBEITBAR,
filter_maschine_id=filter_maschine_id, filter_status=filter_status,
)
@@ -844,7 +872,10 @@ def leitstand_uebersicht_loeschen(auftrag_id):
filter_maschine_id = request.form.get("maschine_id") or ""
filter_status = request.form.get("status") or "offen_pause"
with db.get_cursor() as cur:
cur.execute('DELETE FROM "Auftraege" WHERE id = %s', (auftrag_id,))
# Aktive Aufträge (gerade an der Maschine laufend) dürfen hier nicht
# gelöscht werden können, unabhängig davon, was im UI angeboten wird
# (analog zur Bearbeiten-Sperre für aktive Aufträge).
cur.execute('DELETE FROM "Auftraege" WHERE id = %s AND status <> \'aktiv\'', (auftrag_id,))
return redirect(url_for("leitstand_uebersicht", maschine_id=filter_maschine_id, status=filter_status))
+5 -1
View File
@@ -14,7 +14,7 @@
</select>
<span>Status:</span>
<select name="status" onchange="this.form.submit()">
<option value="offen_pause" {% if filter_status == "offen_pause" %}selected{% endif %}>Offen/Pausiert</option>
<option value="offen_pause" {% if filter_status == "offen_pause" %}selected{% endif %}>Offen/Pausiert/Aktiv</option>
<option value="alle" {% if filter_status == "alle" %}selected{% endif %}>Alle</option>
</select>
<button type="submit">Filtern</button>
@@ -42,6 +42,9 @@
<td>{{ "Ja" if a.aktiv else "Nein" }}</td>
<td>{{ a.sid_fmt }}</td>
<td class="col-actions">
{% if a.status == "aktiv" %}
<span style="color:var(--text-dim); font-size:0.85em;">gesperrt (aktiv an Maschine)</span>
{% else %}
<div class="row-actions">
<a class="icon-btn" href="{{ url_for('leitstand_uebersicht_bearbeiten', auftrag_id=a.id, maschine_id=filter_maschine_id, status=filter_status) }}">Bearbeiten</a>
<form method="post" action="{{ url_for('leitstand_uebersicht_loeschen', auftrag_id=a.id) }}" class="order-form">
@@ -50,6 +53,7 @@
<button type="submit" class="icon-btn danger">L&ouml;schen</button>
</form>
</div>
{% endif %}
</td>
</tr>
{% endfor %}
@@ -31,7 +31,18 @@
<label for="soll_h">St&uuml;ck pro Stunde</label>
<input type="number" step="any" id="soll_h" name="soll_h" value="{{ auftrag.soll_h_fmt }}" {{ 'readonly' if gesperrt }} required>
</div>
{% if gesperrt %}
<div class="status-line"><span class="label">Status</span><span>{{ status_anzeige }}</span></div>
{% else %}
<div class="form-group">
<label for="status">Status</label>
<select id="status" name="status" required>
{% for wert, label in status_optionen %}
<option value="{{ wert }}" {% if auftrag.status == wert %}selected{% endif %}>{{ label }}</option>
{% endfor %}
</select>
</div>
{% endif %}
<div class="status-line">
<span class="label">Priorit&auml;t</span>
<span>{{ auftrag.sid_fmt }} <span style="color:var(--text-dim); font-size:0.85em;">(&auml;nderbar unter "Auftragspriorit&auml;t")</span></span>