# Lösung: "undefined" Druckaufträge Problem ## 📋 Problem-Beschreibung Das Mercedes-Benz MYP System zeigte bei Druckaufträgen häufig "undefined" Werte an, insbesondere: - Job-Name als "undefined" - Drucker-Name als "undefined" - Dauer als "undefined Min" - Benutzer-Informationen als "undefined"  ## 🔍 Ursachen-Analyse ### 1. **Inkonsistente Datenfelder** Das Backend-Model `Job.to_dict()` gab andere Feldnamen zurück als das Frontend erwartete: **Backend gab zurück:** - `name` (statt `filename`/`title`) - `printer` (Objekt statt `printer_name`) - `user` (Objekt statt `user_name`) **Frontend erwartete:** - `filename`, `title` oder `file_name` - `printer_name` (String) - `user_name` (String) ### 2. **Fehlende Dashboard-Daten** Die Dashboard-Funktion in `app.py` war leer und lud keine Daten: ```python @app.route("/dashboard") @login_required def dashboard(): """Haupt-Dashboard""" return render_template("dashboard.html") # Keine Daten! ``` ### 3. **JavaScript Null-Checks unvollständig** ```javascript // Problematisch: ${job.filename || job.title || job.name || 'Unbekannter Job'} // Wenn alle undefined → undefined wird angezeigt ``` ## ✅ Implementierte Lösung ### 1. **Erweiterte Job.to_dict() Methode** (`models.py`) ```python def to_dict(self) -> dict: # Grundlegende Job-Informationen result = { "id": self.id, "name": self.name, "description": self.description, # ... weitere Grundfelder } # Frontend-kompatible Felder hinzufügen result.update({ # Alternative Namen für Frontend-Kompatibilität "title": self.name, "filename": self.name, "file_name": self.name, # Drucker-Informationen direkt verfügbar "printer_name": self.printer.name if self.printer else "Unbekannter Drucker", "printer_model": self.printer.model if self.printer else None, # Benutzer-Informationen direkt verfügbar "user_name": self.user.name if self.user else "Unbekannter Benutzer", "username": self.user.username if self.user else None, # Zeitstempel in deutschen Formaten "start_time": self.start_at.strftime('%d.%m.%Y %H:%M') if self.start_at else "Nicht festgelegt", "created_time": self.created_at.strftime('%d.%m.%Y %H:%M') if self.created_at else "Unbekannt", # Status-Text in Deutsch "status_text": self._get_status_text(self.status), # Berechnete Felder "progress": self._calculate_progress(), "remaining_minutes": self._calculate_remaining_minutes() }) return result def _get_status_text(self, status: str) -> str: """Wandelt englische Status-Codes in deutsche Texte um""" status_mapping = { 'scheduled': 'Geplant', 'pending': 'Wartend', 'running': 'Läuft', 'completed': 'Abgeschlossen', 'failed': 'Fehlgeschlagen', # ... weitere Mappings } return status_mapping.get(status, status.title() if status else 'Unbekannt') ``` ### 2. **Vollständige Dashboard-Funktion** (`app.py`) ```python @app.route("/dashboard") @login_required def dashboard(): """Haupt-Dashboard mit vollständigen Daten für die Anzeige""" try: db_session = get_db_session() # Aktive Jobs laden active_jobs_query = db_session.query(Job).filter( Job.status.in_(['scheduled', 'running', 'printing', 'pending']) ) if not current_user.is_admin: active_jobs_query = active_jobs_query.filter(Job.user_id == current_user.id) active_jobs = active_jobs_query.order_by(Job.created_at.desc()).limit(10).all() # Statistiken berechnen active_jobs_count = len(active_jobs) available_printers_count = len([p for p in printers if p.status in ['idle', 'ready']]) success_rate = round((completed_jobs_count / total_jobs_count * 100), 1) if total_jobs_count > 0 else 0 # Template-Daten mit Fallback-Werten template_data = { 'active_jobs_count': active_jobs_count, 'available_printers_count': available_printers_count, 'total_jobs_count': total_jobs_count, 'success_rate': success_rate, 'active_jobs': dashboard_active_jobs, 'printers': dashboard_printers, 'activities': activities, # ... weitere Daten } return render_template("dashboard.html", **template_data) except Exception as e: # Fallback-Dashboard mit sicheren Standardwerten fallback_data = { 'active_jobs_count': 0, 'available_printers_count': 0, 'total_jobs_count': 0, 'success_rate': 0, 'active_jobs': [], 'printers': [], 'activities': [], 'error': f"Fehler beim Laden der Dashboard-Daten: {str(e)}" } return render_template("dashboard.html", **fallback_data) ``` ### 3. **Verbesserte JavaScript Null-Checks** (`global-refresh-functions.js`) ```javascript // Verbesserte Feldermapping für Frontend-Kompatibilität const jobName = job.name || job.title || job.filename || job.file_name || 'Unbekannter Job'; const printerName = job.printer_name || (job.printer?.name) || 'Unbekannter Drucker'; const userName = job.user_name || (job.user?.name) || 'Unbekannter Benutzer'; const statusText = job.status_text || job.status || 'Unbekannt'; const createdDate = job.created_time || (job.created_at ? new Date(job.created_at).toLocaleDateString('de-DE') : 'Unbekannt'); const progress = job.progress || 0; // Sichere Job-Karten-Darstellung return `
ID: ${job.id || 'N/A'}
Drucker: ${printerName}
Benutzer: ${userName}
Erstellt: ${createdDate}
${progress > 0 ? `Fortschritt: ${progress}%
` : ''}