remove lexoffice name in project

This commit is contained in:
duffyduck 2026-03-06 08:40:53 +01:00
parent b93d9e4def
commit f74f936d72
9 changed files with 39 additions and 39 deletions

View File

@ -19,7 +19,7 @@ DEFAULT_SETTINGS = {
"smtp_ssl": "starttls", "smtp_ssl": "starttls",
"smtp_username": "", "smtp_username": "",
"smtp_password": "", "smtp_password": "",
"lexoffice_email": "", "import_email": "",
"source_folder": "Rechnungen", "source_folder": "Rechnungen",
"processed_folder": "Rechnungen/Verarbeitet", "processed_folder": "Rechnungen/Verarbeitet",
"interval_minutes": "5", "interval_minutes": "5",

View File

@ -85,7 +85,7 @@ def _build_forward_email(
msg["Subject"] = f"Belegimport: {original_subject}" msg["Subject"] = f"Belegimport: {original_subject}"
body = ( body = (
f"Automatisch weitergeleitet von LexOffice Belegimport.\n" f"Automatisch weitergeleitet von Belegimport.\n"
f"Original-Absender: {original_from}\n" f"Original-Absender: {original_from}\n"
f"Original-Betreff: {original_subject}\n" f"Original-Betreff: {original_subject}\n"
f"Anzahl Anhänge: {len(attachments)}" f"Anzahl Anhänge: {len(attachments)}"
@ -121,13 +121,13 @@ def _move_email(conn: imaplib.IMAP4, msg_uid: bytes, dest_folder: str):
async def process_mailbox() -> dict: async def process_mailbox() -> dict:
settings = await get_settings() settings = await get_settings()
if not settings.get("imap_server") or not settings.get("lexoffice_email"): if not settings.get("imap_server") or not settings.get("import_email"):
logger.warning("IMAP oder LexOffice-Email nicht konfiguriert") logger.warning("IMAP oder Import-Email nicht konfiguriert")
return {"processed": 0, "skipped": 0, "errors": 0, "error": "Nicht konfiguriert"} return {"processed": 0, "skipped": 0, "errors": 0, "error": "Nicht konfiguriert"}
source_folder = settings.get("source_folder", "INBOX") source_folder = settings.get("source_folder", "INBOX")
processed_folder = settings.get("processed_folder", "INBOX/Verarbeitet") processed_folder = settings.get("processed_folder", "INBOX/Verarbeitet")
lexoffice_email = settings["lexoffice_email"] import_email = settings["import_email"]
smtp_from = settings.get("smtp_username", "") smtp_from = settings.get("smtp_username", "")
processed = 0 processed = 0
@ -187,7 +187,7 @@ async def process_mailbox() -> dict:
forward_msg = _build_forward_email( forward_msg = _build_forward_email(
from_addr=smtp_from, from_addr=smtp_from,
to_addr=lexoffice_email, to_addr=import_email,
original_subject=subject, original_subject=subject,
original_from=from_addr, original_from=from_addr,
attachments=attachments, attachments=attachments,
@ -259,18 +259,18 @@ async def process_mailbox() -> dict:
async def send_test_email() -> dict: async def send_test_email() -> dict:
settings = await get_settings() settings = await get_settings()
if not settings.get("smtp_server") or not settings.get("lexoffice_email"): if not settings.get("smtp_server") or not settings.get("import_email"):
return {"success": False, "error": "SMTP oder LexOffice-Email nicht konfiguriert"} return {"success": False, "error": "SMTP oder Import-Email nicht konfiguriert"}
try: try:
smtp_conn = _connect_smtp(settings) smtp_conn = _connect_smtp(settings)
msg = MIMEMultipart() msg = MIMEMultipart()
msg["From"] = settings["smtp_username"] msg["From"] = settings["smtp_username"]
msg["To"] = settings["lexoffice_email"] msg["To"] = settings["import_email"]
msg["Subject"] = "LexOffice Belegimport - Test-Email" msg["Subject"] = "Belegimport - Test-Email"
msg.attach(MIMEText( msg.attach(MIMEText(
"Dies ist eine Test-Email vom LexOffice Belegimport Service.\n" "Dies ist eine Test-Email vom Belegimport Service.\n"
"Wenn Sie diese Email erhalten, funktioniert die SMTP-Verbindung.", "Wenn Sie diese Email erhalten, funktioniert die SMTP-Verbindung.",
"plain", "plain",
"utf-8", "utf-8",

View File

@ -32,12 +32,12 @@ async def lifespan(app: FastAPI):
interval = int(settings.get("interval_minutes", 5)) interval = int(settings.get("interval_minutes", 5))
enabled = settings.get("scheduler_enabled", "false") == "true" enabled = settings.get("scheduler_enabled", "false") == "true"
configure_job(interval, enabled) configure_job(interval, enabled)
logger.info("LexOffice Belegimport gestartet") logger.info("Belegimport gestartet")
yield yield
logger.info("LexOffice Belegimport beendet") logger.info("Belegimport beendet")
app = FastAPI(title="LexOffice Belegimport", lifespan=lifespan) app = FastAPI(title="Belegimport", lifespan=lifespan)
app.mount("/static", StaticFiles(directory="app/static"), name="static") app.mount("/static", StaticFiles(directory="app/static"), name="static")
templates = Jinja2Templates(directory="app/templates") templates = Jinja2Templates(directory="app/templates")
@ -73,7 +73,7 @@ async def _save_form_settings(request: Request) -> dict:
"smtp_ssl": form.get("smtp_ssl", "starttls"), "smtp_ssl": form.get("smtp_ssl", "starttls"),
"smtp_username": form.get("smtp_username", ""), "smtp_username": form.get("smtp_username", ""),
"smtp_password": form.get("smtp_password") or current.get("smtp_password", ""), "smtp_password": form.get("smtp_password") or current.get("smtp_password", ""),
"lexoffice_email": form.get("lexoffice_email", ""), "import_email": form.get("import_email", ""),
"source_folder": form.get("source_folder", "Rechnungen"), "source_folder": form.get("source_folder", "Rechnungen"),
"processed_folder": form.get("processed_folder", "Rechnungen/Verarbeitet"), "processed_folder": form.get("processed_folder", "Rechnungen/Verarbeitet"),
"interval_minutes": form.get("interval_minutes", "5"), "interval_minutes": form.get("interval_minutes", "5"),
@ -323,5 +323,5 @@ async def separator_pdf():
return Response( return Response(
content=pdf_bytes, content=pdf_bytes,
media_type="application/pdf", media_type="application/pdf",
headers={"Content-Disposition": "attachment; filename=Trennseite_LexOffice.pdf"}, headers={"Content-Disposition": "attachment; filename=Trennseite.pdf"},
) )

View File

@ -16,7 +16,7 @@ from app.mail_processor import _connect_smtp, _build_forward_email
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
SEPARATOR_QR_CONTENT = "LEXOFFICE-TRENNUNG" SEPARATOR_QR_CONTENT = "BELEGIMPORT-TRENNUNG"
UPLOAD_DIR = Path(os.environ.get("UPLOAD_DIR", "/data/uploads")) UPLOAD_DIR = Path(os.environ.get("UPLOAD_DIR", "/data/uploads"))
@ -85,11 +85,11 @@ def split_pdf(pdf_path: str, separator_pages: list[int]) -> list[bytes]:
async def process_scanned_pdf(pdf_path: str, progress_callback=None) -> dict: async def process_scanned_pdf(pdf_path: str, progress_callback=None) -> dict:
"""Full pipeline: detect separators, split, send each document to LexOffice.""" """Full pipeline: detect separators, split, send each document via email."""
settings = await get_settings() settings = await get_settings()
if not settings.get("smtp_server") or not settings.get("lexoffice_email"): if not settings.get("smtp_server") or not settings.get("import_email"):
return {"error": "SMTP oder LexOffice-Email nicht konfiguriert", "total_pages": 0, "documents": 0, "sent": 0, "errors": 1} return {"error": "SMTP oder Import-Email nicht konfiguriert", "total_pages": 0, "documents": 0, "sent": 0, "errors": 1}
# Step 1: Detect separator pages (CPU-bound, run in thread) # Step 1: Detect separator pages (CPU-bound, run in thread)
if progress_callback: if progress_callback:
@ -116,7 +116,7 @@ async def process_scanned_pdf(pdf_path: str, progress_callback=None) -> dict:
if not documents: if not documents:
return {"error": "Keine Dokumente nach dem Splitting gefunden", "total_pages": total_pages, "documents": 0, "sent": 0, "errors": 1} return {"error": "Keine Dokumente nach dem Splitting gefunden", "total_pages": total_pages, "documents": 0, "sent": 0, "errors": 1}
# Step 3: Send each document to LexOffice # Step 3: Send each document via email
if progress_callback: if progress_callback:
progress_callback("status", 0, 0, f"{len(documents)} Dokument(e) erkannt, starte Versand...") progress_callback("status", 0, 0, f"{len(documents)} Dokument(e) erkannt, starte Versand...")
@ -135,7 +135,7 @@ async def process_scanned_pdf(pdf_path: str, progress_callback=None) -> dict:
filename = f"Scan_Dokument_{i + 1}.pdf" filename = f"Scan_Dokument_{i + 1}.pdf"
msg = _build_forward_email( msg = _build_forward_email(
from_addr=settings["smtp_username"], from_addr=settings["smtp_username"],
to_addr=settings["lexoffice_email"], to_addr=settings["import_email"],
original_subject=f"Scan-Upload Dokument {i + 1}/{len(documents)}", original_subject=f"Scan-Upload Dokument {i + 1}/{len(documents)}",
original_from="Scan-Upload", original_from="Scan-Upload",
attachments=[(filename, doc_bytes)], attachments=[(filename, doc_bytes)],
@ -217,7 +217,7 @@ def generate_separator_pdf() -> bytes:
# Title text # Title text
_centered_textbox(page, 120, "TRENNSEITE", 36, (0, 0, 0)) _centered_textbox(page, 120, "TRENNSEITE", 36, (0, 0, 0))
_centered_textbox(page, 170, "LexOffice Belegimport", 16, (0.4, 0.4, 0.4)) _centered_textbox(page, 170, "Belegimport", 16, (0.4, 0.4, 0.4))
# Insert QR code image centered # Insert QR code image centered
qr_bytes = io.BytesIO() qr_bytes = io.BytesIO()

View File

@ -124,12 +124,12 @@ async def process_smb_share() -> dict:
if not settings.get("smb_server") or not settings.get("smb_share"): if not settings.get("smb_server") or not settings.get("smb_share"):
return {"processed": 0, "skipped": 0, "errors": 0, "error": "SMB nicht konfiguriert"} return {"processed": 0, "skipped": 0, "errors": 0, "error": "SMB nicht konfiguriert"}
if not settings.get("lexoffice_email"): if not settings.get("import_email"):
return {"processed": 0, "skipped": 0, "errors": 0, "error": "LexOffice-Email nicht konfiguriert"} return {"processed": 0, "skipped": 0, "errors": 0, "error": "Import-Email nicht konfiguriert"}
mode = settings.get("smb_mode", "forward") mode = settings.get("smb_mode", "forward")
smtp_from = settings.get("smtp_username", "") smtp_from = settings.get("smtp_username", "")
lexoffice_email = settings["lexoffice_email"] import_email = settings["import_email"]
processed = 0 processed = 0
skipped = 0 skipped = 0
@ -180,7 +180,7 @@ async def process_smb_share() -> dict:
subject = f"SMB-Import: {filename} (Dokument {i + 1}/{len(documents)})" subject = f"SMB-Import: {filename} (Dokument {i + 1}/{len(documents)})"
msg = _build_forward_email( msg = _build_forward_email(
from_addr=smtp_from, from_addr=smtp_from,
to_addr=lexoffice_email, to_addr=import_email,
original_subject=subject, original_subject=subject,
original_from="SMB-Import", original_from="SMB-Import",
attachments=[(doc_filename, doc_bytes)], attachments=[(doc_filename, doc_bytes)],
@ -200,7 +200,7 @@ async def process_smb_share() -> dict:
else: else:
msg = _build_forward_email( msg = _build_forward_email(
from_addr=smtp_from, from_addr=smtp_from,
to_addr=lexoffice_email, to_addr=import_email,
original_subject=f"SMB-Import: {filename}", original_subject=f"SMB-Import: {filename}",
original_from="SMB-Import", original_from="SMB-Import",
attachments=[(filename, pdf_data)], attachments=[(filename, pdf_data)],

View File

@ -3,12 +3,12 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>LexOffice Belegimport</title> <title>Belegimport</title>
<link rel="stylesheet" href="/static/style.css"> <link rel="stylesheet" href="/static/style.css">
</head> </head>
<body> <body>
<nav> <nav>
<div class="nav-brand">LexOffice Belegimport</div> <div class="nav-brand">Belegimport</div>
<div class="nav-links"> <div class="nav-links">
<a href="/" class="{% if active_page == 'settings' %}active{% endif %}">Einstellungen</a> <a href="/" class="{% if active_page == 'settings' %}active{% endif %}">Einstellungen</a>
<a href="/scan" class="{% if active_page == 'scan' %}active{% endif %}">Scan-Upload</a> <a href="/scan" class="{% if active_page == 'scan' %}active{% endif %}">Scan-Upload</a>

View File

@ -5,7 +5,7 @@
<div class="card"> <div class="card">
<h2>Scan-Upload</h2> <h2>Scan-Upload</h2>
<p class="text-muted" style="margin-bottom:1rem;"> <p class="text-muted" style="margin-bottom:1rem;">
Mehrseitige PDF hochladen. Trennseiten mit QR-Code werden automatisch erkannt und die einzelnen Dokumente an LexOffice gesendet. Mehrseitige PDF hochladen. Trennseiten mit QR-Code werden automatisch erkannt und die einzelnen Dokumente gesendet.
</p> </p>
<!-- Upload Zone --> <!-- Upload Zone -->
@ -234,7 +234,7 @@ function listenProgress(uploadId) {
if (result.separator_pages > 0) { if (result.separator_pages > 0) {
msg += ' (' + result.separator_pages + ' Trennseite(n))'; msg += ' (' + result.separator_pages + ' Trennseite(n))';
} }
msg += ', ' + result.sent + ' an LexOffice gesendet'; msg += ', ' + result.sent + ' gesendet';
if (result.errors > 0) { if (result.errors > 0) {
msg += ', ' + result.errors + ' Fehler'; msg += ', ' + result.errors + ' Fehler';
showResult(msg, 'warning'); showResult(msg, 'warning');

View File

@ -77,12 +77,12 @@
</div> </div>
<div class="card"> <div class="card">
<h2>LexOffice & Ordner</h2> <h2>Import & Ordner</h2>
<div class="form-grid"> <div class="form-grid">
<div class="form-group form-group-wide"> <div class="form-group form-group-wide">
<label for="lexoffice_email">LexOffice Import-Emailadresse</label> <label for="import_email">Import-Emailadresse</label>
<input type="email" id="lexoffice_email" name="lexoffice_email" <input type="email" id="import_email" name="import_email"
value="{{ settings.get('lexoffice_email', '') }}" placeholder="import-xyz@lexoffice.de"> value="{{ settings.get('import_email', '') }}" placeholder="import@example.com">
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="source_folder">Eingangsordner (IMAP)</label> <label for="source_folder">Eingangsordner (IMAP)</label>
@ -103,7 +103,7 @@
</div> </div>
<div class="form-actions"> <div class="form-actions">
<button type="button" class="btn btn-secondary" onclick="testEmail()"> <button type="button" class="btn btn-secondary" onclick="testEmail()">
<span class="btn-text">Test-Email an LexOffice senden</span> <span class="btn-text">Test-Email senden</span>
<span class="btn-spinner" style="display:none;">Sende...</span> <span class="btn-spinner" style="display:none;">Sende...</span>
</button> </button>
</div> </div>
@ -343,7 +343,7 @@ async function testEmail() {
const resp = await fetch('/api/test-email', { method: 'POST', body: getFormData() }); const resp = await fetch('/api/test-email', { method: 'POST', body: getFormData() });
const data = await resp.json(); const data = await resp.json();
if (data.success) { if (data.success) {
const addr = document.getElementById('lexoffice_email').value; const addr = document.getElementById('import_email').value;
showAlert('Test-Email erfolgreich an ' + addr + ' gesendet! Einstellungen gespeichert.', 'success'); showAlert('Test-Email erfolgreich an ' + addr + ' gesendet! Einstellungen gespeichert.', 'success');
} else { } else {
showAlert('Test-Email fehlgeschlagen: ' + data.error, 'error'); showAlert('Test-Email fehlgeschlagen: ' + data.error, 'error');

View File

@ -1,7 +1,7 @@
services: services:
belegimport: belegimport:
build: . build: .
container_name: lexoffice-belegimport container_name: belegimport
ports: ports:
- "8081:8000" - "8081:8000"
volumes: volumes: