5 Commits

4 changed files with 120 additions and 160 deletions

View File

@@ -5,49 +5,37 @@ 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/),
und dieses Projekt adhäriert zu [Semantic Versioning](https://semver.org/lang/de/).
## [1.0.2] - 2024-03-19
### Hinzugefügt
- Wetterinformationen für jeden Suchtreffer
- Integration der OpenWeather API
- Wetter-Icons und Temperaturanzeige
- Umgebungsvariablen für API-Keys
## [1.0.6] - 2024-03-17
### Geändert
- Anpassung der API-Antwortstruktur
- Verbesserte Fehlerbehandlung für API-Anfragen
## [1.0.1] - 2024-03-19
### Hinzugefügt
- Neues Suchfeld für Telefonnummer
- Reset-Icons für alle Suchfelder
- Trefferzähler für Suchergebnisse
- Verbesserte Suchfunktion: Kombinierte Suche über mehrere Felder möglich
- Dokumentation: Beispiele für kombinierte Suche hinzugefügt
## [1.0.5] - 2024-03-17
### Geändert
- Verbesserte Positionierung der UI-Elemente
- Optimierte Suchlogik im Backend
- CSV-Datei in data-Verzeichnis verschoben
- Allgemeine Suche um Telefonnummer erweitert
- Verbesserte Suchfunktion: Ergebnisliste wird gelöscht, wenn alle Suchfelder leer sind
### Behoben
- Korrektur der Icon-Anzeige in Suchfeldern
- Verbesserte Fehlerbehandlung beim Laden der CSV-Datei
## [1.0.4] - 2024-03-17
### Geändert
- Verbesserte Adressanzeige: Location-Icon neben der Adresse
- Entfernung des Google Maps Links aus dem Adresstext
## [1.0.0] - 2024-03-18
## [1.0.3] - 2024-03-17
### Geändert
- Hervorhebung der Suchbegriffe in den Ergebnissen
- Verbesserte Benutzeroberfläche
## [1.0.2] - 2024-03-17
### Geändert
- Entfernung der Wetterinformationen
- Optimierung der Suchfunktion
## [1.0.1] - 2024-03-17
### Hinzugefügt
- Grundlegende Suchfunktionalität
- Spezifische Suchfelder für:
- Name
- Ort
- Kundennummer
- Fachrichtung
- Allgemeine Suche über alle Felder
- Klickbare Links für:
- Telefonnummern
- E-Mail-Adressen
- Google Maps Integration
- Share-Funktion für Suchergebnisse
- Responsive Design mit Bootstrap
- Live-Suche während der Eingabe
- Wetterinformationen für Kundensitz
- Caching für Wetterdaten
## [1.0.0] - 2024-03-17
### Hinzugefügt
- Erste Version der Kundensuche
- Grundlegende Suchfunktionen
- Responsive Design

120
README.md
View File

@@ -1,23 +1,27 @@
# medisoftware Kundensuche
Eine Webanwendung zur Suche in Kundendaten der medisoftware.
Eine webbasierte Kundensuche für medisoftware mit erweiterten Suchfunktionen.
## Features
- Live-Suche in Kundendaten
- Spezifische Suchfelder für:
- Name
- Schnelle und präzise Kundensuche
- Mehrere Suchfelder für gezielte Suche:
- Name (Vor- und Nachname)
- Ort
- Kundennummer
- Fachrichtung
- Telefonnummer
- Telefon
- Allgemeine Suche über alle Felder
- Klickbare Telefonnummern
- Klickbare E-Mail-Adressen
- Google Maps Integration für Adressen
- Share-Funktion für Suchergebnisse
- Trefferzähler
- Reset-Funktion für alle Suchfelder
- Kombinierte Suche über mehrere Felder
- Hervorhebung der Suchbegriffe in den Ergebnissen
- Direkte Links zu:
- medisoftware Kundenkartei (Kundennummer)
- Google Maps (Adresse)
- Telefon (Klick zum Anrufen)
- E-Mail (Klick zum Mailen)
- Responsive Design für alle Geräte
- Automatische Aktualisierung der Ergebnisse
- Leere Ergebnisliste bei leeren Suchfeldern
## Installation
@@ -27,81 +31,69 @@ git clone https://gitea.elpatron.me/elpatron/medi-customers.git
cd medi-customers
```
2. Python-Abhängigkeiten installieren:
2. Docker Container starten:
```bash
pip install -r requirements.txt
docker-compose up -d
```
3. CSV-Datei in das `data`-Verzeichnis kopieren:
```bash
mkdir data
cp spezexpo.csv data/customers.csv
```
3. Die Anwendung ist unter `http://localhost:5001` erreichbar.
4. Anwendung starten:
```bash
python app.py
```
## Entwicklung
Die Anwendung ist dann unter `http://localhost:5001` erreichbar.
- Python 3.11
- Flask
- Docker
- Bootstrap 5
- Font Awesome
## Lizenz
Alle Rechte vorbehalten. © 2025 medisoftware
## API-Beispiele
Die Such-API unterstützt folgende Parameter:
### Spezifische Suche
### Suche nach Name
```bash
# Nach Name suchen
curl "http://localhost:5001/search?name=Schmidt"
curl "http://localhost:5001/search?name=Mustermann"
```
# Nach Ort suchen
### Suche nach Ort
```bash
curl "http://localhost:5001/search?ort=Berlin"
```
# Nach Kundennummer suchen
### Suche nach Kundennummer
```bash
curl "http://localhost:5001/search?kundennummer=12345"
```
# Nach Fachrichtung suchen
curl "http://localhost:5001/search?fachrichtung=Allgemeinmedizin"
### Suche nach Fachrichtung
```bash
curl "http://localhost:5001/search?fachrichtung=Zahnarzt"
```
# Nach Telefonnummer suchen
### Suche nach Telefon
```bash
curl "http://localhost:5001/search?telefon=030"
# Kombinierte Suche
curl "http://localhost:5001/search?name=Schmidt&ort=Berlin&fachrichtung=Allgemeinmedizin"
```
### Allgemeine Suche
```bash
# Suche in allen Feldern
curl "http://localhost:5001/search?q=Schmidt"
curl "http://localhost:5001/search?q=Suchbegriff"
```
### Beispiel-Response
```json
[
{
"Vorname": "Max",
"Nachname": "Mustermann",
"Nummer": "12345",
"Ort": "Berlin",
"Fachrichtung": "Allgemeinmedizin",
"Tel": "030123456",
"Email": "max@example.com"
}
]
### Kombinierte Suche
```bash
# Suche nach Fachrichtung und Ort
curl "http://localhost:5001/search?fachrichtung=Zahnarzt&ort=Berlin"
# Suche nach Name und Telefon
curl "http://localhost:5001/search?name=Mustermann&telefon=030"
# Suche nach mehreren Kriterien
curl "http://localhost:5001/search?fachrichtung=Zahnarzt&ort=Berlin&name=Schmidt"
```
## Versionen
## Version
### v1.0.1
- Telefonnummer-Suchfeld hinzugefügt
- Reset-Icons für alle Suchfelder
- Verbesserte Positionierung der UI-Elemente
- Optimierte Suchlogik
- CSV-Datei in data-Verzeichnis verschoben
### v1.0.0
- Erste Version
- Grundlegende Suchfunktionalität
- Klickbare Links für Telefon, E-Mail und Adressen
- Share-Funktion für Suchergebnisse
Aktuelle Version: [1.0.5](CHANGELOG.md#105---2024-03-17)

17
app.py
View File

@@ -13,7 +13,7 @@ logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)
# Version der Anwendung
VERSION = "1.0.5"
VERSION = "1.0.6"
# Pfad zur CSV-Datei
CSV_FILE = "data/customers.csv"
@@ -68,10 +68,12 @@ def search():
telefon = request.args.get('telefon', '').strip()
query = request.args.get('q', '').strip()
# Wenn keine spezifischen Suchkriterien angegeben sind, aber eine allgemeine Suche
if not any([name, ort, kundennummer, fachrichtung, telefon]) and query:
# Suche in allen relevanten Feldern
mask = (
# Initialisiere die Maske für die Filterung
mask = pd.Series(True, index=df.index)
# Wenn eine allgemeine Suche angegeben ist
if query:
query_mask = (
df['Vorname'].str.contains(query, case=False, na=False) |
df['Nachname'].str.contains(query, case=False, na=False) |
df['Ort'].str.contains(query, case=False, na=False) |
@@ -79,10 +81,9 @@ def search():
df['Fachrichtung'].str.contains(query, case=False, na=False) |
df['Tel'].astype(str).str.contains(query, case=False, na=False)
)
else:
# Spezifische Suche
mask = pd.Series(True, index=df.index)
mask &= query_mask
# Spezifische Suchkriterien anwenden
if name:
name_mask = (
df['Vorname'].str.contains(name, case=False, na=False) |

View File

@@ -139,18 +139,6 @@
margin-left: 4px;
font-size: 1.2em;
}
.weather-info {
display: inline-flex;
align-items: center;
margin-left: 10px;
font-size: 0.9em;
color: #666;
}
.weather-info img {
width: 24px;
height: 24px;
margin-right: 4px;
}
</style>
</head>
<body>
@@ -246,10 +234,7 @@
function createCustomerLink(customerNumber) {
if (!customerNumber) return 'N/A';
return `<a href="medisw:openkkbefe/P${customerNumber}?NetGrp=4"
class="customer-link" target="_blank" rel="noopener noreferrer">
${customerNumber}
</a>`;
return `<a href="medisw:openkkbefe/P${customerNumber}?NetGrp=4" class="customer-link">${customerNumber}</a>`;
}
function showCopyFeedback() {
@@ -326,22 +311,16 @@
data.results.forEach(customer => {
const card = document.createElement('div');
card.className = 'card mb-3';
const customerLink = createCustomerLink(customer.Nummer);
console.log('Customer:', customer); // Debug-Ausgabe
console.log('Customer link:', customerLink); // Debug-Ausgabe
card.innerHTML = `
<div class="card-body">
<h5 class="card-title">${customer.Vorname} ${customer.Nachname}</h5>
<p class="card-text">
<strong>Kundennummer:</strong> ${customer.Nummer}<br>
<strong>Kundennummer:</strong> ${customerLink}<br>
<strong>Fachrichtung:</strong> ${customer.Fachrichtung || 'N/A'}<br>
<strong>Adresse:</strong> ${createAddressLink(customer.Strasse, customer.PLZ, customer.Ort)}
${customer.weather ? `
<span class="weather-info">
<img src="http://openweathermap.org/img/wn/${customer.weather.icon}@2x.png"
alt="${customer.weather.description}"
title="${customer.weather.description}">
${customer.weather.temperature}°C
</span>
` : ''}
<br>
<strong>Adresse:</strong> ${createAddressLink(customer.Strasse, customer.PLZ, customer.Ort)}<br>
<strong>Telefon:</strong> ${createPhoneLink(customer.Tel)}<br>
<strong>E-Mail:</strong> ${createEmailLink(customer.mail)}
</p>