diff --git a/README.md b/README.md index 16887c5..8b1c845 100644 --- a/README.md +++ b/README.md @@ -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. diff --git a/VERSION b/VERSION index afaf360..7f20734 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.0.0 \ No newline at end of file +1.0.1 \ No newline at end of file diff --git a/build/app.py b/build/app.py index ceddd35..55ff202 100644 --- a/build/app.py +++ b/build/app.py @@ -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//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)) @@ -1123,4 +1154,4 @@ def health(): if __name__ == "__main__": - app.run(host="0.0.0.0", port=5000, debug=False) + app.run(host="0.0.0.0", port=5000, debug=False) \ No newline at end of file diff --git a/build/templates/leitstand_uebersicht.html b/build/templates/leitstand_uebersicht.html index 1254a8c..20848ec 100644 --- a/build/templates/leitstand_uebersicht.html +++ b/build/templates/leitstand_uebersicht.html @@ -14,7 +14,7 @@ Status: @@ -42,6 +42,9 @@ {{ "Ja" if a.aktiv else "Nein" }} {{ a.sid_fmt }} + {% if a.status == "aktiv" %} + gesperrt (aktiv an Maschine) + {% else %}
Bearbeiten
@@ -50,6 +53,7 @@
+ {% endif %} {% endfor %} @@ -57,4 +61,4 @@ {% endif %} -{% endblock %} +{% endblock %} \ No newline at end of file diff --git a/build/templates/leitstand_uebersicht_bearbeiten.html b/build/templates/leitstand_uebersicht_bearbeiten.html index e3b2f90..c667b33 100644 --- a/build/templates/leitstand_uebersicht_bearbeiten.html +++ b/build/templates/leitstand_uebersicht_bearbeiten.html @@ -31,7 +31,18 @@ + {% if gesperrt %}
Status{{ status_anzeige }}
+ {% else %} +
+ + +
+ {% endif %}
Priorität {{ auftrag.sid_fmt }} (änderbar unter "Auftragspriorität")