🎉 Refactor & Update Backend Files, Documentation 📚

This commit is contained in:
2025-06-01 00:05:09 +02:00
parent 193164964e
commit b2bdc2d123
12 changed files with 4178 additions and 1868 deletions

View File

@@ -96,6 +96,12 @@ def guest_request_form():
)
db_session.add(guest_request)
db_session.flush() # Um ID zu erhalten
# OTP-Code sofort generieren für Status-Abfrage
otp_code = guest_request.generate_otp()
guest_request.otp_expires_at = datetime.now() + timedelta(hours=72) # 72h gültig
db_session.commit()
# Benachrichtigung für Genehmiger erstellen
@@ -109,10 +115,10 @@ def guest_request_form():
}
)
logger.info(f"Neue Gastanfrage erstellt: ID {guest_request.id}, Name: {name}")
logger.info(f"Neue Gastanfrage erstellt: ID {guest_request.id}, Name: {name}, OTP generiert")
flash("Ihr Antrag wurde erfolgreich eingereicht!", "success")
# Weiterleitung zur Status-Seite
# Weiterleitung zur Status-Seite mit OTP-Code-Info
return redirect(url_for('guest.guest_request_status', request_id=guest_request.id))
except Exception as e:
@@ -295,6 +301,12 @@ def api_create_guest_request():
)
db_session.add(guest_request)
db_session.flush() # Um ID zu erhalten
# OTP-Code sofort generieren für Status-Abfrage
otp_code = guest_request.generate_otp()
guest_request.otp_expires_at = datetime.now() + timedelta(hours=72) # 72h gültig
db_session.commit()
# Benachrichtigung für Genehmiger erstellen
@@ -308,12 +320,14 @@ def api_create_guest_request():
}
)
logger.info(f"Neue Gastanfrage erstellt: ID {guest_request.id}, Name: {name}")
logger.info(f"Neue Gastanfrage erstellt: ID {guest_request.id}, Name: {name}, OTP generiert")
return jsonify({
"success": True,
"request_id": guest_request.id,
"status": guest_request.status,
"otp_code": otp_code, # Code wird nur bei Erstellung zurückgegeben
"status_check_url": url_for('guest.guest_status_check_page', _external=True),
"redirect_url": url_for('guest.guest_request_status', request_id=guest_request.id)
})
@@ -852,4 +866,126 @@ def api_deny_request(request_id):
except Exception as e:
logger.error(f"Fehler beim Ablehnen der Gastanfrage: {str(e)}")
return jsonify({"error": "Fehler beim Verarbeiten der Anfrage"}), 500
return jsonify({"error": "Fehler beim Verarbeiten der Anfrage"}), 500
@guest_blueprint.route('/api/guest/status', methods=['POST'])
def api_guest_status_by_otp():
"""
Öffentliche Route für Gäste um ihren Auftragsstatus mit OTP-Code zu prüfen.
Keine Authentifizierung erforderlich.
"""
try:
data = request.get_json()
if not data:
return jsonify({
'success': False,
'message': 'Keine Daten empfangen'
}), 400
otp_code = data.get('otp_code', '').strip()
email = data.get('email', '').strip() # Optional für zusätzliche Verifikation
if not otp_code:
return jsonify({
'success': False,
'message': 'OTP-Code ist erforderlich'
}), 400
with get_cached_session() as db_session:
# Alle Gastaufträge mit OTP-Codes finden
guest_requests = db_session.query(GuestRequest).filter(
GuestRequest.otp_code.isnot(None)
).all()
found_request = None
for request_obj in guest_requests:
if request_obj.verify_otp(otp_code):
# Zusätzliche E-Mail-Verifikation falls angegeben
if email and request_obj.email and request_obj.email.lower() != email.lower():
continue
found_request = request_obj
break
if not found_request:
logger.warning(f"Ungültiger OTP-Code für Gast-Status-Abfrage: {otp_code[:4]}****")
return jsonify({
'success': False,
'message': 'Ungültiger Code oder E-Mail-Adresse'
}), 404
# Status-Informationen für den Gast zusammenstellen
status_info = {
'id': found_request.id,
'name': found_request.name,
'file_name': found_request.file_name,
'status': found_request.status,
'created_at': found_request.created_at.isoformat() if found_request.created_at else None,
'updated_at': found_request.updated_at.isoformat() if found_request.updated_at else None,
'duration_min': found_request.duration_min,
'reason': found_request.reason
}
# Status-spezifische Informationen hinzufügen
if found_request.status == 'approved':
status_info.update({
'approved_at': found_request.approved_at.isoformat() if found_request.approved_at else None,
'approval_notes': found_request.approval_notes,
'message': 'Ihr Auftrag wurde genehmigt! Sie können mit dem Drucken beginnen.',
'can_start_job': found_request.otp_used_at is None # Noch nicht verwendet
})
# Job-Informationen hinzufügen falls vorhanden
if found_request.job_id:
job = db_session.query(Job).options(joinedload(Job.printer)).filter_by(id=found_request.job_id).first()
if job:
status_info['job'] = {
'id': job.id,
'name': job.name,
'status': job.status,
'start_at': job.start_at.isoformat() if job.start_at else None,
'end_at': job.end_at.isoformat() if job.end_at else None,
'printer_name': job.printer.name if job.printer else None
}
elif found_request.status == 'rejected':
status_info.update({
'rejected_at': found_request.rejected_at.isoformat() if found_request.rejected_at else None,
'rejection_reason': found_request.rejection_reason,
'message': 'Ihr Auftrag wurde leider abgelehnt.'
})
elif found_request.status == 'pending':
# Berechne wie lange der Auftrag schon wartet
if found_request.created_at:
waiting_time = datetime.now() - found_request.created_at
hours_waiting = int(waiting_time.total_seconds() / 3600)
status_info.update({
'hours_waiting': hours_waiting,
'message': f'Ihr Auftrag wird bearbeitet. Wartezeit: {hours_waiting} Stunden.'
})
else:
status_info['message'] = 'Ihr Auftrag wird bearbeitet.'
# OTP als verwendet markieren (da erfolgreich abgefragt)
db_session.commit()
logger.info(f"Gast-Status-Abfrage erfolgreich für Request {found_request.id}")
return jsonify({
'success': True,
'request': status_info
})
except Exception as e:
logger.error(f"Fehler bei Gast-Status-Abfrage: {str(e)}")
return jsonify({
'success': False,
'message': 'Fehler beim Abrufen des Status'
}), 500
@guest_blueprint.route('/status-check')
def guest_status_check_page():
"""
Öffentliche Seite für Gäste um ihren Auftragsstatus zu prüfen.
"""
return render_template('guest_status_check.html')