Rufnummernsuche auf den Altbestand user_old ausweiten

Die Suche lief nur gegen persons und fand deshalb den Anrufer von Anfrage
13037 nicht: dessen Mobilnummer steht in user_old, in persons ist zu
derselben Person nur eine aeltere siebenstellige Nummer gepflegt. Beide
Zeilen sind ueber tmp_user_person_map korrekt verknuepft (userid 3204 ->
person_id 2266), die Rufnummer ist bei der Migration schlicht nicht
nachgezogen worden.

Das ist kein Einzelfall. Von 2552 gemappten Paaren weicht bei 122 die
Nummer ab, 87 Nummern stehen ausschliesslich in user_old, und 176 alte
Zeilen haben gar kein Mapping. persons ist damit keine Obermenge, und die
Suche allein darueber verfehlt 87 der 2739 bekannten Rufnummern.

Der Index wird jetzt aus beiden Tabellen aufgebaut. Findet sich zu einer
alten Zeile ein aktueller Datensatz, werden dessen Daten gezeigt - die
Nummer ist nur der Schluessel, angezeigt gehoert der gepflegte Stand. Der
Vorschlag weist aus, wenn die Nummer aus dem Altbestand stammt, und
unterscheidet den Fall ohne aktuellen Datensatz.

Ein Patient darf je Nummer nur einmal erscheinen. Die Personen-ID reicht
dafuer nicht: nicht gemappte Altzeilen haben eine eigene userid und standen
dadurch neben ihrem persons-Gegenstueck, sichtbar als "2 Patienten:
Andreas Busche, Andreas Busche". Zweiter Schluessel ist deshalb Name plus
Geburtstag. Der Vergleich traegt hier, weil ohnehin nur Eintraege zu ein und
derselben Rufnummer verglichen werden - ueber den Gesamtbestand waere er
unbrauchbar, weil 0000-00-00 als Geburtstag massenhaft vorkommt.

Nachgeprueft ueber alle 2739 bekannten Rufnummern: jede liefert einen
Treffer, keine einzige eine doppelte Identitaet, groesste Trefferzahl 16 an
einer Nummer. 87 Nummern sind neu auffindbar, darunter die von Anfrage
13037, die jetzt korrekt auf person_id 2266 zeigt. Listenlogik ueber alle
12793 Anfragen unveraendert fehlerfrei; der Vorschlag steht weiterhin nie
bei einer Anfrage mit bereits zugeordnetem Patienten. Kosten bleiben zwei
Abfragen je Seitenaufruf, unabhaengig von der Zeilenzahl.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-08 21:09:53 +02:00
co-authored by Claude Opus 5
parent 53cff55ac2
commit e7955e354c
+81 -11
View File
@@ -715,13 +715,23 @@ function NormalisiereRufnummer($nummer){
/**
* Patienten zu einer Rufnummer suchen.
*
* Liefert alle passenden Zeilen aus persons - bewusst alle, denn 521 der
* 2972 gepflegten Nummern gehoeren zu mehr als einer Person (Familien, zwei
* Nummern sogar zu 16 bzw. 18). Die Auswahl trifft die Mitarbeiterin, nicht
* der Code.
* Gesucht wird in persons UND im Altbestand user_old. persons allein reicht
* nicht: bei 122 der 2552 migrierten Paare weicht die Nummer ab, 87 Nummern
* stehen ausschliesslich in user_old, und 176 alte Zeilen wurden nie
* gemappt. Genau so ein Fall war Anfrage 13037 - die Mobilnummer stand nur
* im Altbestand, in persons nur eine aeltere siebenstellige.
*
* Nummern mit weniger als 7 Ziffern werden nicht gesucht: in persons stehen
* ein paar Platzhalter mit 1 bis 5 Ziffern, die sonst wahllos zusammenfallen.
* Gibt es zu einer alten Zeile einen aktuellen Datensatz, werden dessen
* Daten gezeigt: die Nummer ist nur der Schluessel, angezeigt gehoert der
* gepflegte Stand. Jeder Patient taucht je Nummer hoechstens einmal auf.
*
* Liefert bewusst alle Treffer, denn 521 der gepflegten Nummern gehoeren zu
* mehr als einer Person (Familien, zwei sogar zu 16 bzw. 18). Die Auswahl
* trifft die Mitarbeiterin, nicht der Code.
*
* Nummern mit weniger als 7 Ziffern werden nicht gesucht: in den Stammdaten
* stehen ein paar Platzhalter mit 1 bis 5 Ziffern, die sonst wahllos
* zusammenfallen.
*
* Der Index wird beim ersten Treffer einmal je Seitenaufruf aufgebaut und
* danach wiederverwendet - die Anfrageliste zeigt bis zu einige tausend
@@ -737,14 +747,61 @@ function FindePatientenZuRufnummer($pdo, $nummer){
if($index === null){
$index = array();
$gesehen = array();
$aufnehmen = function($nummerRoh, $schluessel, $eintrag) use (&$index, &$gesehen){
$n = NormalisiereRufnummer($nummerRoh);
if(strlen($n) < 7){
return;
}
// Zweiter Schluessel ueber Name und Geburtstag: nicht gemappte
// Altzeilen haben eine eigene userid, sind aber oft dieselbe
// Person wie ein persons-Datensatz. Ohne das stuende sie zweimal
// in der Liste. Der Vergleich traegt hier, weil ohnehin nur
// Eintraege zu ein und derselben Rufnummer verglichen werden.
$identitaet = "id:" . mb_strtolower(trim((string)$eintrag["vorname"]) . "|"
. trim((string)$eintrag["nachname"]) . "|" . (string)$eintrag["geburtstag"]);
if(isset($gesehen[$n][$schluessel]) || isset($gesehen[$n][$identitaet])){
return;
}
$gesehen[$n][$schluessel] = true;
$gesehen[$n][$identitaet] = true;
$index[$n][] = $eintrag;
};
$stmt = $pdo->query("SELECT person_id, vorname, nachname, geburtstag, email, tele
FROM persons WHERE tele IS NOT NULL AND tele <> ''");
foreach($stmt as $p){
$n = NormalisiereRufnummer($p["tele"]);
if(strlen($n) < 7){
continue;
}
$index[$n][] = $p;
$aufnehmen($p["tele"], "p" . $p["person_id"], array(
"person_id" => $p["person_id"],
"vorname" => $p["vorname"],
"nachname" => $p["nachname"],
"geburtstag" => $p["geburtstag"],
"email" => $p["email"],
"altbestand" => false,
));
}
$stmt = $pdo->query("SELECT u.userid, u.tele,
p.person_id AS person_id,
COALESCE(p.vorname, u.vorname) AS vorname,
COALESCE(p.nachname, u.nachname) AS nachname,
COALESCE(p.geburtstag, u.geburtstag) AS geburtstag,
COALESCE(p.email, u.mail) AS email
FROM user_old u
LEFT JOIN tmp_user_person_map m ON m.old_userid = u.userid
LEFT JOIN persons p ON p.person_id = m.person_id
WHERE u.tele IS NOT NULL AND u.tele <> ''");
foreach($stmt as $u){
$pid = $u["person_id"] !== null ? (int)$u["person_id"] : null;
$aufnehmen($u["tele"], $pid !== null ? "p" . $pid : "u" . $u["userid"], array(
"person_id" => $pid,
"vorname" => $u["vorname"],
"nachname" => $u["nachname"],
"geburtstag" => $u["geburtstag"],
"email" => $u["email"],
"altbestand" => true,
));
}
}
@@ -773,9 +830,13 @@ function GetPatientZuRufnummerAusgabe($pdo, $source, $anrufernummer, $personId =
}
$namen = array();
$ausAltbestand = false;
foreach($treffer as $p){
$name = trim(((string)$p["vorname"]) . " " . ((string)$p["nachname"]));
$namen[] = htmlspecialchars($name, ENT_QUOTES, 'UTF-8');
if(!empty($p["altbestand"])){
$ausAltbestand = true;
}
}
if(count($treffer) === 1){
@@ -796,6 +857,12 @@ function GetPatientZuRufnummerAusgabe($pdo, $source, $anrufernummer, $personId =
$text .= "<br>" . htmlspecialchars($mail, ENT_QUOTES, 'UTF-8');
}
if(!empty($p["altbestand"])){
$text .= $p["person_id"] === null
? "<br><i>nur im alten Bestand, kein aktueller Patientendatensatz</i>"
: "<br><i>Rufnummer stammt aus dem alten Bestand</i>";
}
return $text . "<br><i>nicht bestätigt - nur über die Rufnummer erkannt</i><br>";
}
@@ -804,6 +871,9 @@ function GetPatientZuRufnummerAusgabe($pdo, $source, $anrufernummer, $personId =
if(count($namen) > count($gezeigt)){
$text .= " und " . (count($namen) - count($gezeigt)) . " weiteren";
}
if($ausAltbestand){
$text .= "<br><i>teilweise über den alten Bestand gefunden</i>";
}
return $text . "<br><i>nicht zugeordnet - bitte selbst prüfen</i><br>";
}