38 Commits

Author SHA1 Message Date
5549c64735 chore: Version auf 1.2.19 aktualisiert 2025-03-21 17:08:56 +01:00
392eb9de32 fix: Passwort-Eingabe in upload.html wieder hinzugefügt 2025-03-21 17:07:48 +01:00
41dfe566c6 fix: Bootstrap Icons für Menü in upload.html hinzugefügt 2025-03-21 17:04:54 +01:00
db4b0cdee2 fix: Logo-Zentrierung korrigiert 2025-03-21 17:02:04 +01:00
b0a6a7e7ca chore: Version auf 1.2.18 aktualisiert 2025-03-21 16:56:34 +01:00
9e531b3f7c feat: README-Anzeige und Code-Statistiken aktualisiert 2025-03-21 16:55:31 +01:00
99bf2fa1f4 Test 2025-03-21 13:39:12 +01:00
cd4db22e72 fix: Login-Passwort aus Umgebungsvariable LOGIN_PASSWORD verwenden 2025-03-21 13:38:04 +01:00
1cf8fbb91d Version 1.2.17: Optimierte Datenbankverbindungen und verbesserte Indizes 2025-03-21 12:56:48 +01:00
16bd7ec544 Optimierung: Thread-sichere Datenbankverbindungen und verbesserte Indizes 2025-03-21 12:55:50 +01:00
4d5a7b4f5e Version 1.2.16: Verbesserte Suchfunktion und Reset-Buttons 2025-03-21 12:42:18 +01:00
9922c0ae9d Verbesserte Suchfunktion: Highlighting für allgemeine Suche und Reset-Buttons 2025-03-21 12:40:59 +01:00
93314424d9 Feature: VCF-Export der Suchergebnisse 2025-03-21 12:07:18 +01:00
d14ac5d9af Feature: CSV-Export der Suchergebnisse 2025-03-21 12:04:17 +01:00
b4939147c4 Verbesserte index.html: JavaScript-Code in separate Datei ausgelagert und Meta-Tags hinzugefügt 2025-03-21 12:03:00 +01:00
2a33fc45de Version 1.2.16: Verbesserte Darstellung der Suchergebnisse und Code-Organisation 2025-03-21 11:50:54 +01:00
3a317de8f0 Entfernt doppelte CSS-Datei style.css 2025-03-21 11:34:28 +01:00
f626cd52fd Version 1.2.15: Autovervollständigung für Orte 2025-03-21 11:25:28 +01:00
6283ccff6d Version 1.2.14: Autovervollständigung für Fachrichtungen 2025-03-21 10:53:37 +01:00
3893e148ab README Code Statistik 2025-03-20 14:20:42 +01:00
65fbde845e Update: Code-Statistiken in README.md aktualisiert 2025-03-20 14:19:23 +01:00
57d3a05a5a Remove: docker-compose.yml aus dem Repository entfernt 2025-03-20 12:17:55 +01:00
dfd50d5e78 Entferne docker-compose.yml aus Repository 2025-03-20 12:14:33 +01:00
73541796f6 Manuelle Änderungen in .gitignore 2025-03-20 12:01:07 +01:00
e3e9900482 Version 1.2.13: Korrektur der SQL-Abfrage für die allgemeine Suche 2025-03-20 11:58:54 +01:00
156078ff3a Version 1.2.13: Korrektur der SQL-Abfrage für die allgemeine Suche 2025-03-20 11:55:07 +01:00
5d56c7128e Remove: .bak-Dateien aus dem Repository entfernt und zur .gitignore hinzugefügt 2025-03-20 11:06:54 +01:00
98f887f51e Remove: CSV-Dateien aus dem Repository entfernt und zur .gitignore hinzugefügt 2025-03-20 10:23:45 +01:00
f46947b6d4 Fix: Performance-Optimierungen und verbessertes Highlighting in index.html 2025-03-20 10:14:54 +01:00
c1b55c3579 Version 1.2.12: Performance-Optimierungen und verbessertes Highlighting 2025-03-20 09:57:17 +01:00
6a2e290d54 Release v1.2.11: Filterung von intern-Einträgen und verbesserte SQL-Abfrage 2025-03-19 19:09:19 +01:00
7263464b89 Release v1.2.11: Filterung von intern-Einträgen und verbesserte SQL-Abfrage 2025-03-19 19:08:34 +01:00
7b88e62de0 Release v1.2.10: Version aus VERSION-Variable und verbesserte Zeilenabstände 2025-03-19 18:54:06 +01:00
d50ea60af9 Release v1.2.10: Version aus VERSION-Variable und verbesserte Zeilenabstände 2025-03-19 18:52:37 +01:00
ec559f5c72 Fix: Suchergebnisse werden wieder korrekt angezeigt 2025-03-19 18:39:29 +01:00
c454620ae1 Release v1.2.9: Verbesserte Adress-Links und Docker-Port-Mapping 2025-03-19 15:01:59 +01:00
94c381fbfc Aktualisierung der Dokumentation und Versionsangabe auf v1.2.8 2025-03-19 14:12:30 +01:00
06576b08d9 Verbesserte Tag-Anzeige: Badge neben dem Teilen-Button mit farblicher Hervorhebung 2025-03-19 14:07:58 +01:00
13 changed files with 1498 additions and 888 deletions

23
.gitignore vendored
View File

@@ -17,6 +17,7 @@ pip-delete-this-directory.txt
.vscode/ .vscode/
*.swp *.swp
*.swo *.swo
*.bak
# Logs # Logs
*.log *.log
@@ -43,13 +44,21 @@ coverage.xml
# Docker # Docker
.docker/ .docker/
docker-compose.yml
# Daten # Daten
spezexpo.csv data/
# Database # Virtual Environment
*.db develop-eggs/
data/customers.db downloads/
data/customers.csv eggs/
docker-compose.yml .eggs/
/data/*.csv lib/
lib64/
parts/
sdist/
var/
wheels/
.installed.cfg
*.egg

View File

@@ -5,6 +5,133 @@ Alle wichtigen Änderungen an diesem Projekt werden in dieser Datei dokumentiert
Das Format basiert auf [Keep a Changelog](https://keepachangelog.com/de/1.0.0/), Das Format basiert auf [Keep a Changelog](https://keepachangelog.com/de/1.0.0/),
und dieses Projekt adhäriert zu [Semantic Versioning](https://semver.org/lang/de/). und dieses Projekt adhäriert zu [Semantic Versioning](https://semver.org/lang/de/).
## [Unreleased]
### Hinzugefügt
- CSV-Export-Funktion für Suchergebnisse
- Export-Button in der Benutzeroberfläche
- Automatische Formatierung der CSV-Datei mit allen relevanten Kundendaten
## [1.2.16] - 2024-03-21
### Geändert
- Verbesserte Suchfunktion: Highlighting für allgemeine Suche in allen Feldern
- Optimierte Reset-Buttons in den Suchfeldern
- Verbesserte CSS-Styles für die Suchfeld-Icons
## [1.2.15] - 2024-03-20
### Hinzugefügt
- Autovervollständigung für das Ort-Feld
- Neue API-Route für Ortsvorschläge
- Optimierte SQL-Abfragen für die Ortssuche
## [1.2.14] - 2024-03-20
### Hinzugefügt
- Autovervollständigung für das Fachrichtungsfeld
- Neue API-Route für Fachrichtungsvorschläge
- Optimierte SQL-Abfragen für die Fachrichtungssuche
## [1.2.13] - 2024-03-20
### Fixed
- Korrektur der Parameteranzahl in der SQL-Abfrage für die allgemeine Suche
- Behebung des Fehlers bei der Suche in allen Datenbankfeldern
## [v1.2.12] - 2024-03-19
### Geändert
- Performance-Optimierung der Suchfunktion durch Reduzierung der Suchfelder
- Verbesserte Suchgeschwindigkeit durch LIMIT in SQL-Abfragen
- Optimiertes Debounce-Intervall für Live-Suche
- Verbessertes Highlighting für Teilstrings in Suchergebnissen
## [v1.2.11] - 2024-03-19
### Geändert
- Einträge mit der Fachrichtung "intern" werden aus den Suchergebnissen gefiltert
- Verbesserte SQL-Abfrage für die Suchergebnisse
## [v1.2.10] - 2024-03-19
### Geändert
- Verbesserte Darstellung der Adress-Links mit Location- und Route-Icons
- Korrektur des Docker-Port-Mappings für bessere Erreichbarkeit
## [v1.2.9] - 2024-03-19
### Geändert
- Verbesserte Darstellung der Adress-Links mit Location- und Route-Icons
- Korrektur des Docker-Port-Mappings für bessere Erreichbarkeit
## [v1.2.8] - 2024-03-19
### Geändert
- Verbesserte Tag-Anzeige: Badge neben dem Teilen-Button mit farblicher Hervorhebung (blau für MEDISOFT, orange für MEDICONSULT)
## [v1.2.7] - 2024-03-19
### Geändert
- Korrektur der Feldreihenfolge in den Suchergebnissen
- Verbesserung der Tag-Anzeige
## [v1.2.6] - 2024-03-19
### Geändert
- Verbesserte Darstellung der Kundennummern in den Suchergebnissen
- Optimierte Anzeige der Kundennummern in der Detailansicht
- Anpassung der Kundennummernberechnung für die MEDISOFT-Integration
- Verbesserte Formatierung der Kundennummern in der Benutzeroberfläche
## [v1.2.5] - 2024-03-19
### Geändert
- Verbesserte Darstellung der Kundennummern in den Suchergebnissen
- Optimierte Anzeige der Kundennummern in der Detailansicht
- Anpassung der Kundennummernberechnung für die MEDISOFT-Integration
- Verbesserte Formatierung der Kundennummern in der Benutzeroberfläche
## [v1.2.4] - 2024-03-19
### Geändert
- Verbesserte Darstellung der Kundennummern in den Suchergebnissen
- Optimierte Anzeige der Kundennummern in der Detailansicht
- Anpassung der Kundennummernberechnung für die MEDISOFT-Integration
- Verbesserte Formatierung der Kundennummern in der Benutzeroberfläche
## [v1.2.3] - 2024-03-19
### Geändert
- Verbesserte Darstellung der Kundennummern in den Suchergebnissen
- Optimierte Anzeige der Kundennummern in der Detailansicht
- Anpassung der Kundennummernberechnung für die MEDISOFT-Integration
- Verbesserte Formatierung der Kundennummern in der Benutzeroberfläche
## [v1.2.2] - 2024-03-19
### Geändert
- Verbesserte Darstellung der Kundennummern in den Suchergebnissen
- Optimierte Anzeige der Kundennummern in der Detailansicht
- Anpassung der Kundennummernberechnung für die MEDISOFT-Integration
- Verbesserte Formatierung der Kundennummern in der Benutzeroberfläche
## [v1.2.1] - 2024-03-19
### Geändert
- Verbesserte Darstellung der Kundennummern in den Suchergebnissen
- Optimierte Anzeige der Kundennummern in der Detailansicht
- Anpassung der Kundennummernberechnung für die MEDISOFT-Integration
- Verbesserte Formatierung der Kundennummern in der Benutzeroberfläche
## [v1.2.0] - 2024-03-19
### Hinzugefügt
- Neue Spalte "Tag" in der Kundendatenbank
- Unterscheidung zwischen MEDISOFT und MEDICONSULT Kunden
- Filteroption für die Anzeige von MEDISOFT oder MEDICONSULT Kunden
- Verbesserte Darstellung der Kundennummern in den Suchergebnissen
- Optimierte Anzeige der Kundennummern in der Detailansicht
- Anpassung der Kundennummernberechnung für die MEDISOFT-Integration
- Verbesserte Formatierung der Kundennummern in der Benutzeroberfläche
## [v1.1.0] - 2024-03-19
### Hinzugefügt
- Neue Spalte "Tag" in der Kundendatenbank
- Unterscheidung zwischen MEDISOFT und MEDICONSULT Kunden
- Filteroption für die Anzeige von MEDISOFT oder MEDICONSULT Kunden
## [v1.0.0] - 2024-03-19
### Hinzugefügt
- Erste Version der Anwendung
- Grundlegende Suchfunktionalität
- Anzeige von Kundendetails
- Integration mit MEDISOFT
- Responsive Design
- IP-basierte Zugriffskontrolle
## [1.2.6] - 2024-03-19 ## [1.2.6] - 2024-03-19
### Geändert ### Geändert
- Verbesserte Suchfunktion: Keine Ergebnisse mehr bei leeren Suchfeldern - Verbesserte Suchfunktion: Keine Ergebnisse mehr bei leeren Suchfeldern
@@ -84,4 +211,11 @@ und dieses Projekt adhäriert zu [Semantic Versioning](https://semver.org/lang/d
- Echtzeit-Suche über Kundendaten - Echtzeit-Suche über Kundendaten
- Hervorhebung von Suchbegriffen in den Ergebnissen - Hervorhebung von Suchbegriffen in den Ergebnissen
- Klickbare Links für Telefonnummern, E-Mail-Adressen und Adressen - Klickbare Links für Telefonnummern, E-Mail-Adressen und Adressen
- Docker-Container für einfache Installation und Deployment - Docker-Container für einfache Installation und Deployment
## [1.2.19] - 2024-03-19
### Geändert
- Version auf 1.2.19 aktualisiert
## [1.2.18] - 2024-03-19
# ... existing code ...

100
README.md
View File

@@ -1,35 +1,54 @@
# Medi-Customers # medisoftware Kundensuche
Eine Flask-basierte Webanwendung zur Verwaltung von Kundenkontakten für medizinische Einrichtungen. Eine einfache und effiziente Kundensuche für medisoftware Kunden.
## Features ## Features
- Kundensuche nach verschiedenen Kriterien (Name, Ort, Kundennummer, etc.) - 🔍 Echtzeit-Suche über alle Kundendaten
- Direkte Links zu Kundendaten in medisoftware (für autorisierte IPs) - 📱 Responsive Design für alle Geräte
- Telefonnummern-Links für autorisierte IPs - 🔒 IP-basierte Zugriffskontrolle
- Adress-Links mit Google Maps Integration - 🔗 Direkte Integration mit MEDISOFT
- IP-basierte Zugriffssteuerung - 🏥 Unterscheidung zwischen MEDISOFT und MEDICONSULT Kunden
- Responsive Design - 🎨 Farbliche Hervorhebung der Kundentypen (blau für MEDISOFT, orange für MEDICONSULT)
- 📍 Verbesserte Adress-Links mit Location- und Route-Icons
- 📤 CSV-Export der Suchergebnisse
- 📥 CSV-Import für Kundendaten
- 📖 Integrierte README-Anzeige
- 🍔 Intuitives Hamburger-Menü
- 📱 VCF-Export für Kontakte
## Version
Aktuelle Version: 1.2.19
## Installation ## Installation
1. Repository klonen: 1. Klonen Sie das Repository:
```bash ```bash
git clone https://gitea.elpatron.me/elpatron/medi-customers.git git clone https://gitea.elpatron.me/elpatron/medi-customers.git
cd medi-customers cd medi-customers
``` ```
2. Umgebungsvariablen einrichten: 2. Erstellen Sie die erforderlichen Verzeichnisse:
```bash ```bash
cp .env.example .env mkdir -p data
# Bearbeiten Sie die .env-Datei mit Ihren Einstellungen
``` ```
3. Docker Container starten: 3. Starten Sie die Anwendung mit Docker Compose:
```bash ```bash
docker-compose up -d docker-compose up --build
``` ```
Die Anwendung ist dann unter `http://localhost:5000` erreichbar.
## Entwicklung
Die Anwendung ist in Python mit Flask entwickelt und verwendet SQLite als Datenbank. Das Frontend wurde mit HTML, CSS und JavaScript implementiert.
## Lizenz
Alle Rechte vorbehalten. © 2024 medisoftware
## Konfiguration ## Konfiguration
Die Anwendung kann über folgende Umgebungsvariablen konfiguriert werden: Die Anwendung kann über folgende Umgebungsvariablen konfiguriert werden:
@@ -38,7 +57,8 @@ Die Anwendung kann über folgende Umgebungsvariablen konfiguriert werden:
- `FLASK_ENV`: Die Flask-Umgebung (development/production) - `FLASK_ENV`: Die Flask-Umgebung (development/production)
- `SECRET_KEY`: Der geheime Schlüssel für Flask-Sessions - `SECRET_KEY`: Der geheime Schlüssel für Flask-Sessions
- `DATABASE_URL`: Die URL zur SQLite-Datenbank - `DATABASE_URL`: Die URL zur SQLite-Datenbank
- `STATIC_PASSWORD`: Das Passwort für die Login-Seite - `LOGIN_PASSWORD`: Das Passwort für die Login-Seite
- `UPLOAD_PASSWORD`: Das Passwort für den CSV-Upload
- `ALLOWED_IP_RANGES`: Komma-getrennte Liste von IP-Bereichen, die direkten Zugriff haben - `ALLOWED_IP_RANGES`: Komma-getrennte Liste von IP-Bereichen, die direkten Zugriff haben
- `LOG_LEVEL`: Das Logging-Level (INFO/DEBUG) - `LOG_LEVEL`: Das Logging-Level (INFO/DEBUG)
@@ -49,14 +69,6 @@ Die Anwendung unterstützt CIDR-Notation für IP-Bereiche. Beispiele:
- Subnetz: 192.168.1.0/24 - Subnetz: 192.168.1.0/24
- Größeres Netzwerk: 10.0.0.0/8 - Größeres Netzwerk: 10.0.0.0/8
## Version
Aktuelle Version: v1.2.6
## Lizenz
Alle Rechte vorbehalten. © 2025 medisoftware
## API-Beispiele ## API-Beispiele
### Suche nach Name ### Suche nach Name
@@ -101,6 +113,46 @@ curl "http://localhost:5001/search?name=Mustermann&telefon=030"
curl "http://localhost:5001/search?fachrichtung=Zahnarzt&ort=Berlin&name=Schmidt" curl "http://localhost:5001/search?fachrichtung=Zahnarzt&ort=Berlin&name=Schmidt"
``` ```
## Benutzeroberfläche
### Hauptmenü
- Home: Zurück zur Hauptseite
- CSV-Dateien hochladen: Import neuer Kundendaten
- README: Anzeige der Dokumentation
### Suchfunktionen
- Allgemeine Suche über alle Felder
- Spezifische Suche nach:
- Name
- Ort
- Kundennummer
- PLZ
- Fachrichtung
- Filterung nach Kundentyp (MEDISOFT/MEDICONSULT)
### Export
- CSV-Export der Suchergebnisse
- VCF-Export für Kontakte
- Direkte Links zu Kundendetails
- Teilen von Suchergebnissen
## Version ## Version
Aktuelle Version: [v1.2.4](CHANGELOG.md#v124---2024-03-19) Aktuelle Version: [v1.2.17](CHANGELOG.md#v1217---2024-03-19)
## Code-Statistiken
Language|files|blank|comment|code
:-------|-------:|-------:|-------:|-------:
JavaScript|1|67|28|420
HTML|4|16|0|382
CSS|1|63|0|324
Markdown|2|77|0|295
YAML|1|0|0|14
Dockerfile|1|8|9|11
Text|1|0|0|6
--------|--------|--------|--------|--------
SUM:|12|302|163|1732
## Lizenz
Alle Rechte vorbehalten. © 2025 medisoftware

721
app.py
View File

@@ -5,277 +5,198 @@ import logging
import numpy as np import numpy as np
from datetime import datetime, timedelta from datetime import datetime, timedelta
from dotenv import load_dotenv from dotenv import load_dotenv
import requests
from collections import defaultdict
import ipaddress
import csv
import sqlite3 import sqlite3
from functools import wraps from functools import wraps
from contextlib import contextmanager
import time
import threading
import markdown2
app = Flask(__name__, static_folder='static') app = Flask(__name__, static_folder='static')
app.secret_key = os.getenv('SECRET_KEY', 'default-secret-key') app.config['SECRET_KEY'] = os.environ.get('SECRET_KEY', 'dev')
app.config['ALLOWED_IP_RANGES'] = os.getenv('ALLOWED_IP_RANGES', '192.168.0.0/16,10.0.0.0/8').split(',')
app.config['VERSION'] = '1.2.19'
app.config['DATABASE'] = 'data/customers.db'
app.config['DATABASE_TIMEOUT'] = 20
app.config['DATABASE_POOL_SIZE'] = 5
logging.basicConfig(level=logging.INFO) logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
# Version der Anwendung # Thread-lokaler Speicher für Datenbankverbindungen
VERSION = "1.2.1" thread_local = threading.local()
# Pfad zur Datenbank
DB_FILE = 'data/customers.db'
# Lade Umgebungsvariablen
load_dotenv()
# Statisches Passwort aus der .env Datei
STATIC_PASSWORD = os.getenv('LOGIN_PASSWORD', 'default-password')
ALLOWED_IP_RANGES = os.getenv('ALLOWED_IP_RANGES', '').split(',')
def get_db_connection(): def get_db_connection():
"""Erstellt eine neue Datenbankverbindung mit Timeout""" """Erstellt eine neue Datenbankverbindung für den aktuellen Thread"""
conn = sqlite3.connect(DB_FILE, timeout=20) if not hasattr(thread_local, "connection"):
conn.row_factory = sqlite3.Row thread_local.connection = sqlite3.connect(app.config['DATABASE'], timeout=app.config['DATABASE_TIMEOUT'])
return conn thread_local.connection.row_factory = sqlite3.Row
return thread_local.connection
@contextmanager
def get_db():
"""Context Manager für Datenbankverbindungen"""
conn = get_db_connection()
try:
yield conn
except Exception:
conn.rollback()
raise
finally:
conn.commit()
def init_db(): def init_db():
"""Initialisiert die SQLite-Datenbank mit der notwendigen Tabelle.""" """Initialisiert die SQLite-Datenbank mit der notwendigen Tabelle."""
conn = get_db_connection() with get_db() as conn:
c = conn.cursor() c = conn.cursor()
try:
# Erstelle die Kunden-Tabelle
c.execute('''
CREATE TABLE IF NOT EXISTS customers (
id INTEGER PRIMARY KEY AUTOINCREMENT,
nummer TEXT,
name TEXT,
strasse TEXT,
plz TEXT,
ort TEXT,
telefon TEXT,
mobil TEXT,
email TEXT,
bemerkung TEXT,
fachrichtung TEXT,
tag TEXT,
handy TEXT,
tele_firma TEXT,
kontakt1 TEXT,
kontakt2 TEXT,
kontakt3 TEXT
)
''')
# Optimierte Indizes für die häufigsten Suchanfragen
c.execute('CREATE INDEX IF NOT EXISTS idx_customers_name_ort ON customers(name, ort)')
c.execute('CREATE INDEX IF NOT EXISTS idx_customers_fachrichtung ON customers(fachrichtung)')
c.execute('CREATE INDEX IF NOT EXISTS idx_customers_tag ON customers(tag)')
c.execute('CREATE INDEX IF NOT EXISTS idx_customers_plz ON customers(plz)')
# Zusammengesetzter Index für die häufigste Suchkombination
c.execute('CREATE INDEX IF NOT EXISTS idx_customers_search ON customers(name, ort, fachrichtung, tag)')
logger.info('Datenbank initialisiert')
except Exception as e:
logger.error(f'Fehler bei der Datenbankinitialisierung: {str(e)}')
raise
def isIPInSubnet(ip, subnet):
"""Überprüft, ob eine IP-Adresse in einem Subnetz liegt."""
try: try:
# Erstelle die Kunden-Tabelle # Teile die IP und das Subnetz in ihre Komponenten
c.execute(''' subnet_ip, bits = subnet.split('/')
CREATE TABLE IF NOT EXISTS customers ( ip_parts = [int(x) for x in ip.split('.')]
id INTEGER PRIMARY KEY AUTOINCREMENT, subnet_parts = [int(x) for x in subnet_ip.split('.')]
nummer TEXT,
name TEXT,
strasse TEXT,
plz TEXT,
ort TEXT,
telefon TEXT,
mobil TEXT,
email TEXT,
bemerkung TEXT,
fachrichtung TEXT,
tag TEXT
)
''')
# Erstelle Indizes für alle Suchfelder # Konvertiere IPs in 32-bit Zahlen
c.execute('CREATE INDEX IF NOT EXISTS idx_customers_nummer ON customers(nummer)') ip_num = (ip_parts[0] << 24) | (ip_parts[1] << 16) | (ip_parts[2] << 8) | ip_parts[3]
c.execute('CREATE INDEX IF NOT EXISTS idx_customers_name ON customers(name)') subnet_num = (subnet_parts[0] << 24) | (subnet_parts[1] << 16) | (subnet_parts[2] << 8) | subnet_parts[3]
c.execute('CREATE INDEX IF NOT EXISTS idx_customers_strasse ON customers(strasse)')
c.execute('CREATE INDEX IF NOT EXISTS idx_customers_plz ON customers(plz)')
c.execute('CREATE INDEX IF NOT EXISTS idx_customers_ort ON customers(ort)')
c.execute('CREATE INDEX IF NOT EXISTS idx_customers_telefon ON customers(telefon)')
c.execute('CREATE INDEX IF NOT EXISTS idx_customers_mobil ON customers(mobil)')
c.execute('CREATE INDEX IF NOT EXISTS idx_customers_email ON customers(email)')
c.execute('CREATE INDEX IF NOT EXISTS idx_customers_fachrichtung ON customers(fachrichtung)')
c.execute('CREATE INDEX IF NOT EXISTS idx_customers_tag ON customers(tag)')
# Erstelle einen zusammengesetzten Index für die häufigste Suchkombination # Erstelle die Subnetzmaske
c.execute('CREATE INDEX IF NOT EXISTS idx_customers_name_ort ON customers(name, ort)') mask = ~((1 << (32 - int(bits))) - 1)
conn.commit() # Prüfe, ob die IP im Subnetz liegt
logger.info('Datenbank initialisiert') return (ip_num & mask) == (subnet_num & mask)
except Exception as e: except Exception as e:
logger.error(f'Fehler bei der Datenbankinitialisierung: {str(e)}') logger.error(f"Fehler bei der IP-Überprüfung: {str(e)}")
raise return False
finally:
conn.close()
def import_csv(): def import_csv():
"""Importiert die CSV-Datei in die Datenbank""" """Importiert die CSV-Datei in die Datenbank"""
conn = None
try: try:
conn = get_db_connection() with get_db() as conn:
c = conn.cursor() c = conn.cursor()
# Lösche bestehende Daten
c.execute('DELETE FROM customers')
# Importiere MEDISOFT-Daten
if os.path.exists('data/customers.csv'):
logger.info("Importiere MEDISOFT-Daten...")
df = pd.read_csv('data/customers.csv', encoding='utf-8')
df.columns = df.columns.str.strip().str.replace('"', '')
df = df.apply(lambda x: x.str.strip().str.replace('"', '') if x.dtype == "object" else x)
df['name'] = df['Vorname'] + ' ' + df['Nachname']
for _, row in df.iterrows(): # Lösche bestehende Daten
c.execute(''' c.execute('DELETE FROM customers')
INSERT INTO customers (name, nummer, strasse, plz, ort, telefon, mobil, email, fachrichtung, tag)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
''', (row['name'], row['Nummer'], row['Strasse'], row['PLZ'], row['Ort'],
row['Tel'], row['Handy'], row['mail'], row['Fachrichtung'], 'medisoft'))
else:
logger.warning("MEDISOFT CSV-Datei nicht gefunden")
# Importiere MEDICONSULT-Daten
if os.path.exists('data/customers_snk.csv'):
logger.info("Importiere MEDICONSULT-Daten...")
df_snk = pd.read_csv('data/customers_snk.csv', encoding='utf-8')
df_snk.columns = df_snk.columns.str.strip().str.replace('"', '')
df_snk = df_snk.apply(lambda x: x.str.strip().str.replace('"', '') if x.dtype == "object" else x)
df_snk['name'] = df_snk['Vorname'] + ' ' + df_snk['Nachname']
for _, row in df_snk.iterrows(): # Importiere MEDISOFT-Daten
c.execute(''' if os.path.exists('data/customers.csv'):
INSERT INTO customers (name, nummer, strasse, plz, ort, telefon, mobil, email, fachrichtung, tag) logger.info("Importiere MEDISOFT-Daten...")
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) df = pd.read_csv('data/customers.csv', encoding='iso-8859-1')
''', (row['name'], row['Nummer'], row['Strasse'], row['PLZ'], row['Ort'], df.columns = df.columns.str.strip().str.replace('"', '')
row['Tel'], row['Handy'], row['mail'], row['Fachrichtung'], 'mediconsult')) df = df.apply(lambda x: x.str.strip().str.replace('"', '') if x.dtype == "object" else x)
else:
logger.warning("MEDICONSULT CSV-Datei nicht gefunden") # Filtere Datensätze mit Fachrichtung "intern"
df = df[df['Fachrichtung'].str.lower() != 'intern']
conn.commit()
logger.info("CSV-Daten erfolgreich in die Datenbank importiert") # Bereite die Daten für den Batch-Insert vor
data = [(
row['VorNachname'], row['Nummer'], row['Strasse'], row['PLZ'], row['Ort'],
row['Tel'], row['Tel'], row['mail'], row['Fachrichtung'], 'medisoft',
row['Handy'], row['Tele Firma'], row['Kontakt1'], row['Kontakt2'], row['Kontakt3']
) for _, row in df.iterrows()]
# Führe Batch-Insert durch
c.executemany('''
INSERT INTO customers (
name, nummer, strasse, plz, ort, telefon, mobil, email,
fachrichtung, tag, handy, tele_firma, kontakt1, kontakt2, kontakt3
)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
''', data)
else:
logger.warning("MEDISOFT CSV-Datei nicht gefunden")
# Importiere MEDICONSULT-Daten
if os.path.exists('data/customers_snk.csv'):
logger.info("Importiere MEDICONSULT-Daten...")
df_snk = pd.read_csv('data/customers_snk.csv', encoding='iso-8859-1')
df_snk.columns = df_snk.columns.str.strip().str.replace('"', '')
df_snk = df_snk.apply(lambda x: x.str.strip().str.replace('"', '') if x.dtype == "object" else x)
# Filtere Datensätze mit Fachrichtung "intern"
df_snk = df_snk[df_snk['Fachrichtung'].str.lower() != 'intern']
# Bereite die Daten für den Batch-Insert vor
data = [(
row['VorNachname'], row['Nummer'], row['Strasse'], row['PLZ'], row['Ort'],
row['Tel'], row['Tel'], row['mail'], row['Fachrichtung'], 'mediconsult',
row['Handy'], row['Tele Firma'], row['Kontakt1'], row['Kontakt2'], row['Kontakt3']
) for _, row in df_snk.iterrows()]
# Führe Batch-Insert durch
c.executemany('''
INSERT INTO customers (
name, nummer, strasse, plz, ort, telefon, mobil, email,
fachrichtung, tag, handy, tele_firma, kontakt1, kontakt2, kontakt3
)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
''', data)
else:
logger.warning("MEDICONSULT CSV-Datei nicht gefunden")
logger.info("CSV-Daten erfolgreich in die Datenbank importiert")
except Exception as e: except Exception as e:
logger.error(f"Fehler beim Importieren der CSV-Datei: {str(e)}") logger.error(f"Fehler beim Importieren der CSV-Datei: {str(e)}")
raise raise
finally:
if conn:
conn.close()
def search_customers():
try:
q = request.args.get('q', '')
name = request.args.get('name', '')
ort = request.args.get('ort', '')
nummer = request.args.get('nummer', '')
plz = request.args.get('plz', '')
fachrichtung = request.args.get('fachrichtung', '')
operator = request.args.get('operator', 'or')
conn = get_db_connection()
c = conn.cursor()
# Basis-SQL-Query
query = '''
SELECT DISTINCT
c.id,
c.name,
c.nummer,
c.strasse,
c.plz,
c.ort,
c.telefon,
c.mobil,
c.email,
c.fachrichtung,
c.tag
FROM customers c
WHERE 1=1
'''
params = []
# Suchbedingungen
conditions = []
if q:
search_terms = q.split()
if operator == 'and':
for term in search_terms:
conditions.append('''
(c.name LIKE ? OR c.nummer LIKE ? OR c.strasse LIKE ?
OR c.plz LIKE ? OR c.ort LIKE ? OR c.telefon LIKE ?
OR c.mobil LIKE ? OR c.email LIKE ? OR c.fachrichtung LIKE ?
OR c.tag LIKE ?)
''')
params.extend([f'%{term}%'] * 10)
else:
term_conditions = []
for term in search_terms:
term_conditions.append('''
(c.name LIKE ? OR c.nummer LIKE ? OR c.strasse LIKE ?
OR c.plz LIKE ? OR c.ort LIKE ? OR c.telefon LIKE ?
OR c.mobil LIKE ? OR c.email LIKE ? OR c.fachrichtung LIKE ?
OR c.tag LIKE ?)
''')
params.extend([f'%{term}%'] * 10)
conditions.append('(' + ' OR '.join(term_conditions) + ')')
if name:
conditions.append('c.name LIKE ?')
params.append(f'%{name}%')
if ort:
conditions.append('c.ort LIKE ?')
params.append(f'%{ort}%')
if nummer:
conditions.append('c.nummer LIKE ?')
params.append(f'%{nummer}%')
if plz:
conditions.append('c.plz LIKE ?')
params.append(f'%{plz}%')
if fachrichtung:
conditions.append('c.fachrichtung LIKE ?')
params.append(f'%{fachrichtung}%')
if conditions:
query += ' AND ' + ' AND '.join(conditions)
c.execute(query, params)
results = c.fetchall()
# Formatiere die Ergebnisse
formatted_results = []
for row in results:
customer = {
'id': row[0],
'name': row[1],
'nummer': row[2],
'strasse': row[3],
'plz': row[4],
'ort': row[5],
'telefon': row[6],
'mobil': row[7],
'email': row[8],
'fachrichtung': row[9],
'tag': row[10]
}
formatted_results.append(customer)
conn.close()
return jsonify(formatted_results)
except Exception as e:
logger.error(f"Fehler bei der Suche: {str(e)}")
return jsonify({'error': str(e)}), 500
def clean_dataframe(df):
"""Konvertiert NaN-Werte in None für JSON-Kompatibilität"""
return df.replace({np.nan: None})
@app.route('/login', methods=['GET', 'POST']) @app.route('/login', methods=['GET', 'POST'])
def login(): def login():
# Versuche, die tatsächliche Client-IP aus dem X-Forwarded-For-Header zu erhalten # Überprüfe, ob die Client-IP in einem der erlaubten Bereiche liegt
client_ip = request.headers.get('X-Forwarded-For', request.remote_addr) client_ip = request.headers.get('X-Forwarded-For', request.remote_addr)
allowed_ip_ranges = os.getenv('ALLOWED_IP_RANGES', '').split(',')
# Überprüfe, ob die Client-IP in einem der erlaubten Bereichen liegt
logger.info(f"Client-IP: {client_ip}") is_allowed = any(isIPInSubnet(client_ip, range.strip()) for range in app.config['ALLOWED_IP_RANGES'] if range.strip())
logger.info(f"Erlaubte IP-Bereiche: {allowed_ip_ranges}")
logger.info(f"Session Status: {session}") if is_allowed:
logger.info(f"Client-IP {client_ip} ist in einem erlaubten Bereich, automatischer Login")
# Überprüfen, ob die IP-Adresse in einem der erlaubten Subnetze liegt session['logged_in'] = True
client_ip_obj = ipaddress.ip_address(client_ip) return redirect(url_for('index'))
for ip_range in allowed_ip_ranges:
try:
network = ipaddress.ip_network(ip_range.strip(), strict=False)
logger.info(f"Überprüfe Netzwerk: {network}")
if client_ip_obj in network:
logger.info("Client-IP ist im erlaubten Bereich.")
session['logged_in'] = True
session.permanent = True # Session bleibt bestehen
return redirect(url_for('index'))
except ValueError:
logger.error(f"Ungültiges Netzwerkformat: {ip_range}")
if request.method == 'POST': if request.method == 'POST':
password = request.form.get('password') password = request.form.get('password')
logger.info(f"Login-Versuch mit Passwort: {'*' * len(password) if password else 'None'}") if password == os.environ.get('LOGIN_PASSWORD'):
if password == STATIC_PASSWORD:
session['logged_in'] = True session['logged_in'] = True
session.permanent = True # Session bleibt bestehen logger.info("Erfolgreicher Login")
logger.info("Login erfolgreich, Session gesetzt")
return redirect(url_for('index')) return redirect(url_for('index'))
else: else:
logger.warning("Falsches Passwort eingegeben") logger.warning("Falsches Passwort eingegeben")
@@ -291,146 +212,240 @@ def index():
logger.info("Benutzer nicht eingeloggt, Weiterleitung zum Login") logger.info("Benutzer nicht eingeloggt, Weiterleitung zum Login")
return redirect(url_for('login')) return redirect(url_for('login'))
allowed_ip_ranges = os.getenv('ALLOWED_IP_RANGES', '')
client_ip = request.headers.get('X-Forwarded-For', request.remote_addr) client_ip = request.headers.get('X-Forwarded-For', request.remote_addr)
logger.info(f"Client-IP: {client_ip}") logger.info(f"Client-IP: {client_ip}")
logger.info(f"Erlaubte IP-Bereiche: {allowed_ip_ranges}") logger.info(f"Erlaubte IP-Bereiche: {app.config['ALLOWED_IP_RANGES']}")
return render_template('index.html', allowed_ip_ranges=allowed_ip_ranges) return render_template('index.html', allowed_ip_ranges=','.join(app.config['ALLOWED_IP_RANGES']), version=app.config['VERSION'])
@app.route('/search', methods=['GET', 'POST']) @app.route('/search', methods=['GET', 'POST'])
def search_customers(): def search():
if not session.get('logged_in'):
return jsonify({'error': 'Nicht eingeloggt'}), 401
try: try:
if request.method == 'POST': if request.method == 'POST':
data = request.get_json() data = request.get_json()
query = data.get('query', '') search_query = data.get('query', '')
tag = data.get('tag', 'medisoft') tag = data.get('tag', 'medisoft')
else: else:
query = request.args.get('q', '') search_query = request.args.get('q', '')
name = request.args.get('name', '') name = request.args.get('name', '')
ort = request.args.get('ort', '') ort = request.args.get('ort', '')
nummer = request.args.get('nummer', '') nummer = request.args.get('nummer', '')
plz = request.args.get('plz', '') plz = request.args.get('plz', '')
fachrichtung = request.args.get('fachrichtung', '') fachrichtung = request.args.get('fachrichtung', '')
operator = request.args.get('operator', 'or')
tag = request.args.get('tag', 'medisoft') tag = request.args.get('tag', 'medisoft')
conn = get_db_connection() with get_db() as conn:
c = conn.cursor() c = conn.cursor()
# Basis-SQL-Query # Baue die SQL-Abfrage
sql = ''' sql_query = '''
SELECT SELECT
c.nummer, nummer,
c.name, name,
c.strasse, strasse,
c.plz, plz,
c.ort, ort,
c.telefon, telefon,
c.mobil, mobil,
c.email, email,
c.fachrichtung, fachrichtung,
c.tag, tag,
CASE handy,
WHEN c.tag = 'medisoft' THEN 'MEDISOFT' tele_firma,
WHEN c.tag = 'mediconsult' THEN 'MEDICONSULT' kontakt1,
ELSE c.tag kontakt2,
END as formatted_tag kontakt3
FROM customers c FROM customers
WHERE 1=1 WHERE 1=1
''' '''
params = [] params = []
if request.method == 'POST': # Füge die Suchbedingungen hinzu
if query: if search_query:
sql += ''' AND ( # Optimierte Suche mit FTS (Full Text Search)
c.name LIKE ? OR sql_query += """
c.nummer LIKE ? OR AND (
c.strasse LIKE ? OR name LIKE ? OR
c.plz LIKE ? OR nummer LIKE ? OR
c.ort LIKE ? OR fachrichtung LIKE ? OR
c.telefon LIKE ? OR ort LIKE ? OR
c.mobil LIKE ? OR plz LIKE ? OR
c.email LIKE ? OR strasse LIKE ? OR
c.fachrichtung LIKE ? telefon LIKE ? OR
)''' mobil LIKE ? OR
search_pattern = f'%{query}%' email LIKE ? OR
params.extend([search_pattern] * 9) bemerkung LIKE ? OR
else: tag LIKE ? OR
# Suchbedingungen für GET-Request handy LIKE ? OR
conditions = [] tele_firma LIKE ? OR
if query: kontakt1 LIKE ? OR
search_terms = query.split() kontakt2 LIKE ? OR
if operator == 'and': kontakt3 LIKE ?
for term in search_terms: )
conditions.append(''' """
(c.name LIKE ? OR c.nummer LIKE ? OR c.strasse LIKE ? search_term = f"%{search_query}%"
OR c.plz LIKE ? OR c.ort LIKE ? OR c.telefon LIKE ? params.extend([search_term] * 16) # 16 Felder für die allgemeine Suche
OR c.mobil LIKE ? OR c.email LIKE ? OR c.fachrichtung LIKE ?)
''')
params.extend([f'%{term}%'] * 9)
else:
term_conditions = []
for term in search_terms:
term_conditions.append('''
(c.name LIKE ? OR c.nummer LIKE ? OR c.strasse LIKE ?
OR c.plz LIKE ? OR c.ort LIKE ? OR c.telefon LIKE ?
OR c.mobil LIKE ? OR c.email LIKE ? OR c.fachrichtung LIKE ?)
''')
params.extend([f'%{term}%'] * 9)
conditions.append('(' + ' OR '.join(term_conditions) + ')')
if name: if name:
conditions.append('c.name LIKE ?') sql_query += " AND name LIKE ?"
params.append(f'%{name}%') params.append(f"%{name}%")
if ort: if ort:
conditions.append('c.ort LIKE ?') sql_query += " AND ort LIKE ?"
params.append(f'%{ort}%') params.append(f"%{ort}%")
if nummer: if nummer:
conditions.append('c.nummer LIKE ?') sql_query += " AND nummer LIKE ?"
params.append(f'%{nummer}%') params.append(f"%{nummer}%")
if plz: if plz:
conditions.append('c.plz LIKE ?') sql_query += " AND plz LIKE ?"
params.append(f'%{plz}%') params.append(f"%{plz}%")
if fachrichtung: if fachrichtung:
conditions.append('c.fachrichtung LIKE ?') sql_query += " AND fachrichtung LIKE ?"
params.append(f'%{fachrichtung}%') params.append(f"%{fachrichtung}%")
if conditions: # Filter nach Tag
sql += ' AND ' + ' AND '.join(conditions) if tag != 'all':
sql_query += " AND tag = ?"
# Füge Tag-Filter hinzu, wenn nicht 'all' ausgewählt ist params.append(tag)
if tag != 'all':
sql += ' AND c.tag = ?'
params.append(tag)
sql += ' ORDER BY c.name' # Füge LIMIT hinzu und optimiere die Sortierung
sql_query += " ORDER BY name LIMIT 100"
c.execute(sql, params)
results = c.fetchall() # Führe die Abfrage aus
c.execute(sql_query, params)
formatted_results = [] results = c.fetchall()
for row in results:
customer = { formatted_results = []
'nummer': row[0], for row in results:
'name': row[1], customer = {
'strasse': row[2], 'nummer': row[0],
'plz': row[3], 'name': row[1],
'ort': row[4], 'strasse': row[2],
'telefon': row[5], 'plz': row[3],
'mobil': row[6], 'ort': row[4],
'email': row[7], 'telefon': row[5],
'fachrichtung': row[8], 'mobil': row[6],
'tag': row[10] # Verwende den formatierten Tag 'email': row[7],
} 'fachrichtung': row[8],
formatted_results.append(customer) 'tag': row[9],
'handy': row[10],
'tele_firma': row[11],
'kontakt1': row[12],
'kontakt2': row[13],
'kontakt3': row[14]
}
formatted_results.append(customer)
return jsonify(formatted_results)
conn.close()
return jsonify(formatted_results)
except Exception as e: except Exception as e:
print(f"Fehler bei der Suche: {str(e)}") logger.error(f"Fehler bei der Suche: {str(e)}")
return jsonify({'error': str(e)}), 500 return jsonify({'error': str(e)}), 500
@app.route('/api/fachrichtungen')
def get_fachrichtungen():
try:
search_term = request.args.get('q', '').lower()
with get_db() as conn:
c = conn.cursor()
# Hole alle eindeutigen Fachrichtungen, die mit dem Suchbegriff übereinstimmen
c.execute('''
SELECT DISTINCT fachrichtung
FROM customers
WHERE fachrichtung IS NOT NULL
AND fachrichtung != ''
AND LOWER(fachrichtung) LIKE ?
ORDER BY fachrichtung
LIMIT 10
''', (f'%{search_term}%',))
fachrichtungen = [row[0] for row in c.fetchall()]
return jsonify(fachrichtungen)
except Exception as e:
logger.error(f"Fehler beim Abrufen der Fachrichtungen: {str(e)}")
return jsonify([])
@app.route('/api/orte')
def get_orte():
try:
search_term = request.args.get('q', '').lower()
with get_db() as conn:
c = conn.cursor()
# Hole alle eindeutigen Orte, die mit dem Suchbegriff übereinstimmen
c.execute('''
SELECT DISTINCT ort
FROM customers
WHERE ort IS NOT NULL
AND ort != ''
AND LOWER(ort) LIKE ?
ORDER BY ort
LIMIT 10
''', (f'%{search_term}%',))
orte = [row[0] for row in c.fetchall()]
return jsonify(orte)
except Exception as e:
logger.error(f"Fehler beim Abrufen der Orte: {str(e)}")
return jsonify([])
@app.route('/upload', methods=['GET', 'POST'])
def upload():
if not session.get('logged_in'):
return redirect(url_for('login'))
if request.method == 'POST':
if request.form.get('password') != os.environ.get('UPLOAD_PASSWORD'):
return render_template('upload.html', error="Falsches Passwort", version=app.config['VERSION'])
if 'customers_snk' not in request.files or 'customers' not in request.files:
return render_template('upload.html', error="Bitte beide CSV-Dateien auswählen", version=app.config['VERSION'])
customers_snk = request.files['customers_snk']
customers = request.files['customers']
if customers_snk.filename == '' or customers.filename == '':
return render_template('upload.html', error="Keine Datei ausgewählt", version=app.config['VERSION'])
if not customers_snk.filename.endswith('.csv') or not customers.filename.endswith('.csv'):
return render_template('upload.html', error="Nur CSV-Dateien sind erlaubt", version=app.config['VERSION'])
try:
# Speichere die Dateien
customers_snk.save('data/customers_snk.csv')
customers.save('data/customers.csv')
# Importiere die Daten in die Datenbank
import_csv('data/customers_snk.csv', 'snk')
import_csv('data/customers.csv', 'medisoft')
return render_template('upload.html', success="Dateien erfolgreich hochgeladen und importiert", version=app.config['VERSION'])
except Exception as e:
logger.error(f"Fehler beim Upload: {str(e)}")
return render_template('upload.html', error=f"Fehler beim Upload: {str(e)}", version=app.config['VERSION'])
return render_template('upload.html', version=app.config['VERSION'])
@app.route('/readme')
def readme():
if not session.get('logged_in'):
return redirect(url_for('login'))
try:
with open('README.md', 'r', encoding='utf-8') as f:
content = f.read()
html_content = markdown2.markdown(content, extras=['fenced-code-blocks', 'tables'])
return render_template('readme.html', content=html_content, version=app.config['VERSION'])
except Exception as e:
logger.error(f"Fehler beim Lesen der README: {str(e)}")
return render_template('readme.html', error="Fehler beim Lesen der README", version=app.config['VERSION'])
def init_app(app): def init_app(app):
"""Initialisiert die Anwendung mit allen notwendigen Einstellungen.""" """Initialisiert die Anwendung mit allen notwendigen Einstellungen."""
with app.app_context(): with app.app_context():
@@ -439,10 +454,10 @@ def init_app(app):
os.makedirs('data', exist_ok=True) os.makedirs('data', exist_ok=True)
# Lösche die alte Datenbank, falls sie existiert # Lösche die alte Datenbank, falls sie existiert
if os.path.exists(DB_FILE): if os.path.exists(app.config['DATABASE']):
try: try:
os.remove(DB_FILE) os.remove(app.config['DATABASE'])
logger.info(f"Alte Datenbank {DB_FILE} wurde gelöscht") logger.info(f"Alte Datenbank {app.config['DATABASE']} wurde gelöscht")
except Exception as e: except Exception as e:
logger.error(f"Fehler beim Löschen der alten Datenbank: {str(e)}") logger.error(f"Fehler beim Löschen der alten Datenbank: {str(e)}")

View File

@@ -1,189 +0,0 @@
"Nummer","Anrede","Vorname","Nachname","Fachrichtung","InstDatum","Strasse","PLZ","Ort","Tel","Fax","mail","Handy","Tele Firma","Kontakt1","Kontakt2","Kontakt3"
"12014","Gemeinschaftspraxis","Dres. med.","Ahnsel/ Tüxen-Ahnsel","Allgemeinmedizin","19.12.2009","Mozartstr. 42","24943","Flensburg","0461/63622","0461/674422","torsten@ahnsel.de","","","","",""
"12166","Herrn","Sven-Oliver Konrad","Alte Rathaus-Apoteke","","15.02.2019","Musbekerweg 1","24955","Harrislee","0461/770099","","","","","","",""
"12046","Herrn","Dr. med. A.","Amran","Allgemeinmedizin","29.06.2010","Hahnweg 24","56242","Selters","026268888","026265878","info@zahnarzt-selters.de","","","","",""
"12167","Herrn","Dr. Kai Chirstiansen","Angler Apotheke","","15.02.2019","Westholmerstraße 3","24972","Steinbergkirche","04632/301","","","","","","",""
"12120","Frau","~","Anlaufpraxis der KVSH","Allgemeinmedizin","21.12.2015","Knuthstr. 1","24939","Flensburg","","","","","","","",""
"12164","Frau","im UKSH Kiel","Apotheke","Apotheke","20.08.2018","Arnold-Heller-Str. 3","24105","Kiel","043126041330","043126041340","info@apotheke-im-uksh-kiel.de","","","www.apotheke-im-uksh-kiel.de","",""
"12168","Frau","Eva Maria Kremer-Dziuron","Apotheke am Freilichtmuseum","","15.02.2019","Am Museum 1a","24113","Molfsee","0431/651488","","","","","","",""
"12160","Frau","St. Michael","Apotheke am Ochsenmarkt","Apotheke","05.02.2018","Am Ochsenmarkt 35","24937","Flensburg","0461/51973","0461/52030","kerstin.tomberger@apotheke-st-michael.de","","","","",""
"12161","Frau","St. Michael","Apotheke im CITTI-PARK","Apotheke","05.02.2018","Langberger Weg 4","24941","Flensburg","0461/99577860","0461/97899436","CITTI@apotheke-st-michael.de","","","","",""
"12113","Herrn","Meine","Apotheke Marienbrunn","Apotheke","21.09.2015","Zwickauer Strasse 99a","04277","Leipzig","0341/8611265","0341/8611267","mail@uwepaepcke.de","","","mail@apotheke-marienbrunn.de","www.apotheke-marienbrunn.de",""
"12198","Herrn","~","Apotheken Wirtschaftsdienst GmbH","","10.09.2019","Steekberg 11","24107","Kiel","","03423/7583791","","","03423/7061519","","",""
"12017","Gemeinschaftspraxis","Dres. med.","Aretz/Winterhoff","Innere Medizin","01.01.2010","Südermarkt 1a","24937","Flensburg","0461/1827804","0461/1827819","","","0461/1827804","","",""
"12010","Frau","Dr. med. Gabriele","Auerbach-Annewanter","Innere Medizin","08.12.2009","Toosbüystr. 4","24939","Flensburg","0461/20204","0461/5057077","auerbach-annewanter@medflug.de","","0461/20204","","",""
"12038","Herrn","Dr. med. S.","Babinsky / Chr. A Mohr","Allgemeinmedizin","30.12.2009","Max-Richter-Str. 2a","24537","Neumünster","04321/853880","04321/8538828","info@praxis-am-kantplatz.de","","04321/8538817","","",""
"12063","Herrn","Dr. med. Michael","Bär","Hautarzt","18.06.2012","Löbauer Str. 17","02625","Bautzen","035912777140","","","","","","",""
"12076","Gemeinschaftspraxis","Dres. med.","Bandick/Lemke/Krüger","Radiologie","31.07.2013","Berliner Allee 40c","22850","Norderstedt","040/5287330","040/52873399","EMAIL@RPXN.DE","","04052385962","","",""
"12021","Herrn","Dr. med. W.","Barchasch","Gynäkologe","22.12.2009","Norongsallee 11","24939","Flensburg","0461/27700","0461/28149","dr.bacco@gmx.de","","0461/27700","","",""
"12047","Herrn","Dr. med. Eberhard","Barth","Innere Medizin","07.09.2010","Hansastr. 2-3","20149","Hamburg","040/456858","040/417346","","","","","",""
"12169","Herrn","Ulrich Grothe","Bergapotheke","","15.02.2019","Am Markt 3","25560","Schenefeld","","","","","","","",""
"12042","Herrn","Michael","Bergeler/G. Pelz-Bergeler","Allgemeinmedizin","05.05.2010","Musbeker Weg 1","24955","Harrislee","046173038","046178873","bergeler_pelz-bergeler@medflug.de","","","","",""
"12101","Herrn","Dipl.-Med. Michael","Beylich","Allgemeinmedizin","27.02.2015","Brückenstr. 33","99955","Bad Tennstedt","036041/57033","","m.beylich@gmail.com","0174/7447780","","036041/42255","praxisbeylich@gmail.com",""
"12170","Herrn","Dr. Kai Christiansen","Birk-Apotheke","","15.02.2019","Nordstraße 2","24395","Gelting","04643/18810","","","","","","",""
"12163","Herrn","~","BITMARCK Service GmbH","","24.07.2018","Kruppstraße 64","45145","Essen","0201/17662463","","","","","","",""
"12132","Herrn","Dr. med. Christoph","Bornhöft","Kinderarzt","04.04.2016","Nibelungenstr. 26","64625","Bensheim","0625172920","","","017672601262","","","",""
"12083","Gemeinschaftspraxis","Dres.med","Bothmann-Graeber/Eggers/Behm","Allgemeinmedizin","05.09.2013","Hebbelstr. 3","24768","Rendsburg","04331/14060","","","","","","",""
"12162","Frau","Dr. med. Susanne","Brenner","Allgemeinmedizin","14.06.2018","Hauptstrasse 100","66583","Spiesen-Elvenberg","06821/9831300","","praxis@bmade.de","0151/56027055","","","",""
"12020","Gemeinschaftspraxis","Dres. med.","Buchholz/ Schulte/Ostermann","Allgemeinmedizin","01.01.2010","Zur Höhe 12","24955","Harrislee","0461/150560","0461/5705218","","","0461/150560","","",""
"12019","Gemeinschaftspraxis","Dres.","Burghoff/v. Carnap-Bornheim/Lammerskitten","Innere Medizin","05.10.2009","Waldstr. 13-15","24939","Flensburg","0461/1683100","0461/16831029","diabetes-zentrum-flensburg@flugmed.de","","015141918161","info-an@dr.robert-winkler.de","c.burghoff@web.de","01746225488 (Carnap)"
"12050","Gemeinschaftspraxis","Dres. med.","Burkert/ Strobach","","08.12.2010","Appenrader Str. 48","24939","Flensburg","0461/41006","","","","","","",""
"12131","Herrn","Winfried","Buß","Orthopädie","30.03.2016","Gerhardstr. 3","24768","Rendsburg","04331/789456","","winfried-buss@web.de","","","","",""
"12081","Frau","Dr. med. Pamela","Deißner","Allgemeinmedizin","05.09.2013","Wennhorn 1a","24816","Hamweddel","04875/1323","04875267","kontakt@praxisdeissner.de","0151535733","","","",""
"12171","Herrn","Gerd Ehmen","Donn-Apotheke","","15.02.2019","Johannßenstraße 2","25693","St. Michaelisdonn","04853460","","","","","","",""
"12086","Herrn","Radiologische Praxis am FEK","Dose/Teufel","Radiologie","15.10.2013","Friesenstr. 11","24534","Neumünster","04321/40910","04321/409121","info@roentgenpraxis-am-fek.de","","","","",""
"12060","Gemeinschaftspraxis","Dres. med. Daniel","Drexler/Lill","Allgemeinmedizin","20.01.2012","Bahnhofstrasse 11","83022","Rosenheim","08031/9412471","","","0151/26338196","","","",""
"12098","Gemeinschaftspraxis","Dres. med.","Eberlein-Riemke/ Laporte","Allgemeinmedizin","01.12.2014","Rathausallee 83F","22846","Norderstedt","04052/66111","","ergs-team@freenet.de","","","","",""
"12210","Herrn","Marcus Hettlage","Element 44","","30.11.2020","Schmiedestraße 11","25899","Niebüll","046619569057","","hettlage@element44.de","01705452248","","","",""
"12152","Herrn","Dr. med. Lars","Emde","Radiologie","22.12.2017","Farmsener Landstr. 193","22359","Hamburg","040/54755080","","","040/54755081","","","",""
"12073","Herrn","GMP für Anästhesie Kiel","Dres. Engel/Rinck/Schele u. Kollegen","Anästhesisten","03.07.2013","Schönberger Str. 11","24148","Kiel","0431/7206522","0431/7206599","rogge@anaesthesie-kiel.de","","0431/7206525","","",""
"12135","Herrn","Priv.-Doz. Dr. med. habil. Peter","Entzian","Innere Medizin","17.06.2016","Kuhberg 28","24534","Neumünster","04321/43621","04321/42444","entzian@lungenarzt-nms.de","0171/6992739","","043219527959 (Schikura)","",""
"12084","Herrn","Dr. med. Matthias","Eppel","Allgemeinmedizin","13.09.2013","Bahnhofstr. 17","24811","Owschlag","043363166","04336999010","info@praxis-owschlag.de","","04336/999011","","",""
"12087","Herrn","~","Evidia MVZ Förderadiologicum GmbH","Radiologie","21.10.2013","Karlstal 32","24143","Kiel","0431/702160","0431/7021619","","","","0171/5180700 Herr Müller","",""
"12143","Frau","Dr. med. Natalie","Fahrenkrog","Gynäkologie","25.10.2016","Blankwasserweg 20","23743","Grömitz","04562/25273","04562/25275","n.fahrenkrog@t-online.de","","","","",""
"12090","Gemeinschaftspraxis","Dres. med.","Falk/Schomburg","","01.01.2014","Seminarweg 4","24837","Schleswig","04621/27027","04621/26074","","0170/5370910","","geheim handy 01577/8930003","",""
"12082","Gemeinschaftspraxis","Dres. med.","Fink/Girma","Urologie","05.09.2013","Bastion 2","24788","Rendsburg","04331/23320","04331/55128","info@urologen-rendsburg.de","0176/24330034","04331/24045","0172/8832839 Dr. Finck","",""
"12172","Frau","Eva Maria Kremer-Dziurom","Fital-Apotheke","","15.02.2019","Posthofstr 4","24321","Lütjenburg","043814040880","","","","","","",""
"12195","Herrn","Jürgen Nolte","Fleethörn-Apotheke","","15.04.2019","Knooper Weg 44","24103","Kiel","0431/554381","","","","","","",""
"12173","Herrn","Sönke Kehrhahn","Flora-Apotheke","","15.02.2019","Schulstraße 25-27","25335","Elmshorn","041214262","","","","","","",""
"12033","Herrn",".","FLUG","","01.01.2010","Dorotheenstr. 6","24939","Flensburg","0461/570520","0461/5705218","","01786963930","0461/570520","","",""
"12174","Frau","Friederike Vogler","Fockbeker Apotheke","","15.02.2019","Rendsburger Str. 19","24787","Fockbek","0433161404","","","","","","",""
"12175","Herrn","Dr. Heinrich Schop","Förde-Apotheke","","15.02.2019","Mürwikerstr. 162","24944","Flensburg","0461314130","","","0171/2146626","","","",""
"12116","Herrn","Martin","Forster","Allgemeinmedizin","29.09.2015","Schwachhauser Heerstraße 167","28211","Bremen","0421/341977","0421/344445","hausarzt-forster@gmx.de","01631599029","","0421/68495400 Privat Dr. Forster und Ehefrau Fr. Broockmann","",""
"12123","Gemeinschaftspraxis","Dres. med.","Forster/Kabelitz","Psychotherapie","14.01.2016","Spitalerstr. 32","20095","Hamburg","040/28059900","","","","","","",""
"12062","Herrn","Dr. med. Daniel","Foss","Internist","08.03.2012","Oberneulander Heerstr. 26-28","28355","Bremen","0421/2053338","0421/2053337","dr.hiho@mac.com","0151/40019890","0421/2053336","","",""
"12069","Herrn","Alexander Selch im","Friedrich-Ebert-Krankenhaus FEK","IT-Abteilung","31.01.2013","Friesenstr. 11","24534","Neumünster","04321/4052031","043214052039","juergen.spanier@fek.de","","","","",""
"12109","Herrn","Dr. med. Jörg","Fuhrberg","Urologe","17.06.2015","Erichsenweg 16","25813","Husum","0461/30550","0461/30615","praxis@dr-fuhrberg.de","0171/1251787","04841/3288","Flensburg@uro-praxis-nord.de","04841/9335045",""
"12040","Frau","Martina","Gaschae","Psychotherapeutin","09.03.2010","Kompagniestr. 9","24937","Flensburg","","","","","","","",""
"12197","Herrn","Karsten","Gebhardt / Jana Klinkicht","","10.09.2019","Am Anger 3","04838","Eilenburg","03423/7061519","","","","","","",""
"12091","Gemeinschaftspraxis","Dres. med.","Gehring /Mansfeld","Innere Medizin","25.03.2014","Berliner Allee 40C","22850","Norderstedt","0405283048","040/51208379","pg@hahc.de","","040/32590369","0157/82022124 Praxishandy","",""
"12102","Herrn","P.","Gernhold/S.Valentin/Dr.M.Stember","Allgemeinmedizin","02.03.2015","Evergerstr. 28-30","51061","Köln-Flittard","0221/662211","02219666319","post@gemeinschaftspraxis-flittard.de","","","","",""
"12151","Herrn","P.","Gernhold/S.Valentin/Dr.M.Stember","","11.12.2017","Oberstr. 10","53859","Niederkassel","02208/1711","02208/8684","","","","","",""
"12194","Herrn","~","GIO","Ärztegemeinschaft","29.03.2019","Schloßplatz 3","24768","Rendsburg","04331/4377600","04331/4376570","m.berges@gioonline.de","","","","",""
"12204","Herrn","185-1.1","gkv informatik","","09.11.2020","Lichtscheider Str. 89","42285","Wuppertal","","","","","","","",""
"12205","Herrn","185-1.2","gkv informatik","","09.11.2020","Lichtscheider Str. 89","42285","Wuppertal","","","","","","","",""
"12206","Herrn","185-2.1","gkv informatik","","09.11.2020","Lichtscheider Str. 89","42285","Wuppertal","","","","","","","",""
"12207","Herrn","185-2.2","gkv informatik","","09.11.2020","Lichtscheider Str. 89","42285","Wuppertal","","","","","","","",""
"12208","Herrn","185-3.1","gkv informatik","","09.11.2020","Lichtscheider Str. 89","42285","Wuppertal","","","","","","","",""
"12209","Herrn","185-3.2","gkv informatik","","09.11.2020","Lichtscheider Str. 89","42285","Wuppertal","","","","","","","",""
"12185","Herrn","~","gkv informatik","privat","19.02.2019","Lichtscheider Str. 89","42285","Wuppertal","020269581201","02026958201201","ronald.laryea@gkvi.de","","","Finanzen@gkvi.de","",""
"12186","Herrn","~","gkv pseudo","privat","20.02.2019","Steinstr 1","24118","Kiel","","","","","","","",""
"12165","Herrn","Informatik","GKVI","","05.02.2019","Lichtscheider Strasse 89","42285","Wuppertal","0202/69581201","","","","","","",""
"12025","Gemeinschaftspraxis","Dres. med.","Görgen-Pauly/Kratzius/Schüren/Schwan","Ki- u. Jugendpsychiater","23.12.2009","St.Annen-Str. 1a","23552","Lübeck","0451/7987077","0451/7987075","info@kjp-Luebeck.de","","0451/7987077","goergen-pauly@kjp-Luebeck.de schueren@kjp-Luebeck.de","neuhauss@kjp-Luebeck.de",""
"12045","Herrn","Dialysezentrum","Gregersen/Lammerskitten","","01.01.2010","Alter Ochsenweg 1","24941","Flensburg","0461/9401594","0461/67422039","","","","","",""
"12176","Herrn","Dr. Heinrich Schop","Grenz-Apotheke","","15.02.2019","Zur Höhle 10","24955","Harrislee","046171359","","","0171/2146626","","","",""
"12095","Herrn","Dr. med. Martin","Gunkel","","21.09.2014","Frankensteiner Str. 28","64319","Pfungstadt","06157/4842","06157/991688","martin@gunkel.net","0179/6721400","","","",""
"12128","Herrn","Dr. med. Martin","Gunkel","Kinderarzt","15.03.2016","Hauptstr. 30","64342","Seeheim-Jugenheim","06257/903275","06257/903277","dr.v.baum@gmx.de","","06257/903276","","",""
"12133","Gemeinschaftspraxis","Dres. med.","Hachmann/ Feil","Kinder- u. Jugendmedizin","06.04.2016","Martinspfad 72","64285","Darmstadt","0615146386","","service@e-kinderaerzte.de","0171/7185207","","","",""
"12043","Gemeinschaftspraxis","Dres. med.","Haferland / Urban","Innere Medizin","20.05.2010","Reichenbacher Str. 106 a","02827","Görlitz","03581/739797","","","","","","",""
"12114","Herrn","Dr. med. J.","Hannappel","Allgemeinmedizin","21.09.2015","Kirchstrasse 12","56333","Winningen","02606/2287","","johannappel@t-online.de","","","","",""
"12015","Gemeinschaftspraxis","Dres. med.","Hansen-Magnusson/Knaut/Kronas","Allgemeinmedizin","29.03.2010","Poststr. 2","24997","Wanderup","04606/227","04606/759","","","04606/2129999","0151/15555353 Praxishandy (in Prx erreichbar)","0170/4839766 Dr Magnusson",""
"12110","Frau","Manuela","Hehemann","Allgemeinmedizin","01.07.2015","Herzbachweg 12","63571","Gelnhausen","06051/888120","06051/888122","manuela.hehemann@freenet.de","0152/04772701","","","",""
"12004","Gemeinschaftspraxis","Dres. med.","Herrberger/Bierwolf","Kieferchirurgen","07.10.2009","An der Obertrave 16a","23552","Lübeck","0451/889010","0451/8890111","info@mkg-holstentor.de","","0451/889010","","",""
"12122","Frau","Dipl.-Psych. Kerstin","Hippius-Schultheß","Psychotherapie","14.01.2016","Dr.-Friedrichs-Ring 55","08056","Zwickau","0375/30359285","0375/30359286","kerstin.hippius@posteo.de","","","","",""
"12140","Frau","Dipl.-Psych. Andrea","Hirschmann","Psychotherapie","20.07.2016","Stormsweg 8","22085","Hamburg","040/2276393","03212/1470998","a@hirschmann-schoen.de","","","","",""
"12177","Herrn","Dr. Peter Froese","Holsten-Apotheke","","15.02.2019","Klas-Groth-Str. 6","24790","Schascht-Audorf","0433194730","","","","","","",""
"12007","Frau","Dr. med. Astrid","Horn","Allgemeinmedizin","25.08.2009","Moltkestr. 20","24937","Flensburg","0461/17908","0461/17909","","","0461/17908","","",""
"12103","Frau","Dipl.-Psych. Imke","Hoyer","Psychotherapie","02.03.2015","Tangstedter Landstr. 516d","22851","Norderstedt","040/35778755","040/35778756","kontakt@psychotherapie-hoyer.de","0162/2308720","","I-hoyer@gmx.net","",""
"12002","Herrn",".","Interessenten","","01.01.2000","Steinstr. 1","24118","Kiel","","","","","","","",""
"12149","Herrn","~","ITSG GmbH","","13.06.2017","Seligenstädter Grund 11","63150","Heusenstamm","06104/60050226","06104/60050300","patrik.bohland@itsg.de","0177/2915142","","","",""
"12066","Herrn","Dr. med. Uwe","Kaeßmann","Unfall-u. Gelenkchirurgie","10.12.2012","Am Krankenhaus 5","24211","Preetz","04342/801211","04342/801489","U.Kaessmann@Klinik-Preetz.de","","","","",""
"12074","Frau","Dr. med. Nora","Kelm","Allgemeinmedizin","08.07.2013","Rendsburger Str. 11","24787","Fockbek","04331/61172","04331/669252","","","","","",""
"12178","Herrn","Hans-Günther Lund","Kgl. priv. Apotheke","","15.02.2019","Markt 1","25917","Leck","046622220","046623054","lund@apotheke-leck.de","","046622220","","",""
"12052","Gemeinschaftspraxis","Dres. med.","Kirsch & Partner","","26.01.2011","Marktpassage 8","21149","Hamburg","040/7017471","040/70380771","","","","","",""
"12130","Frau","Dr. med. Katja","Klenke","Kinderärztin","22.03.2016","Tannenbergstr. 2","64342","Seeheim-Jugenheim","06257/82459","","Klenke.Katja@t-online.de","","","015774205315","",""
"12049","Herrn","Karl- Jürgen","Labor Klos","","08.12.2010","Paul-Ziegler-Str. 1a","24939","Flensburg","0461/503350","0461/5053520","info@labor-klos.de","","","","",""
"12100","Gemeinschaftspraxis","Dres. K.","Kohlsche/G. Reisewitz/E. Glet","Allgemeinmedizin","28.01.2015","Ohechaussee 13","22848","Norderstedt","040/5296888","040/5293063","hausarztpraxis@wtnet.de","","040/52985047","guido.reisewitz@web.de","",""
"12003","Gemeinschaftspraxis","Dres. med","Kraemer/ Schreiber","Allgemeinmedizin","13.07.2009","Carl-Diem-Str. 5","23611","Bad Schwartau","","0451/283996","praxis.kraemer-schreiber@t-online.de","","0451/22776","","",""
"12065","Herrn","Dennis","Kramkowski","Allgemeinmedizin","10.12.2012","Fritz-Reuter-Str. 90","24159","Kiel","0431/39021","0431/393934","praxis@kramkowski.net","0160/97984098","","http://www.kramkowski.net/","",""
"12061","Herrn","Städtisches","Krankenhaus Kiel GmbH","privat","20.01.2012","Chemnitzstr. 33","24116","Kiel","04311697","","systemtechnik@krankenhaus-kiel.de","","","","",""
"12097","Herrn","Labor Dr.","Krause u. Kollegen MVZ GmbH","Labormedizin","24.11.2014","Steenbeker Weg 23","24106","Kiel","0431/22010100","0431/22010109","metzner@labor-krause.de","","","","",""
"12125","Gemeinschaftspraxis","Dres. med.","Kröger und Kollegen","Radiologie","24.02.2016","Wallstraße 40 - 44","24768","Rendsburg","04331/72044","04331/77880","kroeger.s@o2mail.de","","","goettsche@roentgenpraxis-rendsburg.de","Tilo.Engel@smart-it4.com",""
"12138","Herrn","Dr. med. Thorsten","Kummerow","Augenheilkunde","13.07.2016","Schützenstr. 19","24568","Kaltenkirchen","041915143","04191909999","dr.kummerow@t-online.de","0172/5412180","04191/909998","","",""
"12179","Frau","Michaela-Alexandra Banzhaf","Kur-Apotheke","","15.02.2019","Strandstraße 110","23669","Timmendorf Strand","0450389090","","Kur-Apotheke-Niendorf.Timmendorfer-Strand@apotheke-sh.de","","","","",""
"12212","Herrn","~","KVT - Notdienst Service gGmbH","","17.05.2024","Zum Hospitalgraben 8","99425","Weimar","036434950101","","sandra.may@kvt-nd-service.de","","","","",""
"12203","Herrn","~","Labor Mohr","","05.08.2020","Rathausplatz 1","24103","Kiel","0431/978881","0431/978824","hmohr@labormohr.de","","","","",""
"12071","Herrn","Lübeck","Laborärztliche GP","Labormedizin","22.03.2013","Von-Morgen-Str. 3","23564","Lübeck","0451/610900","0451/6109010","andreas.bobrowski@labor-luebeck.de","","","l.sawatzki@labor-luebeck.de","",""
"12108","Herrn","MVZ","LaborDiagnostik Mittelhessen GmbH","","26.05.2015","Ursulum 1","35396","Gießen","0641/300210","0641/30021100","thomas.bender@ldm-labor.de","","","www.ldm-labor.de","",""
"12072","Herrn","Labor","Lademannbogen MVZ GmbH","Labormedizin","15.05.2013","Lademannbogen 61","22339","Hamburg","040538050","","max@labor-lademannbogen.de","","","","",""
"12180","Herrn","Jonas Friedrichson","Lamberti-Apotheke","","15.02.2019","Dithmarscher Weg 9","25866","Mildstedt","048417940","","","","","","",""
"12009","Frau","Carolin","Langhanke","Innere Medizin","01.01.2010","Apenrader Straße 10","24939","Flensburg","04614041","0461/4043","greg.steg@versanet.de","","0461/4041","0171/6834407 Handy Frau Stegmann","",""
"12181","Herrn","Jonas Friedrichson","Linden-Apotheke","","15.02.2019","Parkweg 10~","25821","Breklum","04671943323","","","","","","",""
"12118","Herrn","MVZ","Lubinus GmbH","","09.11.2015","Steenbeker Weg 25","24106","Kiel","04313888123","0431/38881290","j.wilkens@lubinus-stiftung.de","","0431/38882932","","",""
"12137","Gemeinschaftspraxis","Dres. med.","Maier/Georgijewitsch","Orthopädie","12.07.2016","Rödelheimer Bahnweg 21","60489","Frankfurt","069/34875980","069/348759899","","","069/348759816","","",""
"12106","Frau","~","Mammographie-Screening-Hamburg","","11.05.2015","Mönckebergstr. 11","20095","Hamburg","040/471100218","040/471100260","","","040/471100200","","",""
"12093","Herrn","Dr. med. Bernd","Mansfeld","","25.03.2014","Friedrichsgaber Weg 488","22846","Norderstedt","0405222211","","mansfeld@wtnet.de","","040/52610380","","",""
"12032","Gemeinschaftspraxis","Dres. med.","Mantzel/ Storrer-Mantzel","Allgemeinmedizin","17.11.2009","Dr-Behm-Ring 8","24963","Tarp","04638/610","04638/898927","vmantzel@web.de","","04638/610","stomtz@web.de","vo-mantzel@t-online.de",""
"12035","Gemeinschaftspraxis","Dres. med.","Marckmann/Sielmann","Allgemeinmedizin","31.12.2009","Kuhberg 43-45","24534","Neumünster","04321/42320","04321/489918","ute-petersen@gmx.de","0174/8135162","04321/42320","","",""
"12182","Herrn","Karsten Werner","Markt Apotheke","","15.02.2019","Markt 8","25821","Bredstedt","","","","","","","",""
"12183","Herrn","Dr. Peter Froese","Mastbrook Apotheke","","15.02.2019","Ostlandstr 3","24768","Rendsburg","043314705","","","","","","",""
"12008","Herrn","Dirk","Mechler","Allgemeinmedizin","29.09.2009","Meldorfer-Str. 69-71","25746","Heide","0481/62181","0481/61791","info@praxis-hei.de","0176/32747045","0481/62181","","",""
"12139","Herrn","~","medical Wundmanagement Hamburg GmbH","","19.07.2016","Hauptstr. 1a","22962","Siek","04107/9076776","04107/9087888","yannic.wetendorf@medical-wundmanagement.de","","","simon.schintag@medical-wundmanagement.de","",""
"12126","Herrn","Henning","Meyer","Psychiatrie","08.03.2016","Lornsenstr. 18","24768","Rendsburg","04331/4598459","04331/4598458","kontakt@psychiatrie-meyer.de","","","","",""
"12147","Herrn","~","MKG Chirurgie LindenArcarden","Chirurgie","08.05.2017","Fackenburger Allee 1","23554","Lübeck","0451/504910","0451/5049123","","","","","",""
"12184","Herrn","Nicolas Ahlers","Moorbek- Apotheke","","15.02.2019","Rathausallee 35-39","22846","Norderstedt","0405227552","","","","","","",""
"12037","Herrn","Dr. med. W.","Müller/ S. Kiesbye","Innere Medizin","06.10.2009","Marrensdamm 5","24944","Flensburg","0461/37151","0461/37943","w.mueller@kardiologie-flensburg.de","01718261880","0461/37151","","",""
"12200","Herrn","Dr. Benjamin Sattler","MVZ Prüner Gang","","05.03.2020","Prüner Gang 16-20","24103","Kiel","0431974470","04319744715","","","","","",""
"12121","Herrn","Jihad","Nassar","Allgemeinmedizin","04.01.2016","Schweizergasse 2","63486","Bruchköbel","06181/71329","","","","","","",""
"12146","Herrn","HNO med.","Nord","HNO-Ärzte","19.12.2016","Wallstraße 40-44","24768","Rendsburg","0433143460","","","","","","",""
"12005","Herrn","Dr. med. Helmut","Oehne","HNO-Arzt","31.07.2009","Nikolaikirchhof 5","24937","Flensburg","0461/24749","0461/22012","","","0461/24749","","",""
"12070","Herrn","Dr. M.","Orlowski/ H. Damaschke","Allgemeinmedizin","22.03.2013","Ostlandstr. 8","23812","Wahlstedt","04554/2344","","","","","","",""
"12127","Herrn","Dr. med. P.","Papachrysanthou","Innere Medizin","09.03.2016","Schiffbrückenplatz 9","24768","Rendsburg","04331/12900","","","0160/8857779","","","",""
"12187","Herrn","Christian Neumann","Parkcenter-Einhorn-Apotheke","","15.02.2019","Christianstraße 20","24534","Neumünster","","","info@apotheke-neumuenster.de","","","","",""
"12092","Herrn","Dr. med. F.","Paul","","25.03.2014","Marktplatz 1","22844","Norderstedt","040/52110717","","","","","","",""
"12058","Herrn","Stiftung Schwarzach","Pfarrer-Michael-Graf-","Orthopädie","19.12.2011","Dekan-Graf-Str. 2-6","94374","Schwarzach","09962/209571","09962/209525","","","09962/209514","","",""
"12077","Herrn","Dr. med. Heimo","Polchau","Kinder- und Jugendärzte","09.08.2013","Lehmberg 7","24103","Kiel","0431/2400240","0431/2400246","praxis@polchau.de","0162/6603963","","","0431/2400242 Dr. Polchau direkt",""
"12202","Herrn","GP Eutin","Radiologische","","30.04.2020","Hospitalstraße 22","23701","Eutin","0452172061","","","","","","",""
"12085","Herrn","Dipl. med. R.","Rahden","Internist","02.10.2013","Ernst Thälmann Str. 51","18461","Franzburg","038322857","038322589825","praxis.rahden@online.de","","","","",""
"12188","Frau","Jutta Kuhn","Rathaus-Apotheke OHG","","15.02.2019","Rathausstraße 11","22941","Bargteheide","","","","","","","",""
"12142","Gemeinschaftspraxis","Dres. med.","Rathjens/ Hartmaring","Allgemeinmedizin","01.09.2016","Friedrichstr. 1","25469","Halstenbek","04101/44490","04101/46717","joachim@rathjens.de","","","0410145818 geheim","",""
"12189","Frau","Bettina Obrock-Kienzle","Reiter Apotheke am Hogenkamp","","15.02.2019","Ansgarstr. 31","25336","Elmshorn","","","","","","","",""
"12190","Frau","Bettina Obrock-Kienzle","Reiter-Apotheke im Pferdeviertel","","15.02.2019","Eichstraße 34","25336","Elmshorn","04121/62696","","","","","","",""
"12036","Herrn","Dr. med.","Ritschl","Allgemeinmedizin","21.12.2009","Fördestr. 54","24944","Flensburg","0461/37177","0461/3153094","anrok@t-online.de","01702002208","0461/37177","","",""
"12096","Herrn","Dr. med. Martin","Freiherr von Rosen","Innere Medizin","10.11.2014","Schlossplatz 3","36129","Gersfeld","06654/960950","","info@praxis-rosen.de","","","","",""
"12022","Gemeinschaftspraxis","Dres. med.","Rundfeldt","Allgemeinmedizin","25.03.2010","Mürwiker Str. 174","24944","Flensburg","0461/32911","0461/32051","rundfeldt@medflug.de","","0461/32911","","",""
"12067","Herrn","Dr. med. Oliver","Sauer","Innere Medizin/Diabetologie","13.12.2012","Wilhelmsplatz 1a","02826","Görlitz","03581/878393","03581/878411","Praxissauer@gmx.de","","","","",""
"12094","Gemeinschaftspraxis","Dres. med.","Sawula & Budde","","25.03.2014","Rathausallee 7","22846","Norderstedt","0405257829","","","","","","",""
"12141","Herrn","Dr. med. R.","Schäferkordt","Psychotherapie","14.01.2014","Fritz-Reuter-Str. 23","19258","Boizenburg/Elbe","038847/487179","038847487019","schaeferkordt@gmx.de","","","","",""
"12034","Gemeinschaftspraxis","Dres. med.","Schlegel/Nolde","Internisten","19.12.2009","Bismarckstr. 92-94","24943","Flensburg","0461/17008","0461/17000","anne-schlegel@gmx.de","","0461/17008","Anne-Schlegel@gmx.de Tel: 04613107830","matthias.nolde@online.de","0172/4502569 Fr Lilie"
"12039","Herrn","Dr. med. Tim","Schlüter","Psychotherapeut","21.04.2010","Spitalerstr. 32","20095","Hamburg","040/20201010","040/202010119","","","040/202010110","","",""
"12064","Herrn","Dipl.-Med. D.","Schmidt","Allgemeinmedizin","18.07.2012","Am Markt 1","19273","Neuhaus","038841/20740","038841/61228","","","","","",""
"12068","Herrn","Dipl.-Psych. Michael","Schmidt","Psycholog.Psychotherapeut","13.12.2012","Augustastr. 27","02826","Görlitz","03581/316034","03581/3609558","praxis.schmidt@psychotherapie-goerlitz.de","","","","",""
"12054","Herrn","Dr. med. Walter","Schmidt","Allgemeinmedizin","07.04.2011","Christianstraße 48","23514","Neumünster","04321/44183","","","","","","",""
"12105","Herrn","Sven","Schnakenbeck/Dr. med. B. Obermeier","","04.05.2015","Mühlenstr. 7a","23866","Nahe","04535/8830","04535/2162","praxis@docobermeier.de","","","","",""
"12104","Gemeinschaftspraxis","Dres. med.","Schönewolf/Schult-Kronefeld","Innere Medizin","25.03.2015","Ulzburger Str. 12","22850","Norderstedt","040/5294944","040/5240403","","","","","",""
"12145","Gemeinschaftspraxis","Dres. med.","Schröder/Günther/Venzke/Kalinski","Pathologie- Hamburg","29.11.2016","Lademannbogen 61-63","22339","Hamburg","040/53805890","040/53805750","wolff@pathologie-hamburg.de","","","","",""
"12088","Herrn","Dr. med. Frank","Schubert","Radiologie","21.10.2013","Am Krankenhaus 5","24211","Preetz","04342/801284","04342/801285","","","","","",""
"12099","Gemeinschaftspraxis","Dres. med.","Schult-Kronefeld/Volk","Innere Medizin","08.12.2014","Ulzburger Str. 12","22850","Norderstedt","040/5294944","0405240403","sk@lungenpraxis-norderstedt.de","0177/3613055","","","",""
"12041","Herrn","Dr. med. Matthias","MVZ Bad Doberan Schwarz","Gynäkologe","27.10.1999","Am Markt 12d","18209","Bad Doberan","0381/82221","0381/82273","","","","0381/83454 privat","",""
"12148","Herrn","Dr. med. Oliver","Seibert","Orthopädie","31.05.2017","Frankfurter Str. 26","61118","Bad Vilbel","06101/83946","06101/12689","praxis@dr-seibert.de","","","www.dr-seibert.de","",""
"12124","Herrn","Dr. med. Thomas","Siedschlag","Allgemeinmedizin","08.02.2016","Am Landratspark 1","23795","Bad Segeberg","045512582","0455194812","praxis@orthopaedie-segeberg.de","","","dr.thomas.siedschlag@onlinemed.de","",""
"12191","Frau","Dr. Christina Bischof-Deichnik","Sonnen-Apotheke","","15.02.2019","Bergedorfer Straße 58-62","21502","Geesthacht","","","","","","","",""
"12089","Herrn","Nephrologisches Zentrum Reinbek","Dres. Staben/Meier/Ewald/Bassler","Nephrologen","01.01.2011","Am Ladenzentrum 8","21465","Reinbek","040/7277860","040/72778615","","","","","",""
"12196","Herrn","~","Stadtklinik Frankenthal","","30.07.2019","Elsa-Brändström-Str. 1","67227","Frankenthal","","","","","","","",""
"12027","Frau","Ulrike","Staffeld","Innere Medizin","29.12.2009","Am Stadtrand 41","24536","Neumünster","04321/31800","04321/39628","uli.sta@gmx.de","0172/1618761","04321/31800","","",""
"12115","Herrn","PD Dr. med. Spilcke-Liss/","Streckenbach/Schindler/Spielhagen","Radiologie","21.09.2015","Pappelallee 1","17489","Greifswald","03834/80440","03834/804441","","","","","",""
"12075","Herrn","Sönke","Sturm","Allgemeinmedizin","25.07.2013","Hohe Str. 26","24806","Hohn","04335/92740","","praxis@sturm-hohn.de","0162/4595544","","","",""
"12006","Gemeinschaftspraxis","Dres. med.","Stybalkowski","Innere Medizin","14.08.2009","Krämerstraße 12","25813","Husum","04841/5007","04841/82881","","","04841/5007","","",""
"12055","Herrn","Andre","Suchland","Psychiatrie","27.05.2011","Erich-Oppenheimer-Str. 6F","02827","Görlitz","03581/3759569","03581/3759589","","","","","",""
"12078","Herrn","Mike","Thomsen","Allgemeinmedizin","13.08.2013","Moltkestr. 12","24768","Rendsburg","04331/23411","04331/25574","Hausarztpraxis-Thomsen@gmx.de","01724123411","","0176/32997993 (Griguhn)","",""
"12117","Herrn","Dr. med. Th.","Thormann / L. Wintermeyer","Innere Medizin","02.11.2015","Preußerstr. 1-9","24105","Kiel","043130821","04313053523","ikad-kiel@arcor.de","","","017652174673 Dr Thormann","0431/314655",""
"12136","Herrn","Dr. med. Dieter","Tischendorf","Innere Medizin","21.06.2016","Battentor 23","36115","Hilders","06681/967970","06681/967971","dtisch@web.de","","","","",""
"12199","Herrn","Olaf Zander","Trave Apotheke","","17.02.2020","Chausseebaum 6","23795","Klein Rönnau","04551/82199","","olaf_zander@t-online.de","","","","",""
"12111","Gemeinschaftspraxis","Dres. med.","Truschnowitsch/Mittasch","Orthopädie","02.07.2015","Emmerich-Josef-Str. 40","65929","Frankfurt-Höchst","069/302085","","info@orthopaediezentrum-frankfurt.de","","","","",""
"12112","Frau","Dr. med. Kerstin","Uphoff","Kinder- u. Jugendmedizin","13.08.2015","Holzweg 8","61440","Oberursel/Ts.","06171/4650","06171/587098","bernd.uphoff@t-online.de","01623297946","","069/71473959","",""
"12150","Herrn","Verband","VDEK","","21.07.2017","Askanischer Platz 1","10963","Berlin","","","","","","","",""
"12201","Herrn","Diagnosticum","VISIORAD MVZ GmbH","","30.04.2020","Fahltskamp 74","25421","Pinneberg","0410154420","","info@visiorad.de","","","bh-vr@ps-g.de","",""
"12129","Herrn","Jörn","Voigt","Kinderarzt","15.03.2016","Röntgenstr. 26","64823","Groß Umstadt","06078/4433","06078/783681","joern.voigt@kinderarzt-voigt.de","","","","",""
"12192","Frau","Bärbel Hansen","Vorstadt-Apotheke","","15.02.2019","Schweriner Straße 51","23909","Ratzeburg","","","","","","","",""
"12057","Frau","Kirsten Katharina","Warnecke","Kieferchirurgie","11.08.2011","Wismarsche Straße 132-134","19053","Schwerin","0385/3265050","0385/32650511","mkg-schwerinqgmx.de","","","","",""
"12134","Herrn","Dr. med. Markus","Wegmann","Kinder- und Jugendmedizin","19.05.2016","Deutschhausstr. 30","35037","Marburg","06421/961990","06421/8891198","911@drwegmann.de","015201712529","","","",""
"12107","Herrn","Dr. med. Peter","Weidemann","","22.05.2015","Kurbrunnenstr. 22","52066","Aachen","0241/6052852","0241/6052851","weidemann@aol.com","","","","",""
"12053","Herrn","Orthopädikum Neuer Wall","Dres. Westermann/Schwade","Orthodädie","17.03.2011","Neuer Wall 36","20354","Hamburg","040/364714","040/364273","kontakt@Orthopaedikum-Neuer-Wall.de","0179/5465870","","","",""
"12056","Herrn","Hr.Ebling","Westpfalz-Klinikum GmbH","EDV-Abteilung Hr.Ebling","29.07.2011","Hellmut-Hartert-Str. 1","67655","Kaiserslautern","0631/2031321","","","","","","",""
"12059","Gemeinschaftspraxis","Dres. med. Ulrich/Andreas","Wiegers/Seifert","","18.01.2012","Flensburger Str. 15","24837","Schleswig","04621/28024","","","","04621/304811","","",""
"12144","Herrn","Dr. med. Jan","Wierecky","Hämatologie/Onkologie","16.11.2016","Hohe Weide 17b","20259","Hamburg","040/3571777500","040357177710","wierecky@onkologie-hamburg.de","","","0403571777526 (Frau Zaech)","",""
"12048","Gemeinschaftspraxis","Dres. med.","Winkler/ Burghoff/ v. Carnap","123456","13.12.2009","Waldstr. 13-15 Haus A","24939","Flensburg","0461/1683100","0461/16831029","","","","FLUG9","",""
"12193","Herrn","Karsten Werner","Wolfs Apotheke","","15.02.2019","Markt 28","25821","Bredstedt","","","","","","","",""
"12119","Gemeinschaftspraxis","Dres. med. Onischke/","Zechlin/ Kellinghusen","Innere Medizin","20.11.2015","Lütjenburger Str. 2","24238","Selent","04384/603","04384/604","clausonischke@web.de","","","","",""
"12079","Herrn","Dr. med. B.","Zybura","Allgemeinmedizin","16.08.2013","Paradeplatz 8","24768","Rendsburg","04331/21133","04331/29591","seidel-zybura@t-online.de","0152/34258424","","","",""
1 Nummer Anrede Vorname Nachname Fachrichtung InstDatum Strasse PLZ Ort Tel Fax mail Handy Tele Firma Kontakt1 Kontakt2 Kontakt3
2 12014 Gemeinschaftspraxis Dres. med. Ahnsel/ Tüxen-Ahnsel Allgemeinmedizin 19.12.2009 Mozartstr. 42 24943 Flensburg 0461/63622 0461/674422 torsten@ahnsel.de
3 12166 Herrn Sven-Oliver Konrad Alte Rathaus-Apoteke 15.02.2019 Musbekerweg 1 24955 Harrislee 0461/770099
4 12046 Herrn Dr. med. A. Amran Allgemeinmedizin 29.06.2010 Hahnweg 24 56242 Selters 026268888 026265878 info@zahnarzt-selters.de
5 12167 Herrn Dr. Kai Chirstiansen Angler Apotheke 15.02.2019 Westholmerstraße 3 24972 Steinbergkirche 04632/301
6 12120 Frau ~ Anlaufpraxis der KVSH Allgemeinmedizin 21.12.2015 Knuthstr. 1 24939 Flensburg
7 12164 Frau im UKSH Kiel Apotheke Apotheke 20.08.2018 Arnold-Heller-Str. 3 24105 Kiel 043126041330 043126041340 info@apotheke-im-uksh-kiel.de www.apotheke-im-uksh-kiel.de
8 12168 Frau Eva Maria Kremer-Dziuron Apotheke am Freilichtmuseum 15.02.2019 Am Museum 1a 24113 Molfsee 0431/651488
9 12160 Frau St. Michael Apotheke am Ochsenmarkt Apotheke 05.02.2018 Am Ochsenmarkt 35 24937 Flensburg 0461/51973 0461/52030 kerstin.tomberger@apotheke-st-michael.de
10 12161 Frau St. Michael Apotheke im CITTI-PARK Apotheke 05.02.2018 Langberger Weg 4 24941 Flensburg 0461/99577860 0461/97899436 CITTI@apotheke-st-michael.de
11 12113 Herrn Meine Apotheke Marienbrunn Apotheke 21.09.2015 Zwickauer Strasse 99a 04277 Leipzig 0341/8611265 0341/8611267 mail@uwepaepcke.de mail@apotheke-marienbrunn.de www.apotheke-marienbrunn.de
12 12198 Herrn ~ Apotheken Wirtschaftsdienst GmbH 10.09.2019 Steekberg 11 24107 Kiel 03423/7583791 03423/7061519
13 12017 Gemeinschaftspraxis Dres. med. Aretz/Winterhoff Innere Medizin 01.01.2010 Südermarkt 1a 24937 Flensburg 0461/1827804 0461/1827819 0461/1827804
14 12010 Frau Dr. med. Gabriele Auerbach-Annewanter Innere Medizin 08.12.2009 Toosbüystr. 4 24939 Flensburg 0461/20204 0461/5057077 auerbach-annewanter@medflug.de 0461/20204
15 12038 Herrn Dr. med. S. Babinsky / Chr. A Mohr Allgemeinmedizin 30.12.2009 Max-Richter-Str. 2a 24537 Neumünster 04321/853880 04321/8538828 info@praxis-am-kantplatz.de 04321/8538817
16 12063 Herrn Dr. med. Michael Bär Hautarzt 18.06.2012 Löbauer Str. 17 02625 Bautzen 035912777140
17 12076 Gemeinschaftspraxis Dres. med. Bandick/Lemke/Krüger Radiologie 31.07.2013 Berliner Allee 40c 22850 Norderstedt 040/5287330 040/52873399 EMAIL@RPXN.DE 04052385962
18 12021 Herrn Dr. med. W. Barchasch Gynäkologe 22.12.2009 Norongsallee 11 24939 Flensburg 0461/27700 0461/28149 dr.bacco@gmx.de 0461/27700
19 12047 Herrn Dr. med. Eberhard Barth Innere Medizin 07.09.2010 Hansastr. 2-3 20149 Hamburg 040/456858 040/417346
20 12169 Herrn Ulrich Grothe Bergapotheke 15.02.2019 Am Markt 3 25560 Schenefeld
21 12042 Herrn Michael Bergeler/G. Pelz-Bergeler Allgemeinmedizin 05.05.2010 Musbeker Weg 1 24955 Harrislee 046173038 046178873 bergeler_pelz-bergeler@medflug.de
22 12101 Herrn Dipl.-Med. Michael Beylich Allgemeinmedizin 27.02.2015 Brückenstr. 33 99955 Bad Tennstedt 036041/57033 m.beylich@gmail.com 0174/7447780 036041/42255 praxisbeylich@gmail.com
23 12170 Herrn Dr. Kai Christiansen Birk-Apotheke 15.02.2019 Nordstraße 2 24395 Gelting 04643/18810
24 12163 Herrn ~ BITMARCK Service GmbH 24.07.2018 Kruppstraße 64 45145 Essen 0201/17662463
25 12132 Herrn Dr. med. Christoph Bornhöft Kinderarzt 04.04.2016 Nibelungenstr. 26 64625 Bensheim 0625172920 017672601262
26 12083 Gemeinschaftspraxis Dres.med Bothmann-Graeber/Eggers/Behm Allgemeinmedizin 05.09.2013 Hebbelstr. 3 24768 Rendsburg 04331/14060
27 12162 Frau Dr. med. Susanne Brenner Allgemeinmedizin 14.06.2018 Hauptstrasse 100 66583 Spiesen-Elvenberg 06821/9831300 praxis@bmade.de 0151/56027055
28 12020 Gemeinschaftspraxis Dres. med. Buchholz/ Schulte/Ostermann Allgemeinmedizin 01.01.2010 Zur Höhe 12 24955 Harrislee 0461/150560 0461/5705218 0461/150560
29 12019 Gemeinschaftspraxis Dres. Burghoff/v. Carnap-Bornheim/Lammerskitten Innere Medizin 05.10.2009 Waldstr. 13-15 24939 Flensburg 0461/1683100 0461/16831029 diabetes-zentrum-flensburg@flugmed.de 015141918161 info-an@dr.robert-winkler.de c.burghoff@web.de 01746225488 (Carnap)
30 12050 Gemeinschaftspraxis Dres. med. Burkert/ Strobach 08.12.2010 Appenrader Str. 48 24939 Flensburg 0461/41006
31 12131 Herrn Winfried Buß Orthopädie 30.03.2016 Gerhardstr. 3 24768 Rendsburg 04331/789456 winfried-buss@web.de
32 12081 Frau Dr. med. Pamela Deißner Allgemeinmedizin 05.09.2013 Wennhorn 1a 24816 Hamweddel 04875/1323 04875267 kontakt@praxisdeissner.de 0151535733
33 12171 Herrn Gerd Ehmen Donn-Apotheke 15.02.2019 Johannßenstraße 2 25693 St. Michaelisdonn 04853460
34 12086 Herrn Radiologische Praxis am FEK Dose/Teufel Radiologie 15.10.2013 Friesenstr. 11 24534 Neumünster 04321/40910 04321/409121 info@roentgenpraxis-am-fek.de
35 12060 Gemeinschaftspraxis Dres. med. Daniel Drexler/Lill Allgemeinmedizin 20.01.2012 Bahnhofstrasse 11 83022 Rosenheim 08031/9412471 0151/26338196
36 12098 Gemeinschaftspraxis Dres. med. Eberlein-Riemke/ Laporte Allgemeinmedizin 01.12.2014 Rathausallee 83F 22846 Norderstedt 04052/66111 ergs-team@freenet.de
37 12210 Herrn Marcus Hettlage Element 44 30.11.2020 Schmiedestraße 11 25899 Niebüll 046619569057 hettlage@element44.de 01705452248
38 12152 Herrn Dr. med. Lars Emde Radiologie 22.12.2017 Farmsener Landstr. 193 22359 Hamburg 040/54755080 040/54755081
39 12073 Herrn GMP für Anästhesie Kiel Dres. Engel/Rinck/Schele u. Kollegen Anästhesisten 03.07.2013 Schönberger Str. 11 24148 Kiel 0431/7206522 0431/7206599 rogge@anaesthesie-kiel.de 0431/7206525
40 12135 Herrn Priv.-Doz. Dr. med. habil. Peter Entzian Innere Medizin 17.06.2016 Kuhberg 28 24534 Neumünster 04321/43621 04321/42444 entzian@lungenarzt-nms.de 0171/6992739 043219527959 (Schikura)
41 12084 Herrn Dr. med. Matthias Eppel Allgemeinmedizin 13.09.2013 Bahnhofstr. 17 24811 Owschlag 043363166 04336999010 info@praxis-owschlag.de 04336/999011
42 12087 Herrn ~ Evidia MVZ Förderadiologicum GmbH Radiologie 21.10.2013 Karlstal 32 24143 Kiel 0431/702160 0431/7021619 0171/5180700 Herr Müller
43 12143 Frau Dr. med. Natalie Fahrenkrog Gynäkologie 25.10.2016 Blankwasserweg 20 23743 Grömitz 04562/25273 04562/25275 n.fahrenkrog@t-online.de
44 12090 Gemeinschaftspraxis Dres. med. Falk/Schomburg 01.01.2014 Seminarweg 4 24837 Schleswig 04621/27027 04621/26074 0170/5370910 geheim handy 01577/8930003
45 12082 Gemeinschaftspraxis Dres. med. Fink/Girma Urologie 05.09.2013 Bastion 2 24788 Rendsburg 04331/23320 04331/55128 info@urologen-rendsburg.de 0176/24330034 04331/24045 0172/8832839 Dr. Finck
46 12172 Frau Eva Maria Kremer-Dziurom Fital-Apotheke 15.02.2019 Posthofstr 4 24321 Lütjenburg 043814040880
47 12195 Herrn Jürgen Nolte Fleethörn-Apotheke 15.04.2019 Knooper Weg 44 24103 Kiel 0431/554381
48 12173 Herrn Sönke Kehrhahn Flora-Apotheke 15.02.2019 Schulstraße 25-27 25335 Elmshorn 041214262
49 12033 Herrn . FLUG 01.01.2010 Dorotheenstr. 6 24939 Flensburg 0461/570520 0461/5705218 01786963930 0461/570520
50 12174 Frau Friederike Vogler Fockbeker Apotheke 15.02.2019 Rendsburger Str. 19 24787 Fockbek 0433161404
51 12175 Herrn Dr. Heinrich Schop Förde-Apotheke 15.02.2019 Mürwikerstr. 162 24944 Flensburg 0461314130 0171/2146626
52 12116 Herrn Martin Forster Allgemeinmedizin 29.09.2015 Schwachhauser Heerstraße 167 28211 Bremen 0421/341977 0421/344445 hausarzt-forster@gmx.de 01631599029 0421/68495400 Privat Dr. Forster und Ehefrau Fr. Broockmann
53 12123 Gemeinschaftspraxis Dres. med. Forster/Kabelitz Psychotherapie 14.01.2016 Spitalerstr. 32 20095 Hamburg 040/28059900
54 12062 Herrn Dr. med. Daniel Foss Internist 08.03.2012 Oberneulander Heerstr. 26-28 28355 Bremen 0421/2053338 0421/2053337 dr.hiho@mac.com 0151/40019890 0421/2053336
55 12069 Herrn Alexander Selch im Friedrich-Ebert-Krankenhaus FEK IT-Abteilung 31.01.2013 Friesenstr. 11 24534 Neumünster 04321/4052031 043214052039 juergen.spanier@fek.de
56 12109 Herrn Dr. med. Jörg Fuhrberg Urologe 17.06.2015 Erichsenweg 16 25813 Husum 0461/30550 0461/30615 praxis@dr-fuhrberg.de 0171/1251787 04841/3288 Flensburg@uro-praxis-nord.de 04841/9335045
57 12040 Frau Martina Gaschae Psychotherapeutin 09.03.2010 Kompagniestr. 9 24937 Flensburg
58 12197 Herrn Karsten Gebhardt / Jana Klinkicht 10.09.2019 Am Anger 3 04838 Eilenburg 03423/7061519
59 12091 Gemeinschaftspraxis Dres. med. Gehring /Mansfeld Innere Medizin 25.03.2014 Berliner Allee 40C 22850 Norderstedt 0405283048 040/51208379 pg@hahc.de 040/32590369 0157/82022124 Praxishandy
60 12102 Herrn P. Gernhold/S.Valentin/Dr.M.Stember Allgemeinmedizin 02.03.2015 Evergerstr. 28-30 51061 Köln-Flittard 0221/662211 02219666319 post@gemeinschaftspraxis-flittard.de
61 12151 Herrn P. Gernhold/S.Valentin/Dr.M.Stember 11.12.2017 Oberstr. 10 53859 Niederkassel 02208/1711 02208/8684
62 12194 Herrn ~ GIO Ärztegemeinschaft 29.03.2019 Schloßplatz 3 24768 Rendsburg 04331/4377600 04331/4376570 m.berges@gioonline.de
63 12204 Herrn 185-1.1 gkv informatik 09.11.2020 Lichtscheider Str. 89 42285 Wuppertal
64 12205 Herrn 185-1.2 gkv informatik 09.11.2020 Lichtscheider Str. 89 42285 Wuppertal
65 12206 Herrn 185-2.1 gkv informatik 09.11.2020 Lichtscheider Str. 89 42285 Wuppertal
66 12207 Herrn 185-2.2 gkv informatik 09.11.2020 Lichtscheider Str. 89 42285 Wuppertal
67 12208 Herrn 185-3.1 gkv informatik 09.11.2020 Lichtscheider Str. 89 42285 Wuppertal
68 12209 Herrn 185-3.2 gkv informatik 09.11.2020 Lichtscheider Str. 89 42285 Wuppertal
69 12185 Herrn ~ gkv informatik privat 19.02.2019 Lichtscheider Str. 89 42285 Wuppertal 020269581201 02026958201201 ronald.laryea@gkvi.de Finanzen@gkvi.de
70 12186 Herrn ~ gkv pseudo privat 20.02.2019 Steinstr 1 24118 Kiel
71 12165 Herrn Informatik GKVI 05.02.2019 Lichtscheider Strasse 89 42285 Wuppertal 0202/69581201
72 12025 Gemeinschaftspraxis Dres. med. Görgen-Pauly/Kratzius/Schüren/Schwan Ki- u. Jugendpsychiater 23.12.2009 St.Annen-Str. 1a 23552 Lübeck 0451/7987077 0451/7987075 info@kjp-Luebeck.de 0451/7987077 goergen-pauly@kjp-Luebeck.de schueren@kjp-Luebeck.de neuhauss@kjp-Luebeck.de
73 12045 Herrn Dialysezentrum Gregersen/Lammerskitten 01.01.2010 Alter Ochsenweg 1 24941 Flensburg 0461/9401594 0461/67422039
74 12176 Herrn Dr. Heinrich Schop Grenz-Apotheke 15.02.2019 Zur Höhle 10 24955 Harrislee 046171359 0171/2146626
75 12095 Herrn Dr. med. Martin Gunkel 21.09.2014 Frankensteiner Str. 28 64319 Pfungstadt 06157/4842 06157/991688 martin@gunkel.net 0179/6721400
76 12128 Herrn Dr. med. Martin Gunkel Kinderarzt 15.03.2016 Hauptstr. 30 64342 Seeheim-Jugenheim 06257/903275 06257/903277 dr.v.baum@gmx.de 06257/903276
77 12133 Gemeinschaftspraxis Dres. med. Hachmann/ Feil Kinder- u. Jugendmedizin 06.04.2016 Martinspfad 72 64285 Darmstadt 0615146386 service@e-kinderaerzte.de 0171/7185207
78 12043 Gemeinschaftspraxis Dres. med. Haferland / Urban Innere Medizin 20.05.2010 Reichenbacher Str. 106 a 02827 Görlitz 03581/739797
79 12114 Herrn Dr. med. J. Hannappel Allgemeinmedizin 21.09.2015 Kirchstrasse 12 56333 Winningen 02606/2287 johannappel@t-online.de
80 12015 Gemeinschaftspraxis Dres. med. Hansen-Magnusson/Knaut/Kronas Allgemeinmedizin 29.03.2010 Poststr. 2 24997 Wanderup 04606/227 04606/759 04606/2129999 0151/15555353 Praxishandy (in Prx erreichbar) 0170/4839766 Dr Magnusson
81 12110 Frau Manuela Hehemann Allgemeinmedizin 01.07.2015 Herzbachweg 12 63571 Gelnhausen 06051/888120 06051/888122 manuela.hehemann@freenet.de 0152/04772701
82 12004 Gemeinschaftspraxis Dres. med. Herrberger/Bierwolf Kieferchirurgen 07.10.2009 An der Obertrave 16a 23552 Lübeck 0451/889010 0451/8890111 info@mkg-holstentor.de 0451/889010
83 12122 Frau Dipl.-Psych. Kerstin Hippius-Schultheß Psychotherapie 14.01.2016 Dr.-Friedrichs-Ring 55 08056 Zwickau 0375/30359285 0375/30359286 kerstin.hippius@posteo.de
84 12140 Frau Dipl.-Psych. Andrea Hirschmann Psychotherapie 20.07.2016 Stormsweg 8 22085 Hamburg 040/2276393 03212/1470998 a@hirschmann-schoen.de
85 12177 Herrn Dr. Peter Froese Holsten-Apotheke 15.02.2019 Klas-Groth-Str. 6 24790 Schascht-Audorf 0433194730
86 12007 Frau Dr. med. Astrid Horn Allgemeinmedizin 25.08.2009 Moltkestr. 20 24937 Flensburg 0461/17908 0461/17909 0461/17908
87 12103 Frau Dipl.-Psych. Imke Hoyer Psychotherapie 02.03.2015 Tangstedter Landstr. 516d 22851 Norderstedt 040/35778755 040/35778756 kontakt@psychotherapie-hoyer.de 0162/2308720 I-hoyer@gmx.net
88 12002 Herrn . Interessenten 01.01.2000 Steinstr. 1 24118 Kiel
89 12149 Herrn ~ ITSG GmbH 13.06.2017 Seligenstädter Grund 11 63150 Heusenstamm 06104/60050226 06104/60050300 patrik.bohland@itsg.de 0177/2915142
90 12066 Herrn Dr. med. Uwe Kaeßmann Unfall-u. Gelenkchirurgie 10.12.2012 Am Krankenhaus 5 24211 Preetz 04342/801211 04342/801489 U.Kaessmann@Klinik-Preetz.de
91 12074 Frau Dr. med. Nora Kelm Allgemeinmedizin 08.07.2013 Rendsburger Str. 11 24787 Fockbek 04331/61172 04331/669252
92 12178 Herrn Hans-Günther Lund Kgl. priv. Apotheke 15.02.2019 Markt 1 25917 Leck 046622220 046623054 lund@apotheke-leck.de 046622220
93 12052 Gemeinschaftspraxis Dres. med. Kirsch & Partner 26.01.2011 Marktpassage 8 21149 Hamburg 040/7017471 040/70380771
94 12130 Frau Dr. med. Katja Klenke Kinderärztin 22.03.2016 Tannenbergstr. 2 64342 Seeheim-Jugenheim 06257/82459 Klenke.Katja@t-online.de 015774205315
95 12049 Herrn Karl- Jürgen Labor Klos 08.12.2010 Paul-Ziegler-Str. 1a 24939 Flensburg 0461/503350 0461/5053520 info@labor-klos.de
96 12100 Gemeinschaftspraxis Dres. K. Kohlsche/G. Reisewitz/E. Glet Allgemeinmedizin 28.01.2015 Ohechaussee 13 22848 Norderstedt 040/5296888 040/5293063 hausarztpraxis@wtnet.de 040/52985047 guido.reisewitz@web.de
97 12003 Gemeinschaftspraxis Dres. med Kraemer/ Schreiber Allgemeinmedizin 13.07.2009 Carl-Diem-Str. 5 23611 Bad Schwartau 0451/283996 praxis.kraemer-schreiber@t-online.de 0451/22776
98 12065 Herrn Dennis Kramkowski Allgemeinmedizin 10.12.2012 Fritz-Reuter-Str. 90 24159 Kiel 0431/39021 0431/393934 praxis@kramkowski.net 0160/97984098 http://www.kramkowski.net/
99 12061 Herrn Städtisches Krankenhaus Kiel GmbH privat 20.01.2012 Chemnitzstr. 33 24116 Kiel 04311697 systemtechnik@krankenhaus-kiel.de
100 12097 Herrn Labor Dr. Krause u. Kollegen MVZ GmbH Labormedizin 24.11.2014 Steenbeker Weg 23 24106 Kiel 0431/22010100 0431/22010109 metzner@labor-krause.de
101 12125 Gemeinschaftspraxis Dres. med. Kröger und Kollegen Radiologie 24.02.2016 Wallstraße 40 - 44 24768 Rendsburg 04331/72044 04331/77880 kroeger.s@o2mail.de goettsche@roentgenpraxis-rendsburg.de Tilo.Engel@smart-it4.com
102 12138 Herrn Dr. med. Thorsten Kummerow Augenheilkunde 13.07.2016 Schützenstr. 19 24568 Kaltenkirchen 041915143 04191909999 dr.kummerow@t-online.de 0172/5412180 04191/909998
103 12179 Frau Michaela-Alexandra Banzhaf Kur-Apotheke 15.02.2019 Strandstraße 110 23669 Timmendorf Strand 0450389090 Kur-Apotheke-Niendorf.Timmendorfer-Strand@apotheke-sh.de
104 12212 Herrn ~ KVT - Notdienst Service gGmbH 17.05.2024 Zum Hospitalgraben 8 99425 Weimar 036434950101 sandra.may@kvt-nd-service.de
105 12203 Herrn ~ Labor Mohr 05.08.2020 Rathausplatz 1 24103 Kiel 0431/978881 0431/978824 hmohr@labormohr.de
106 12071 Herrn Lübeck Laborärztliche GP Labormedizin 22.03.2013 Von-Morgen-Str. 3 23564 Lübeck 0451/610900 0451/6109010 andreas.bobrowski@labor-luebeck.de l.sawatzki@labor-luebeck.de
107 12108 Herrn MVZ LaborDiagnostik Mittelhessen GmbH 26.05.2015 Ursulum 1 35396 Gießen 0641/300210 0641/30021100 thomas.bender@ldm-labor.de www.ldm-labor.de
108 12072 Herrn Labor Lademannbogen MVZ GmbH Labormedizin 15.05.2013 Lademannbogen 61 22339 Hamburg 040538050 max@labor-lademannbogen.de
109 12180 Herrn Jonas Friedrichson Lamberti-Apotheke 15.02.2019 Dithmarscher Weg 9 25866 Mildstedt 048417940
110 12009 Frau Carolin Langhanke Innere Medizin 01.01.2010 Apenrader Straße 10 24939 Flensburg 04614041 0461/4043 greg.steg@versanet.de 0461/4041 0171/6834407 Handy Frau Stegmann
111 12181 Herrn Jonas Friedrichson Linden-Apotheke 15.02.2019 Parkweg 10~ 25821 Breklum 04671943323
112 12118 Herrn MVZ Lubinus GmbH 09.11.2015 Steenbeker Weg 25 24106 Kiel 04313888123 0431/38881290 j.wilkens@lubinus-stiftung.de 0431/38882932
113 12137 Gemeinschaftspraxis Dres. med. Maier/Georgijewitsch Orthopädie 12.07.2016 Rödelheimer Bahnweg 21 60489 Frankfurt 069/34875980 069/348759899 069/348759816
114 12106 Frau ~ Mammographie-Screening-Hamburg 11.05.2015 Mönckebergstr. 11 20095 Hamburg 040/471100218 040/471100260 040/471100200
115 12093 Herrn Dr. med. Bernd Mansfeld 25.03.2014 Friedrichsgaber Weg 488 22846 Norderstedt 0405222211 mansfeld@wtnet.de 040/52610380
116 12032 Gemeinschaftspraxis Dres. med. Mantzel/ Storrer-Mantzel Allgemeinmedizin 17.11.2009 Dr-Behm-Ring 8 24963 Tarp 04638/610 04638/898927 vmantzel@web.de 04638/610 stomtz@web.de vo-mantzel@t-online.de
117 12035 Gemeinschaftspraxis Dres. med. Marckmann/Sielmann Allgemeinmedizin 31.12.2009 Kuhberg 43-45 24534 Neumünster 04321/42320 04321/489918 ute-petersen@gmx.de 0174/8135162 04321/42320
118 12182 Herrn Karsten Werner Markt Apotheke 15.02.2019 Markt 8 25821 Bredstedt
119 12183 Herrn Dr. Peter Froese Mastbrook Apotheke 15.02.2019 Ostlandstr 3 24768 Rendsburg 043314705
120 12008 Herrn Dirk Mechler Allgemeinmedizin 29.09.2009 Meldorfer-Str. 69-71 25746 Heide 0481/62181 0481/61791 info@praxis-hei.de 0176/32747045 0481/62181
121 12139 Herrn ~ medical Wundmanagement Hamburg GmbH 19.07.2016 Hauptstr. 1a 22962 Siek 04107/9076776 04107/9087888 yannic.wetendorf@medical-wundmanagement.de simon.schintag@medical-wundmanagement.de
122 12126 Herrn Henning Meyer Psychiatrie 08.03.2016 Lornsenstr. 18 24768 Rendsburg 04331/4598459 04331/4598458 kontakt@psychiatrie-meyer.de
123 12147 Herrn ~ MKG Chirurgie LindenArcarden Chirurgie 08.05.2017 Fackenburger Allee 1 23554 Lübeck 0451/504910 0451/5049123
124 12184 Herrn Nicolas Ahlers Moorbek- Apotheke 15.02.2019 Rathausallee 35-39 22846 Norderstedt 0405227552
125 12037 Herrn Dr. med. W. Müller/ S. Kiesbye Innere Medizin 06.10.2009 Marrensdamm 5 24944 Flensburg 0461/37151 0461/37943 w.mueller@kardiologie-flensburg.de 01718261880 0461/37151
126 12200 Herrn Dr. Benjamin Sattler MVZ Prüner Gang 05.03.2020 Prüner Gang 16-20 24103 Kiel 0431974470 04319744715
127 12121 Herrn Jihad Nassar Allgemeinmedizin 04.01.2016 Schweizergasse 2 63486 Bruchköbel 06181/71329
128 12146 Herrn HNO med. Nord HNO-Ärzte 19.12.2016 Wallstraße 40-44 24768 Rendsburg 0433143460
129 12005 Herrn Dr. med. Helmut Oehne HNO-Arzt 31.07.2009 Nikolaikirchhof 5 24937 Flensburg 0461/24749 0461/22012 0461/24749
130 12070 Herrn Dr. M. Orlowski/ H. Damaschke Allgemeinmedizin 22.03.2013 Ostlandstr. 8 23812 Wahlstedt 04554/2344
131 12127 Herrn Dr. med. P. Papachrysanthou Innere Medizin 09.03.2016 Schiffbrückenplatz 9 24768 Rendsburg 04331/12900 0160/8857779
132 12187 Herrn Christian Neumann Parkcenter-Einhorn-Apotheke 15.02.2019 Christianstraße 20 24534 Neumünster info@apotheke-neumuenster.de
133 12092 Herrn Dr. med. F. Paul 25.03.2014 Marktplatz 1 22844 Norderstedt 040/52110717
134 12058 Herrn Stiftung Schwarzach Pfarrer-Michael-Graf- Orthopädie 19.12.2011 Dekan-Graf-Str. 2-6 94374 Schwarzach 09962/209571 09962/209525 09962/209514
135 12077 Herrn Dr. med. Heimo Polchau Kinder- und Jugendärzte 09.08.2013 Lehmberg 7 24103 Kiel 0431/2400240 0431/2400246 praxis@polchau.de 0162/6603963 0431/2400242 Dr. Polchau direkt
136 12202 Herrn GP Eutin Radiologische 30.04.2020 Hospitalstraße 22 23701 Eutin 0452172061
137 12085 Herrn Dipl. med. R. Rahden Internist 02.10.2013 Ernst Thälmann Str. 51 18461 Franzburg 038322857 038322589825 praxis.rahden@online.de
138 12188 Frau Jutta Kuhn Rathaus-Apotheke OHG 15.02.2019 Rathausstraße 11 22941 Bargteheide
139 12142 Gemeinschaftspraxis Dres. med. Rathjens/ Hartmaring Allgemeinmedizin 01.09.2016 Friedrichstr. 1 25469 Halstenbek 04101/44490 04101/46717 joachim@rathjens.de 0410145818 geheim
140 12189 Frau Bettina Obrock-Kienzle Reiter Apotheke am Hogenkamp 15.02.2019 Ansgarstr. 31 25336 Elmshorn
141 12190 Frau Bettina Obrock-Kienzle Reiter-Apotheke im Pferdeviertel 15.02.2019 Eichstraße 34 25336 Elmshorn 04121/62696
142 12036 Herrn Dr. med. Ritschl Allgemeinmedizin 21.12.2009 Fördestr. 54 24944 Flensburg 0461/37177 0461/3153094 anrok@t-online.de 01702002208 0461/37177
143 12096 Herrn Dr. med. Martin Freiherr von Rosen Innere Medizin 10.11.2014 Schlossplatz 3 36129 Gersfeld 06654/960950 info@praxis-rosen.de
144 12022 Gemeinschaftspraxis Dres. med. Rundfeldt Allgemeinmedizin 25.03.2010 Mürwiker Str. 174 24944 Flensburg 0461/32911 0461/32051 rundfeldt@medflug.de 0461/32911
145 12067 Herrn Dr. med. Oliver Sauer Innere Medizin/Diabetologie 13.12.2012 Wilhelmsplatz 1a 02826 Görlitz 03581/878393 03581/878411 Praxissauer@gmx.de
146 12094 Gemeinschaftspraxis Dres. med. Sawula & Budde 25.03.2014 Rathausallee 7 22846 Norderstedt 0405257829
147 12141 Herrn Dr. med. R. Schäferkordt Psychotherapie 14.01.2014 Fritz-Reuter-Str. 23 19258 Boizenburg/Elbe 038847/487179 038847487019 schaeferkordt@gmx.de
148 12034 Gemeinschaftspraxis Dres. med. Schlegel/Nolde Internisten 19.12.2009 Bismarckstr. 92-94 24943 Flensburg 0461/17008 0461/17000 anne-schlegel@gmx.de 0461/17008 Anne-Schlegel@gmx.de Tel: 04613107830 matthias.nolde@online.de 0172/4502569 Fr Lilie
149 12039 Herrn Dr. med. Tim Schlüter Psychotherapeut 21.04.2010 Spitalerstr. 32 20095 Hamburg 040/20201010 040/202010119 040/202010110
150 12064 Herrn Dipl.-Med. D. Schmidt Allgemeinmedizin 18.07.2012 Am Markt 1 19273 Neuhaus 038841/20740 038841/61228
151 12068 Herrn Dipl.-Psych. Michael Schmidt Psycholog.Psychotherapeut 13.12.2012 Augustastr. 27 02826 Görlitz 03581/316034 03581/3609558 praxis.schmidt@psychotherapie-goerlitz.de
152 12054 Herrn Dr. med. Walter Schmidt Allgemeinmedizin 07.04.2011 Christianstraße 48 23514 Neumünster 04321/44183
153 12105 Herrn Sven Schnakenbeck/Dr. med. B. Obermeier 04.05.2015 Mühlenstr. 7a 23866 Nahe 04535/8830 04535/2162 praxis@docobermeier.de
154 12104 Gemeinschaftspraxis Dres. med. Schönewolf/Schult-Kronefeld Innere Medizin 25.03.2015 Ulzburger Str. 12 22850 Norderstedt 040/5294944 040/5240403
155 12145 Gemeinschaftspraxis Dres. med. Schröder/Günther/Venzke/Kalinski Pathologie- Hamburg 29.11.2016 Lademannbogen 61-63 22339 Hamburg 040/53805890 040/53805750 wolff@pathologie-hamburg.de
156 12088 Herrn Dr. med. Frank Schubert Radiologie 21.10.2013 Am Krankenhaus 5 24211 Preetz 04342/801284 04342/801285
157 12099 Gemeinschaftspraxis Dres. med. Schult-Kronefeld/Volk Innere Medizin 08.12.2014 Ulzburger Str. 12 22850 Norderstedt 040/5294944 0405240403 sk@lungenpraxis-norderstedt.de 0177/3613055
158 12041 Herrn Dr. med. Matthias MVZ Bad Doberan Schwarz Gynäkologe 27.10.1999 Am Markt 12d 18209 Bad Doberan 0381/82221 0381/82273 0381/83454 privat
159 12148 Herrn Dr. med. Oliver Seibert Orthopädie 31.05.2017 Frankfurter Str. 26 61118 Bad Vilbel 06101/83946 06101/12689 praxis@dr-seibert.de www.dr-seibert.de
160 12124 Herrn Dr. med. Thomas Siedschlag Allgemeinmedizin 08.02.2016 Am Landratspark 1 23795 Bad Segeberg 045512582 0455194812 praxis@orthopaedie-segeberg.de dr.thomas.siedschlag@onlinemed.de
161 12191 Frau Dr. Christina Bischof-Deichnik Sonnen-Apotheke 15.02.2019 Bergedorfer Straße 58-62 21502 Geesthacht
162 12089 Herrn Nephrologisches Zentrum Reinbek Dres. Staben/Meier/Ewald/Bassler Nephrologen 01.01.2011 Am Ladenzentrum 8 21465 Reinbek 040/7277860 040/72778615
163 12196 Herrn ~ Stadtklinik Frankenthal 30.07.2019 Elsa-Brändström-Str. 1 67227 Frankenthal
164 12027 Frau Ulrike Staffeld Innere Medizin 29.12.2009 Am Stadtrand 41 24536 Neumünster 04321/31800 04321/39628 uli.sta@gmx.de 0172/1618761 04321/31800
165 12115 Herrn PD Dr. med. Spilcke-Liss/ Streckenbach/Schindler/Spielhagen Radiologie 21.09.2015 Pappelallee 1 17489 Greifswald 03834/80440 03834/804441
166 12075 Herrn Sönke Sturm Allgemeinmedizin 25.07.2013 Hohe Str. 26 24806 Hohn 04335/92740 praxis@sturm-hohn.de 0162/4595544
167 12006 Gemeinschaftspraxis Dres. med. Stybalkowski Innere Medizin 14.08.2009 Krämerstraße 12 25813 Husum 04841/5007 04841/82881 04841/5007
168 12055 Herrn Andre Suchland Psychiatrie 27.05.2011 Erich-Oppenheimer-Str. 6F 02827 Görlitz 03581/3759569 03581/3759589
169 12078 Herrn Mike Thomsen Allgemeinmedizin 13.08.2013 Moltkestr. 12 24768 Rendsburg 04331/23411 04331/25574 Hausarztpraxis-Thomsen@gmx.de 01724123411 0176/32997993 (Griguhn)
170 12117 Herrn Dr. med. Th. Thormann / L. Wintermeyer Innere Medizin 02.11.2015 Preußerstr. 1-9 24105 Kiel 043130821 04313053523 ikad-kiel@arcor.de 017652174673 Dr Thormann 0431/314655
171 12136 Herrn Dr. med. Dieter Tischendorf Innere Medizin 21.06.2016 Battentor 23 36115 Hilders 06681/967970 06681/967971 dtisch@web.de
172 12199 Herrn Olaf Zander Trave Apotheke 17.02.2020 Chausseebaum 6 23795 Klein Rönnau 04551/82199 olaf_zander@t-online.de
173 12111 Gemeinschaftspraxis Dres. med. Truschnowitsch/Mittasch Orthopädie 02.07.2015 Emmerich-Josef-Str. 40 65929 Frankfurt-Höchst 069/302085 info@orthopaediezentrum-frankfurt.de
174 12112 Frau Dr. med. Kerstin Uphoff Kinder- u. Jugendmedizin 13.08.2015 Holzweg 8 61440 Oberursel/Ts. 06171/4650 06171/587098 bernd.uphoff@t-online.de 01623297946 069/71473959
175 12150 Herrn Verband VDEK 21.07.2017 Askanischer Platz 1 10963 Berlin
176 12201 Herrn Diagnosticum VISIORAD MVZ GmbH 30.04.2020 Fahltskamp 74 25421 Pinneberg 0410154420 info@visiorad.de bh-vr@ps-g.de
177 12129 Herrn Jörn Voigt Kinderarzt 15.03.2016 Röntgenstr. 26 64823 Groß Umstadt 06078/4433 06078/783681 joern.voigt@kinderarzt-voigt.de
178 12192 Frau Bärbel Hansen Vorstadt-Apotheke 15.02.2019 Schweriner Straße 51 23909 Ratzeburg
179 12057 Frau Kirsten Katharina Warnecke Kieferchirurgie 11.08.2011 Wismarsche Straße 132-134 19053 Schwerin 0385/3265050 0385/32650511 mkg-schwerinqgmx.de
180 12134 Herrn Dr. med. Markus Wegmann Kinder- und Jugendmedizin 19.05.2016 Deutschhausstr. 30 35037 Marburg 06421/961990 06421/8891198 911@drwegmann.de 015201712529
181 12107 Herrn Dr. med. Peter Weidemann 22.05.2015 Kurbrunnenstr. 22 52066 Aachen 0241/6052852 0241/6052851 weidemann@aol.com
182 12053 Herrn Orthopädikum Neuer Wall Dres. Westermann/Schwade Orthodädie 17.03.2011 Neuer Wall 36 20354 Hamburg 040/364714 040/364273 kontakt@Orthopaedikum-Neuer-Wall.de 0179/5465870
183 12056 Herrn Hr.Ebling Westpfalz-Klinikum GmbH EDV-Abteilung Hr.Ebling 29.07.2011 Hellmut-Hartert-Str. 1 67655 Kaiserslautern 0631/2031321
184 12059 Gemeinschaftspraxis Dres. med. Ulrich/Andreas Wiegers/Seifert 18.01.2012 Flensburger Str. 15 24837 Schleswig 04621/28024 04621/304811
185 12144 Herrn Dr. med. Jan Wierecky Hämatologie/Onkologie 16.11.2016 Hohe Weide 17b 20259 Hamburg 040/3571777500 040357177710 wierecky@onkologie-hamburg.de 0403571777526 (Frau Zaech)
186 12048 Gemeinschaftspraxis Dres. med. Winkler/ Burghoff/ v. Carnap 123456 13.12.2009 Waldstr. 13-15 Haus A 24939 Flensburg 0461/1683100 0461/16831029 FLUG9
187 12193 Herrn Karsten Werner Wolfs Apotheke 15.02.2019 Markt 28 25821 Bredstedt
188 12119 Gemeinschaftspraxis Dres. med. Onischke/ Zechlin/ Kellinghusen Innere Medizin 20.11.2015 Lütjenburger Str. 2 24238 Selent 04384/603 04384/604 clausonischke@web.de
189 12079 Herrn Dr. med. B. Zybura Allgemeinmedizin 16.08.2013 Paradeplatz 8 24768 Rendsburg 04331/21133 04331/29591 seidel-zybura@t-online.de 0152/34258424

View File

@@ -9,5 +9,6 @@ services:
- FLASK_APP=app.py - FLASK_APP=app.py
- FLASK_ENV=production - FLASK_ENV=production
- LOGIN_PASSWORD=changeme - LOGIN_PASSWORD=changeme
- UPLOAD_PASSWORD=upload_changeme
- ALLOWED_IP_RANGES=213.178.68.218/29,192.168.0.0/24,192.168.177.0/24 - ALLOWED_IP_RANGES=213.178.68.218/29,192.168.0.0/24,192.168.177.0/24
command: flask run --host=0.0.0.0 command: flask run --host=0.0.0.0

View File

@@ -2,4 +2,5 @@ flask==3.0.2
pandas==2.2.1 pandas==2.2.1
numpy==1.26.4 numpy==1.26.4
python-dotenv==1.0.1 python-dotenv==1.0.1
requests==2.32.3 requests==2.32.3
markdown2==2.4.12

View File

@@ -1,24 +0,0 @@
.result-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
}
.result-tag {
padding: 4px 8px;
border-radius: 4px;
font-size: 0.9em;
font-weight: 500;
text-transform: uppercase;
}
.tag-medisoft {
background-color: #e3f2fd;
color: #1976d2;
}
.tag-mediconsult {
background-color: #f3e5f5;
color: #7b1fa2;
}

View File

@@ -151,6 +151,36 @@ body {
position: relative; position: relative;
} }
.reset-icon {
position: absolute;
right: 40px;
top: 50%;
transform: translateY(-50%);
cursor: pointer;
color: #6c757d;
z-index: 10;
padding: 0.375rem;
display: none;
}
.input-group input:not(:placeholder-shown) + .reset-icon {
display: block;
}
.reset-icon:hover {
color: #dc3545;
}
.search-icon {
position: absolute;
right: 10px;
top: 50%;
transform: translateY(-50%);
color: #6c757d;
z-index: 10;
padding: 0.375rem;
}
.result-counts { .result-counts {
display: flex; display: flex;
justify-content: center; justify-content: center;
@@ -182,18 +212,78 @@ body {
.customer-card { .customer-card {
background: white; background: white;
border-radius: 8px; border-radius: 8px;
padding: 1.5rem; box-shadow: 0 2px 4px rgba(0,0,0,0.1);
margin-bottom: 1.5rem;
box-shadow: 0 2px 4px rgba(0,0,0,0.05);
border-bottom: 1px solid #e9ecef;
}
.customer-card:last-child {
border-bottom: none;
}
.customer-info {
margin-bottom: 1rem; margin-bottom: 1rem;
padding: 1rem;
}
.customer-header {
display: flex;
justify-content: space-between;
align-items: flex-start;
margin-bottom: 0.5rem;
}
.customer-name {
margin: 0;
font-size: 1.2rem;
color: #333;
}
.customer-actions {
display: flex;
align-items: center;
gap: 0.5rem;
}
.customer-details {
font-size: 0.9rem;
color: #666;
}
.customer-details p {
margin: 0.25rem 0;
}
.customer-details strong {
color: #333;
}
.phone-link, .email-link, .customer-link {
color: #007bff;
text-decoration: none;
}
.phone-link:hover, .email-link:hover, .customer-link:hover {
text-decoration: underline;
}
.address-text {
margin-right: 0.5rem;
}
.address-link, .route-link {
color: #6c757d;
text-decoration: none;
margin-left: 0.5rem;
}
.address-link:hover, .route-link:hover {
color: #343a40;
}
.location-pin, .route-pin {
font-size: 0.9rem;
}
.badge {
font-size: 0.8rem;
padding: 0.35em 0.65em;
}
.btn-sm {
padding: 0.25rem 0.5rem;
font-size: 0.875rem;
} }
.footer-content { .footer-content {
@@ -270,4 +360,28 @@ body {
.tag-mediconsult { .tag-mediconsult {
background-color: #ff9800; background-color: #ff9800;
}
.autocomplete-items {
position: absolute;
border: 1px solid #d4d4d4;
border-top: none;
z-index: 99;
top: 100%;
left: 0;
right: 0;
background-color: white;
max-height: 200px;
overflow-y: auto;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.autocomplete-items div {
padding: 8px 12px;
cursor: pointer;
background-color: white;
}
.autocomplete-items div:hover {
background-color: #f8f9fa;
} }

515
static/js/main.js Normal file
View File

@@ -0,0 +1,515 @@
let searchTimeout;
let lastResults = [];
let fachrichtungTimeout;
let ortTimeout;
let currentPage = 1;
let totalPages = 1;
let currentResults = [];
let currentSearchQuery = '';
let currentFilters = {
fachrichtung: '',
plz: '',
ort: ''
};
function createPhoneLink(phone) {
if (!phone) return '';
const clientIP = document.querySelector('meta[name="client-ip"]').content;
const allowedIPRanges = document.querySelector('meta[name="allowed-ip-ranges"]').content.split(',');
// Überprüfen, ob die Client-IP in einem der erlaubten Bereiche liegt
const isAllowed = allowedIPRanges.some(range => isIPInSubnet(clientIP, range.trim()));
// Entferne alle nicht-numerischen Zeichen
let cleanNumber = phone.replace(/\D/g, '');
// Formatiere die Nummer
let formattedNumber = cleanNumber;
if (cleanNumber.length === 11) {
formattedNumber = cleanNumber.replace(/(\d{4})(\d{7})/, '$1-$2');
} else if (cleanNumber.length === 10) {
formattedNumber = cleanNumber.replace(/(\d{3})(\d{7})/, '$1-$2');
}
// Erstelle den Link
return `<a href="tel:${cleanNumber}" class="phone-link">${formattedNumber}</a>`;
}
function createEmailLink(email) {
if (!email) return '';
return `<a href="mailto:${email}" class="email-link">${email}</a>`;
}
function highlightText(text, searchTerm) {
if (!searchTerm || !text) return text;
// Teile den Suchbegriff in einzelne Wörter
const searchWords = searchTerm.split(/\s+/).filter(word => word.length > 0);
// Wenn keine Wörter gefunden wurden, gebe den ursprünglichen Text zurück
if (searchWords.length === 0) return text;
// Erstelle einen regulären Ausdruck für alle Suchwörter
const regexPattern = searchWords
.map(word => word.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'))
.join('|');
// Erstelle den regulären Ausdruck
const regex = new RegExp(`(${regexPattern})`, 'gi');
// Ersetze alle Übereinstimmungen mit mark-Tags
return text.replace(regex, '<mark>$1</mark>');
}
function createAddressLink(street, plz, city) {
if (!street || !plz || !city) return '';
const address = `${street}, ${plz} ${city}`;
const searchQuery = encodeURIComponent(address);
const routeQuery = encodeURIComponent(address);
return `<span class="address-text">${address}</span>
<a href="https://www.google.com/maps/search/?api=1&query=${searchQuery}"
class="address-link" target="_blank" rel="noopener noreferrer">
<i class="fa-solid fa-location-dot location-pin"></i>
</a>
<a href="https://www.google.com/maps/dir/?api=1&destination=${routeQuery}"
class="route-link" target="_blank" rel="noopener noreferrer">
<i class="fa-solid fa-route route-pin"></i>
</a>`;
}
function adjustCustomerNumber(number) {
return number - 12000;
}
function isIPInSubnet(ip, subnet) {
// Teile die IP und das Subnetz in ihre Komponenten
const [subnetIP, bits] = subnet.split('/');
const ipParts = ip.split('.').map(Number);
const subnetParts = subnetIP.split('.').map(Number);
// Konvertiere IPs in 32-bit Zahlen
const ipNum = (ipParts[0] << 24) | (ipParts[1] << 16) | (ipParts[2] << 8) | ipParts[3];
const subnetNum = (subnetParts[0] << 24) | (subnetParts[1] << 16) | (subnetParts[2] << 8) | subnetParts[3];
// Erstelle die Subnetzmaske
const mask = ~((1 << (32 - bits)) - 1);
// Prüfe, ob die IP im Subnetz liegt
return (ipNum & mask) === (subnetNum & mask);
}
function createCustomerLink(nummer) {
const clientIP = document.querySelector('meta[name="client-ip"]').content;
const allowedIPRanges = document.querySelector('meta[name="allowed-ip-ranges"]').content.split(',');
// Überprüfe, ob die Client-IP in einem der erlaubten Bereiche liegt
const isAllowed = allowedIPRanges.some(range => {
const trimmedRange = range.trim();
return isIPInSubnet(clientIP, trimmedRange);
});
if (isAllowed) {
const adjustedNumber = adjustCustomerNumber(nummer);
return `<a href="medisw:openkkbefe/P${adjustedNumber}?NetGrp=4" class="customer-link">${nummer}</a>`;
} else {
return nummer;
}
}
function showCopyFeedback() {
const feedback = document.getElementById('shareFeedback');
feedback.style.display = 'block';
feedback.style.opacity = '1';
feedback.addEventListener('animationend', () => {
feedback.style.display = 'none';
}, { once: true });
}
async function copyCustomerLink(customerNumber) {
const url = new URL(window.location.href);
url.searchParams.set('kundennummer', customerNumber);
try {
await navigator.clipboard.writeText(url.toString());
showCopyFeedback();
} catch (err) {
// Fehlerbehandlung ohne console.log
}
}
function updateResultCounts() {
const resultCount = document.getElementById('result-count');
const exportButton = document.getElementById('exportButton');
if (lastResults && lastResults.length > 0) {
resultCount.textContent = `${lastResults.length} Ergebnisse gefunden`;
resultCount.style.display = 'inline';
exportButton.style.display = 'inline-block';
} else {
resultCount.textContent = '';
resultCount.style.display = 'none';
exportButton.style.display = 'none';
}
}
function exportToCSV() {
if (!lastResults || lastResults.length === 0) return;
// CSV-Header definieren
const headers = [
'Nummer',
'Name',
'Fachrichtung',
'Straße',
'PLZ',
'Ort',
'Telefon',
'Mobil',
'Handy',
'Telefon Firma',
'E-Mail',
'Kontakt 1',
'Kontakt 2',
'Kontakt 3',
'Tags'
];
// CSV-Daten erstellen
const csvRows = [headers];
lastResults.forEach(customer => {
const row = [
customer.nummer,
customer.name,
customer.fachrichtung,
customer.strasse,
customer.plz,
customer.ort,
customer.telefon,
customer.mobil,
customer.handy,
customer.tele_firma,
customer.email,
customer.kontakt1,
customer.kontakt2,
customer.kontakt3,
(customer.tags || []).join(';')
].map(value => {
// Werte mit Kommas oder Anführungszeichen in Anführungszeichen setzen
if (value && (value.includes(',') || value.includes('"') || value.includes('\n'))) {
return `"${value.replace(/"/g, '""')}"`;
}
return value || '';
});
csvRows.push(row);
});
// CSV-String erstellen
const csvContent = csvRows.map(row => row.join(',')).join('\n');
// Blob erstellen und Download starten
const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
const link = document.createElement('a');
const url = URL.createObjectURL(blob);
link.setAttribute('href', url);
link.setAttribute('download', `kundensuche_${new Date().toISOString().split('T')[0]}.csv`);
link.style.visibility = 'hidden';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
function exportToVCF(customer) {
if (!customer) return;
const vcfData = [
'BEGIN:VCARD',
'VERSION:3.0',
`FN:${customer.name || ''}`,
`N:${customer.name || ''};;;`,
`TEL;TYPE=CELL:${customer.telefon || ''}`,
`TEL;TYPE=HOME:${customer.mobil || ''}`,
`EMAIL:${customer.email || ''}`,
`ADR;TYPE=HOME:;;${customer.strasse || ''};${customer.plz || ''};${customer.ort || ''};`,
`ORG:${customer.fachrichtung || ''}`,
'END:VCARD'
].join('\n');
const blob = new Blob([vcfData], { type: 'text/vcard;charset=utf-8' });
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `kontakt_${customer.name || ''}_${new Date().toISOString().split('T')[0]}.vcf`;
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(url);
document.body.removeChild(a);
}
function displayResults(results) {
const resultsDiv = document.getElementById('results');
const resultCount = document.getElementById('result-count');
const generalSearchTerm = document.getElementById('q').value;
const nameSearchTerm = document.getElementById('nameInput').value;
const fachrichtungSearchTerm = document.getElementById('fachrichtungInput').value;
if (!results || results.length === 0) {
resultsDiv.innerHTML = '<p>Keine Ergebnisse gefunden.</p>';
resultCount.textContent = '';
return;
}
resultCount.textContent = `${results.length} Ergebnisse`;
lastResults = results;
const resultsHTML = results.map(customer => {
// Hilfsfunktion zum Erstellen von Feldern nur wenn sie Werte haben
const createFieldIfValue = (label, value, formatter = (v) => v) => {
if (!value || value === 'N/A' || value === 'n/a' || value === 'N/a' || (typeof value === 'string' && value.trim() === '')) return '';
const formattedValue = formatter(value);
return `<p class="mb-1"><strong>${label}:</strong> ${formattedValue}</p>`;
};
// Highlighting für alle Felder
const highlightField = (value) => {
if (!value) return value;
let highlighted = value;
if (nameSearchTerm) {
highlighted = highlightText(highlighted, nameSearchTerm);
}
if (fachrichtungSearchTerm) {
highlighted = highlightText(highlighted, fachrichtungSearchTerm);
}
if (generalSearchTerm) {
highlighted = highlightText(highlighted, generalSearchTerm);
}
return highlighted;
};
return `
<div class="customer-card">
<div class="customer-header">
<h3 class="customer-name">${highlightField(customer.name)}</h3>
<div class="customer-actions">
<span class="badge ${(customer.tag || 'medisoft') === 'medisoft' ? 'bg-primary' : 'bg-warning text-dark'}">${(customer.tag || 'medisoft').toUpperCase()}</span>
<button class="btn btn-sm btn-outline-primary" onclick="copyCustomerLink('${customer.nummer}')" title="Link kopieren">
<i class="fas fa-link"></i>
</button>
<button class="btn btn-sm btn-outline-primary" onclick='exportToVCF(${JSON.stringify(customer).replace(/'/g, "\\'")})' title="Als VCF exportieren">
<i class="bi bi-person-vcard"></i>
</button>
</div>
</div>
<div class="customer-details">
${createFieldIfValue('Nummer', highlightField(customer.nummer), createCustomerLink)}
${createFieldIfValue('Adresse', (customer.strasse && customer.plz && customer.ort) ? true : false,
() => createAddressLink(
customer.strasse,
highlightField(customer.plz),
highlightField(customer.ort)
))}
${createFieldIfValue('Telefon', highlightField(customer.telefon), createPhoneLink)}
${createFieldIfValue('Mobil', highlightField(customer.mobil), createPhoneLink)}
${createFieldIfValue('Handy', highlightField(customer.handy), createPhoneLink)}
${createFieldIfValue('E-Mail', highlightField(customer.email), createEmailLink)}
${createFieldIfValue('Fachrichtung', highlightField(customer.fachrichtung))}
${createFieldIfValue('Kontakt 1', highlightField(customer.kontakt1), createPhoneLink)}
${createFieldIfValue('Kontakt 2', highlightField(customer.kontakt2), createPhoneLink)}
${createFieldIfValue('Kontakt 3', highlightField(customer.kontakt3), createPhoneLink)}
${customer.tags && customer.tags.length > 0 ? `
<p class="mb-0"><strong>Tags:</strong>
${customer.tags.map(tag => `<span class="badge bg-primary me-1">${tag}</span>`).join('')}
</p>
` : ''}
</div>
</div>
`;
}).join('');
resultsDiv.innerHTML = resultsHTML;
updateResultCounts();
}
function clearInput(inputId) {
document.getElementById(inputId).value = '';
document.getElementById('results').innerHTML = '';
document.getElementById('result-count').textContent = '';
document.getElementById('exportButton').style.display = 'none';
lastResults = [];
}
async function searchCustomers() {
let searchTimeout;
const loading = document.getElementById('loading');
const results = document.getElementById('results');
const generalSearch = document.getElementById('q').value;
const nameSearch = document.getElementById('nameInput').value;
const ortSearch = document.getElementById('ortInput').value;
const nummerSearch = document.getElementById('nummerInput').value;
const plzSearch = document.getElementById('plzInput').value;
const fachrichtungSearch = document.getElementById('fachrichtungInput').value;
const tagFilter = document.getElementById('tagFilter').value;
currentSearchQuery = generalSearch;
currentPage = 1;
// Zeige Ladeanimation
loading.style.display = 'block';
results.innerHTML = '';
// Setze Timeout zurück
clearTimeout(searchTimeout);
// Verzögerte Suche
searchTimeout = setTimeout(async () => {
try {
// Baue die Suchanfrage
const params = new URLSearchParams();
if (generalSearch) params.append('q', generalSearch);
if (nameSearch) params.append('name', nameSearch);
if (ortSearch) params.append('ort', ortSearch);
if (nummerSearch) params.append('nummer', nummerSearch);
if (plzSearch) params.append('plz', plzSearch);
if (fachrichtungSearch) params.append('fachrichtung', fachrichtungSearch);
if (tagFilter) params.append('tag', tagFilter);
const response = await fetch('/search?' + params.toString());
if (!response.ok) {
throw new Error('Netzwerkantwort war nicht ok');
}
const data = await response.json();
displayResults(data);
} catch (error) {
results.innerHTML = '<p>Ein Fehler ist aufgetreten. Bitte versuchen Sie es später erneut.</p>';
} finally {
loading.style.display = 'none';
}
}, 300);
}
function setupFachrichtungAutocomplete() {
const fachrichtungInput = document.getElementById('fachrichtungInput');
const autocompleteList = document.createElement('div');
autocompleteList.className = 'autocomplete-items';
fachrichtungInput.parentNode.appendChild(autocompleteList);
fachrichtungInput.addEventListener('input', function() {
clearTimeout(fachrichtungTimeout);
const searchTerm = this.value;
if (searchTerm.length < 2) {
autocompleteList.style.display = 'none';
return;
}
fachrichtungTimeout = setTimeout(() => {
fetch(`/api/fachrichtungen?q=${encodeURIComponent(searchTerm)}`)
.then(response => response.json())
.then(data => {
autocompleteList.innerHTML = '';
if (data.length > 0) {
data.forEach(item => {
const div = document.createElement('div');
div.textContent = item;
div.addEventListener('click', () => {
fachrichtungInput.value = item;
autocompleteList.style.display = 'none';
searchCustomers();
});
autocompleteList.appendChild(div);
});
autocompleteList.style.display = 'block';
} else {
autocompleteList.style.display = 'none';
}
});
}, 300);
});
document.addEventListener('click', function(e) {
if (!fachrichtungInput.contains(e.target) && !autocompleteList.contains(e.target)) {
autocompleteList.style.display = 'none';
}
});
}
function setupOrtAutocomplete() {
const ortInput = document.getElementById('ortInput');
const autocompleteList = document.createElement('div');
autocompleteList.className = 'autocomplete-items';
ortInput.parentNode.appendChild(autocompleteList);
ortInput.addEventListener('input', function() {
clearTimeout(ortTimeout);
const searchTerm = this.value;
if (searchTerm.length < 2) {
autocompleteList.style.display = 'none';
return;
}
ortTimeout = setTimeout(() => {
fetch(`/api/orte?q=${encodeURIComponent(searchTerm)}`)
.then(response => response.json())
.then(data => {
autocompleteList.innerHTML = '';
if (data.length > 0) {
data.forEach(item => {
const div = document.createElement('div');
div.textContent = item;
div.addEventListener('click', () => {
ortInput.value = item;
autocompleteList.style.display = 'none';
searchCustomers();
});
autocompleteList.appendChild(div);
});
autocompleteList.style.display = 'block';
} else {
autocompleteList.style.display = 'none';
}
});
}, 300);
});
document.addEventListener('click', function(e) {
if (!ortInput.contains(e.target) && !autocompleteList.contains(e.target)) {
autocompleteList.style.display = 'none';
}
});
}
// Event-Listener für die URL-Parameter und Autocomplete-Setup
document.addEventListener('DOMContentLoaded', function() {
const urlParams = new URLSearchParams(window.location.search);
const kundennummer = urlParams.get('kundennummer');
const name = urlParams.get('name');
const ort = urlParams.get('ort');
const plz = urlParams.get('plz');
if (kundennummer) {
document.getElementById('nummerInput').value = kundennummer;
searchCustomers();
}
if (name) {
document.getElementById('nameInput').value = name;
searchCustomers();
}
if (ort) {
document.getElementById('ortInput').value = ort;
searchCustomers();
}
if (plz) {
document.getElementById('plzInput').value = plz;
searchCustomers();
}
// Setup Autocomplete
setupFachrichtungAutocomplete();
setupOrtAutocomplete();
});

View File

@@ -3,17 +3,54 @@
<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">
<meta name="client-ip" content="{{ request.headers.get('X-Forwarded-For', request.remote_addr) }}">
<meta name="allowed-ip-ranges" content="{{ allowed_ip_ranges }}">
<title>medisoftware Kundensuche</title> <title>medisoftware Kundensuche</title>
<link rel="icon" type="image/x-icon" href="{{ url_for('static', filename='favicon.ico') }}"> <link rel="icon" type="image/x-icon" href="{{ url_for('static', filename='favicon.ico') }}">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet"> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" rel="stylesheet"> <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
<link href="{{ url_for('static', filename='css/styles.css') }}" rel="stylesheet"> <link href="{{ url_for('static', filename='css/styles.css') }}" rel="stylesheet">
<style>
.logo {
width: 200px;
height: auto;
margin: 0 auto;
display: block;
}
</style>
</head> </head>
<body> <body>
<div class="main-content"> <div class="main-content">
<div class="container"> <div class="container">
<div class="text-center mb-4"> <div class="position-relative mb-4">
<a href="https://medisoftware.de" target="_blank" rel="noopener noreferrer"><img src="{{ url_for('static', filename='medisoftware_logo_rb_200.png') }}" alt="medisoftware Logo" class="img-fluid" style="max-width: 200px;"></a> <div class="dropdown position-absolute start-0">
<button class="btn btn-link text-dark" type="button" id="menuButton" data-bs-toggle="dropdown" aria-expanded="false">
<i class="bi bi-list fs-4"></i>
</button>
<ul class="dropdown-menu" aria-labelledby="menuButton">
<li>
<a class="dropdown-item" href="{{ url_for('index') }}">
<i class="bi bi-house"></i> Home
</a>
</li>
<li>
<a class="dropdown-item" href="{{ url_for('upload') }}">
<i class="bi bi-cloud-upload"></i> CSV-Dateien hochladen
</a>
</li>
<li>
<a class="dropdown-item" href="{{ url_for('readme') }}">
<i class="bi bi-book"></i> README
</a>
</li>
</ul>
</div>
<div class="text-center">
<a href="https://medisoftware.de" target="_blank" rel="noopener noreferrer">
<img src="{{ url_for('static', filename='medisoftware_logo_rb_200.png') }}" alt="medisoftware Logo" class="img-fluid logo">
</a>
</div>
</div> </div>
<div class="search-container"> <div class="search-container">
<h1 class="text-center mb-4">Kundensuche</h1> <h1 class="text-center mb-4">Kundensuche</h1>
@@ -24,16 +61,6 @@
<i class="fas fa-times reset-icon" onclick="clearInput('q')"></i> <i class="fas fa-times reset-icon" onclick="clearInput('q')"></i>
<i class="fas fa-search search-icon"></i> <i class="fas fa-search search-icon"></i>
</div> </div>
<div class="search-options mt-2">
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="searchOperator" id="searchOr" value="or" checked>
<label class="form-check-label" for="searchOr">ODER</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="searchOperator" id="searchAnd" value="and">
<label class="form-check-label" for="searchAnd">UND</label>
</div>
</div>
</div> </div>
<div class="search-fields"> <div class="search-fields">
@@ -88,8 +115,11 @@
</div> </div>
</div> </div>
<div class="result-counts"> <div id="result-counts" class="mt-2">
<span id="resultCount" class="result-count"></span> <span id="result-count"></span>
<button id="exportButton" class="btn btn-sm btn-outline-primary ms-2" onclick="exportToCSV()" style="display: none;">
<i class="bi bi-file-earmark-spreadsheet"></i> Als CSV exportieren
</button>
</div> </div>
<div id="loading" class="loading"> <div id="loading" class="loading">
@@ -110,272 +140,11 @@
<footer class="footer"> <footer class="footer">
<div class="footer-content"> <div class="footer-content">
Proudly made with ❤️ and 🍺 by <a href="https://www.medisoftware.de" target="_blank" class="footer-link">medisoftware</a> Proudly made with ❤️ and 🍺 by <a href="https://www.medisoftware.de" target="_blank" class="footer-link">medisoftware</a>
<div style="font-size: 0.8em;">Version: v1.2.6</div> <div style="font-size: 0.8em;">Version: {{ version }}</div>
</div> </div>
</footer> </footer>
<script> <script src="{{ url_for('static', filename='js/main.js') }}"></script>
let searchTimeout; <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
let lastResults = [];
function createPhoneLink(phone) {
if (!phone) return 'N/A';
const clientIP = '{{ request.headers.get("X-Forwarded-For", request.remote_addr) }}';
const allowedIPRanges = '{{ allowed_ip_ranges }}'.split(',');
// Überprüfen, ob die Client-IP in einem der erlaubten Bereiche liegt
const isAllowed = allowedIPRanges.some(range => isIPInSubnet(clientIP, range.trim()));
// Entferne alle nicht-numerischen Zeichen
let cleanNumber = phone.replace(/\D/g, '');
// Formatiere die Nummer
let formattedNumber = cleanNumber;
if (cleanNumber.length === 11) {
formattedNumber = cleanNumber.replace(/(\d{4})(\d{7})/, '$1-$2');
} else if (cleanNumber.length === 10) {
formattedNumber = cleanNumber.replace(/(\d{3})(\d{7})/, '$1-$2');
}
// Erstelle den Link
return `<a href="tel:${cleanNumber}" class="phone-link">${formattedNumber}</a>`;
}
function createEmailLink(email) {
if (!email) return 'N/A';
return `<a href="mailto:${email}" class="email-link">${email}</a>`;
}
function highlightText(text, searchTerm) {
if (!searchTerm) return text;
const regex = new RegExp(`(${searchTerm})`, 'gi');
return text.replace(regex, '<mark>$1</mark>');
}
function createAddressLink(street, plz, city) {
if (!street || !plz || !city) return 'N/A';
const address = `${street}, ${plz} ${city}`;
const searchQuery = encodeURIComponent(address);
const routeQuery = encodeURIComponent(address);
const clientIP = '{{ request.headers.get("X-Forwarded-For", request.remote_addr) }}';
return `<span class="address-text">${address}</span>
<a href="https://www.google.com/maps/search/?api=1&query=${searchQuery}"
class="address-link" target="_blank" rel="noopener noreferrer">
<i class="fa-solid fa-location-pin location-pin"></i>
</a>
<a href="https://www.google.com/maps/dir/?api=1&destination=${routeQuery}"
class="route-link" target="_blank" rel="noopener noreferrer">
<i class="fa-solid fa-car route-pin"></i>
</a>`;
}
function adjustCustomerNumber(number) {
return number - 12000;
}
function isIPInSubnet(ip, subnet) {
// Teile die IP und das Subnetz in ihre Komponenten
const [subnetIP, bits] = subnet.split('/');
const ipParts = ip.split('.').map(Number);
const subnetParts = subnetIP.split('.').map(Number);
// Konvertiere IPs in 32-bit Zahlen
const ipNum = (ipParts[0] << 24) | (ipParts[1] << 16) | (ipParts[2] << 8) | ipParts[3];
const subnetNum = (subnetParts[0] << 24) | (subnetParts[1] << 16) | (subnetParts[2] << 8) | subnetParts[3];
// Erstelle die Subnetzmaske
const mask = ~((1 << (32 - bits)) - 1);
// Prüfe, ob die IP im Subnetz liegt
return (ipNum & mask) === (subnetNum & mask);
}
function createCustomerLink(nummer) {
const clientIP = '{{ request.headers.get("X-Forwarded-For", request.remote_addr) }}';
const allowedIPRanges = '{{ allowed_ip_ranges }}'.split(',');
// Überprüfe, ob die Client-IP in einem der erlaubten Bereiche liegt
const isAllowed = allowedIPRanges.some(range => {
const trimmedRange = range.trim();
return isIPInSubnet(clientIP, trimmedRange);
});
const adjustedNumber = adjustCustomerNumber(nummer);
if (isAllowed) {
return `<a href="medisw:openkkbefe/P${adjustedNumber}?NetGrp=4" class="customer-link">${nummer}</a>`;
} else {
return nummer;
}
}
function showCopyFeedback() {
const feedback = document.getElementById('shareFeedback');
feedback.style.display = 'block';
feedback.style.opacity = '1';
feedback.addEventListener('animationend', () => {
feedback.style.display = 'none';
}, { once: true });
}
async function copyCustomerLink(customerNumber) {
const url = new URL(window.location.href);
url.searchParams.set('kundennummer', customerNumber);
try {
await navigator.clipboard.writeText(url.toString());
showCopyFeedback();
} catch (err) {
// Fehlerbehandlung ohne console.log
}
}
function updateResultCounts() {
// Nur Gesamtzahl anzeigen
const generalCount = lastResults.length;
document.getElementById('resultCount').textContent =
generalCount > 0 ? `${generalCount} Treffer gefunden` : '';
document.getElementById('resultCount').classList.toggle('visible', generalCount > 0);
}
function displayResults(results) {
const resultsDiv = document.getElementById('results');
const resultCount = document.getElementById('resultCount');
if (results.length === 0) {
resultsDiv.innerHTML = '<p>Keine Ergebnisse gefunden.</p>';
resultCount.textContent = '0 Ergebnisse';
return;
}
resultCount.textContent = `${results.length} Ergebnisse`;
const resultsList = results.map(customer => `
<div class="card mb-3">
<div class="card-body">
<div class="d-flex justify-content-between align-items-start">
<h5 class="card-title">${customer.name}</h5>
<button class="btn btn-sm btn-outline-primary" onclick="copyCustomerLink('${customer.nummer}')">
<i class="fas fa-share-alt"></i> Teilen
</button>
</div>
<div class="card-text">
<p><strong>Nummer:</strong> ${customer.nummer}</p>
<p><strong>Adresse:</strong> ${customer.strasse}, ${customer.plz} ${customer.ort}</p>
<p><strong>Telefon:</strong> ${createPhoneLink(customer.telefon)}</p>
<p><strong>Mobil:</strong> ${createPhoneLink(customer.mobil)}</p>
<p><strong>E-Mail:</strong> ${createEmailLink(customer.email)}</p>
<p><strong>Fachrichtung:</strong> ${customer.fachrichtung}</p>
${customer.tags && customer.tags.length > 0 ? `
<p><strong>Tags:</strong>
${customer.tags.map(tag => `<span class="badge bg-primary me-1">${tag}</span>`).join('')}
</p>
` : ''}
</div>
</div>
</div>
`).join('');
resultsDiv.innerHTML = resultsList;
}
function searchCustomers() {
const q = document.getElementById('q').value;
const name = document.getElementById('nameInput').value;
const ort = document.getElementById('ortInput').value;
const nummer = document.getElementById('nummerInput').value;
const plz = document.getElementById('plzInput').value;
const fachrichtung = document.getElementById('fachrichtungInput').value;
const searchOperator = document.querySelector('input[name="searchOperator"]:checked').value;
const selectedTag = document.getElementById('tagFilter').value;
// Zeige das Lade-Icon
document.getElementById('loading').style.display = 'block';
// Baue die Suchanfrage
const params = new URLSearchParams();
if (q) params.append('q', q);
if (name) params.append('name', name);
if (ort) params.append('ort', ort);
if (nummer) params.append('nummer', nummer);
if (plz) params.append('plz', plz);
if (fachrichtung) params.append('fachrichtung', fachrichtung);
if (searchOperator) params.append('operator', searchOperator);
if (selectedTag) params.append('tag', selectedTag);
// Führe die Suche durch
fetch('/search?' + params.toString())
.then(response => response.json())
.then(data => {
// Verstecke das Lade-Icon
document.getElementById('loading').style.display = 'none';
if (data.error) {
return;
}
lastResults = data;
updateResultCounts();
displayResults(data);
})
.catch(error => {
document.getElementById('loading').style.display = 'none';
});
}
// Event-Listener für die Live-Suche
const searchInputs = [
document.getElementById('q'),
document.getElementById('nameInput'),
document.getElementById('ortInput'),
document.getElementById('nummerInput'),
document.getElementById('plzInput'),
document.getElementById('fachrichtungInput')
];
const resetIcons = [
document.querySelector('.reset-icon[onclick="clearInput(\'q\')"]'),
document.querySelector('.reset-icon[onclick="clearInput(\'nameInput\')"]'),
document.querySelector('.reset-icon[onclick="clearInput(\'ortInput\')"]'),
document.querySelector('.reset-icon[onclick="clearInput(\'nummerInput\')"]'),
document.querySelector('.reset-icon[onclick="clearInput(\'plzInput\')"]'),
document.querySelector('.reset-icon[onclick="clearInput(\'fachrichtungInput\')"]')
];
searchInputs.forEach((input, index) => {
input.addEventListener('input', function() {
clearTimeout(searchTimeout);
searchTimeout = setTimeout(searchCustomers, 300);
// Reset-Icon anzeigen/verstecken
resetIcons[index].classList.toggle('visible', this.value.length > 0);
});
// Reset-Funktionalität
resetIcons[index].addEventListener('click', function() {
searchInputs[index].value = '';
searchCustomers();
});
});
// URL-Parameter beim Laden der Seite prüfen
window.addEventListener('load', function() {
const urlParams = new URLSearchParams(window.location.search);
const name = urlParams.get('name');
const ort = urlParams.get('ort');
const kundennummer = urlParams.get('kundennummer');
const plz = urlParams.get('plz');
if (name) document.getElementById('nameInput').value = name;
if (ort) document.getElementById('ortInput').value = ort;
if (kundennummer) document.getElementById('nummerInput').value = kundennummer;
if (plz) document.getElementById('plzInput').value = plz;
if (name || ort || kundennummer || plz) {
searchCustomers();
}
});
</script>
</body> </body>
</html> </html>

111
templates/readme.html Normal file
View File

@@ -0,0 +1,111 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>medisoftware Kundensuche - README</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
<link href="{{ url_for('static', filename='css/styles.css') }}" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/github-markdown-css@5.5.0/github-markdown.min.css">
<style>
body {
min-height: 100vh;
display: flex;
flex-direction: column;
margin: 0;
padding: 0;
}
.main-content {
flex: 1 0 auto;
padding: 2rem 0;
margin-bottom: 4rem;
}
.footer {
flex-shrink: 0;
text-align: center;
padding: 1rem;
background-color: #f8f9fa;
border-top: 1px solid #dee2e6;
width: 100%;
position: fixed;
bottom: 0;
left: 0;
z-index: 100;
}
.markdown-body {
box-sizing: border-box;
min-width: 200px;
max-width: 980px;
margin: 0 auto;
padding: 45px;
}
@media (max-width: 767px) {
.markdown-body {
padding: 15px;
}
}
</style>
</head>
<body>
<div class="main-content">
<div class="container">
<div class="d-flex justify-content-between align-items-center mb-4">
<div class="dropdown">
<button class="btn btn-link text-dark" type="button" id="menuButton" data-bs-toggle="dropdown" aria-expanded="false">
<i class="bi bi-list fs-4"></i>
</button>
<ul class="dropdown-menu" aria-labelledby="menuButton">
<li>
<a class="dropdown-item" href="{{ url_for('index') }}">
<i class="bi bi-house"></i> Home
</a>
</li>
<li>
<a class="dropdown-item" href="{{ url_for('upload') }}">
<i class="bi bi-cloud-upload"></i> CSV-Dateien hochladen
</a>
</li>
<li>
<a class="dropdown-item" href="{{ url_for('readme') }}">
<i class="bi bi-book"></i> README
</a>
</li>
</ul>
</div>
<a href="https://medisoftware.de" target="_blank" rel="noopener noreferrer">
<img src="{{ url_for('static', filename='medisoftware_logo_rb_200.png') }}" alt="medisoftware Logo" class="img-fluid" style="max-width: 200px;">
</a>
</div>
<div class="card">
<div class="card-header">
<h2 class="text-center mb-0">README</h2>
</div>
<div class="card-body">
{% if error %}
<div class="alert alert-danger" role="alert">
{{ error }}
</div>
{% else %}
<div class="markdown-body">
{{ content | safe }}
</div>
{% endif %}
</div>
</div>
</div>
</div>
<footer class="footer">
<div class="footer-content">
Proudly made with ❤️ and 🍺 by <a href="https://www.medisoftware.de" target="_blank" class="footer-link">medisoftware</a>
<div style="font-size: 0.8em;">Version: {{ version }}</div>
</div>
</footer>
<script src="{{ url_for('static', filename='js/main.js') }}"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

102
templates/upload.html Normal file
View File

@@ -0,0 +1,102 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>medisoftware Kundensuche - CSV Upload</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
<style>
body {
background-color: #f8f9fa;
}
.main-content {
padding: 2rem 0;
}
.logo {
width: 200px;
height: auto;
margin: 0 auto;
display: block;
}
.upload-container {
background-color: white;
padding: 2rem;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0,0,0,0.1);
}
.form-label {
font-weight: 500;
}
.alert {
margin-bottom: 1rem;
}
</style>
</head>
<body>
<div class="main-content">
<div class="container">
<div class="position-relative mb-4">
<div class="dropdown position-absolute start-0">
<button class="btn btn-link text-dark" type="button" id="menuButton" data-bs-toggle="dropdown" aria-expanded="false">
<i class="bi bi-list fs-4"></i>
</button>
<ul class="dropdown-menu" aria-labelledby="menuButton">
<li>
<a class="dropdown-item" href="{{ url_for('index') }}">
<i class="bi bi-house"></i> Home
</a>
</li>
<li>
<a class="dropdown-item" href="{{ url_for('upload') }}">
<i class="bi bi-cloud-upload"></i> CSV-Dateien hochladen
</a>
</li>
<li>
<a class="dropdown-item" href="{{ url_for('readme') }}">
<i class="bi bi-book"></i> README
</a>
</li>
</ul>
</div>
<div class="text-center">
<a href="https://medisoftware.de" target="_blank" rel="noopener noreferrer">
<img src="{{ url_for('static', filename='medisoftware_logo_rb_200.png') }}" alt="medisoftware Logo" class="img-fluid logo">
</a>
</div>
</div>
<div class="upload-container">
<div class="row justify-content-center">
<div class="col-md-6">
<h2 class="text-center mb-4">CSV-Dateien hochladen</h2>
{% if error %}
<div class="alert alert-danger">{{ error }}</div>
{% endif %}
{% if success %}
<div class="alert alert-success">{{ success }}</div>
{% endif %}
<form method="POST" enctype="multipart/form-data">
<div class="mb-3">
<label for="medisoft_file" class="form-label">MEDISOFT CSV-Datei</label>
<input type="file" class="form-control" id="medisoft_file" name="medisoft_file" accept=".csv">
</div>
<div class="mb-3">
<label for="mediconsult_file" class="form-label">MEDICONSULT CSV-Datei</label>
<input type="file" class="form-control" id="mediconsult_file" name="mediconsult_file" accept=".csv">
</div>
<div class="mb-3">
<label for="password" class="form-label">Passwort</label>
<input type="password" class="form-control" id="password" name="password" required>
</div>
<div class="d-grid">
<button type="submit" class="btn btn-primary">Dateien hochladen</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>