implementation of the upload
This commit is contained in:
+92
-12
@@ -23,6 +23,7 @@ from markupsafe import escape
|
||||
from pymongo import MongoClient
|
||||
from pymongo.errors import PyMongoError
|
||||
from bson.objectid import ObjectId
|
||||
from bson.binary import Binary
|
||||
import user as user_store
|
||||
import buchungen
|
||||
import server_steering as steering
|
||||
@@ -119,6 +120,7 @@ LEGAL_DOWNLOAD_FILES = (
|
||||
],
|
||||
),
|
||||
)
|
||||
ALLOWED_CONTRACT_EXTENSIONS = {'pdf', 'png', 'jpg', 'jpeg', 'webp'}
|
||||
MONGO_URI = os.environ.get("MONGO_URI", "mongodb://localhost:27017")
|
||||
MONGO_DB_NAME = os.environ.get("MONGO_DB_NAME", "Invario_Website")
|
||||
INSTANCE_REPO_URL = os.environ.get("INSTANCE_REPO_URL", "https://git.invario-software.eu/Invario/Inventarsystem")
|
||||
@@ -184,6 +186,10 @@ def _is_allowed_image_filename(filename: str) -> bool:
|
||||
return lowered.endswith(".jpg") or lowered.endswith(".jpeg") or lowered.endswith(".png") or lowered.endswith(".webp")
|
||||
|
||||
|
||||
def _allowed_contract_file(filename):
|
||||
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_CONTRACT_EXTENSIONS
|
||||
|
||||
|
||||
def _is_allowed_tutorial_video_filename(filename: str) -> bool:
|
||||
if not filename:
|
||||
return False
|
||||
@@ -2732,25 +2738,102 @@ def blog_post(post_id):
|
||||
return render_template("blog_post.html", post=post)
|
||||
|
||||
|
||||
@app.route('/my/invoices')
|
||||
@app.route('/invoices/<invoice_id>/hauptvertrag')
|
||||
@login_required
|
||||
def my_invoices():
|
||||
invoices = []
|
||||
def view_hauptvertrag(invoice_id):
|
||||
client = None
|
||||
try:
|
||||
client, col = _get_collection("invoices")
|
||||
invoices = list(col.find({"username": session.get("username")}, {"_id": 0}).sort("created_at", -1))
|
||||
invoice = col.find_one({"_id": ObjectId(invoice_id)})
|
||||
|
||||
# Beträge in Float umwandeln, da das Jinja-Template echte Zahlen erwartet
|
||||
for inv in invoices:
|
||||
if not invoice or "hauptvertrag_data" not in invoice:
|
||||
flash("Kein Hauptvertrag für diese Rechnung vorhanden.", "error")
|
||||
return redirect(url_for("my_invoices"))
|
||||
|
||||
# Sicherheitsprüfung: Darf der Nutzer die Datei sehen? (Nutzer selbst oder Admin)
|
||||
current_user = session.get("username")
|
||||
is_admin = session.get("is_admin")
|
||||
if invoice.get("username") != current_user and not is_admin:
|
||||
flash("Keine Berechtigung zum Anschauen dieses Hauptvertrags.", "error")
|
||||
return redirect(url_for("my_invoices"))
|
||||
|
||||
# Datei-Streams aus den Binärdaten in MongoDB erzeugen
|
||||
file_data = invoice["hauptvertrag_data"]
|
||||
mimetype = invoice.get("hauptvertrag_mimetype", "application/pdf")
|
||||
filename = invoice.get("hauptvertrag_filename", "hauptvertrag")
|
||||
|
||||
return send_file(
|
||||
io.BytesIO(file_data),
|
||||
mimetype=mimetype,
|
||||
as_attachment=False,
|
||||
download_name=filename
|
||||
)
|
||||
except Exception as e:
|
||||
flash("Fehler beim Abrufen der Datei aus der Datenbank.", "error")
|
||||
return redirect(url_for("my_invoices"))
|
||||
finally:
|
||||
if client:
|
||||
client.close()
|
||||
|
||||
|
||||
@app.route('/my/invoices', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def my_invoices():
|
||||
client = None
|
||||
|
||||
# POST-Request: Datei in MongoDB speichern
|
||||
if request.method == 'POST':
|
||||
action = request.form.get("action")
|
||||
invoice_id = request.form.get("invoice_id")
|
||||
uploaded_file = request.files.get("hauptvertrag_file")
|
||||
|
||||
if action == "upload_hauptvertrag" and invoice_id and uploaded_file:
|
||||
if _allowed_contract_file(uploaded_file.filename):
|
||||
file_bytes = uploaded_file.read()
|
||||
filename = uploaded_file.filename
|
||||
mimetype = uploaded_file.mimetype or "application/octet-stream"
|
||||
|
||||
try:
|
||||
client, col = _get_collection("invoices")
|
||||
# Datei direkt als Binary in das Invoice-Dokument schreiben
|
||||
col.update_one(
|
||||
{"_id": ObjectId(invoice_id), "username": session.get("username")},
|
||||
{"$set": {
|
||||
"hauptvertrag_data": Binary(file_bytes),
|
||||
"hauptvertrag_filename": filename,
|
||||
"hauptvertrag_mimetype": mimetype,
|
||||
"paperwork_status": "Hauptvertrag hochgeladen",
|
||||
"updated_at": _utc_now_iso()
|
||||
}}
|
||||
)
|
||||
flash("Hauptvertrag erfolgreich in der Datenbank gespeichert.", "success")
|
||||
except Exception:
|
||||
flash("Fehler beim Speichern in MongoDB.", "error")
|
||||
finally:
|
||||
if client:
|
||||
client.close()
|
||||
else:
|
||||
flash("Ungültiges Format. Erlaubt sind PDF, JPG, PNG und WEBP.", "error")
|
||||
return redirect(url_for("my_invoices"))
|
||||
|
||||
# GET-Request: Rechnungen laden
|
||||
invoices = []
|
||||
try:
|
||||
client, col = _get_collection("invoices")
|
||||
raw_invoices = list(col.find({"username": session.get("username")}).sort("created_at", -1))
|
||||
|
||||
for inv in raw_invoices:
|
||||
inv["id"] = str(inv["_id"])
|
||||
amt = inv.get("amount_eur", 0)
|
||||
if isinstance(amt, str):
|
||||
try:
|
||||
# Entfernt Tausenderpunkte und wandelt das deutsche Komma in einen Punkt um
|
||||
amt = float(amt.replace('.', '').replace(',', '.'))
|
||||
except ValueError:
|
||||
amt = 0.0
|
||||
inv["amount_eur"] = amt
|
||||
# Flag setzen, ob Vertrag in MongoDB liegt (ohne die schweren Binärdaten ins Template zu laden)
|
||||
inv["has_hauptvertrag"] = "hauptvertrag_data" in inv
|
||||
invoices.append(inv)
|
||||
|
||||
except PyMongoError:
|
||||
flash("Rechnungen konnten nicht geladen werden.", "error")
|
||||
@@ -2758,15 +2841,12 @@ def my_invoices():
|
||||
if client:
|
||||
client.close()
|
||||
|
||||
# Load instance requests for this user
|
||||
instance_requests = []
|
||||
try:
|
||||
req_client, req_col = _get_collection("instance_requests")
|
||||
instance_requests = list(req_col.find({"username": session.get("username")}).sort("created_at", -1))
|
||||
for item in instance_requests:
|
||||
item["id"] = str(item.get("_id"))
|
||||
|
||||
# Auch hier sicherstellen, dass der Betrag ein Float ist
|
||||
amt = item.get("amount_eur", 0)
|
||||
if isinstance(amt, str):
|
||||
try:
|
||||
@@ -2774,15 +2854,15 @@ def my_invoices():
|
||||
except ValueError:
|
||||
amt = 0.0
|
||||
item["amount_eur"] = amt
|
||||
|
||||
except PyMongoError:
|
||||
flash("Instanz-Anfragen konnten nicht geladen werden.", "error")
|
||||
finally:
|
||||
if 'req_client' in locals() and req_client:
|
||||
req_client.close()
|
||||
|
||||
|
||||
return render_template("my_invoices.html", invoices=invoices, instance_requests=instance_requests)
|
||||
|
||||
|
||||
@app.route('/my/instance', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def my_instance_management():
|
||||
|
||||
Reference in New Issue
Block a user