Compare commits
5 Commits
Author | SHA1 | Date | |
---|---|---|---|
6cfc2e0162 | |||
bbcd04fd21 | |||
89a5152ada | |||
e6f43ca10a | |||
da3ef358d2 |
66
CHANGELOG.md
66
CHANGELOG.md
@@ -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
120
README.md
@@ -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
17
app.py
@@ -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) |
|
||||
|
@@ -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>
|
||||
|
Reference in New Issue
Block a user