PayPal-Name aus der manuellen Zuordnung lernen
Die automatische Zuordnung verlangt exakte Uebereinstimmung des Zahlernamens mit Anzeigename oder PayPal-Name des Mitglieds. Heisst jemand bei PayPal anders, landet jede Zahlung in der Warteschlange - auch die zehnte, obwohl der Fall laengst einmal von Hand geklaert wurde. Nach einer manuellen Zuordnung wird der Zahlername deshalb beim Mitglied hinterlegt. Zurueckhaltend: ein gepflegter PayPal-Name wird nie ueberschrieben, ein Name gleich dem Anzeigenamen bringt nichts, und passt der Name auch auf ein anderes Mitglied, wird nichts gelernt - das wuerde die Zuordnung mehrdeutig machen und damit blockieren. Was gelernt wurde, steht in der Erfolgsmeldung und im Audit-Log; eine stillschweigende Aenderung am Mitglied waere sonst schwer nachvollziehbar. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+59
-1
@@ -334,6 +334,52 @@ function paypal_fetch_unmatched(PDO $pdo, int $tenantId): array
|
||||
*
|
||||
* @return array{ok:bool, error?:string}
|
||||
*/
|
||||
/**
|
||||
* Soll der Zahlername als PayPal-Name beim Mitglied hinterlegt werden?
|
||||
* Liefert den zu speichernden Namen oder null, wenn nichts zu lernen ist.
|
||||
*
|
||||
* Zurueckhaltend absichtlich: ein bereits gepflegter PayPal-Name wird nie
|
||||
* ueberschrieben, ein Name gleich dem Anzeigenamen bringt nichts (der wird
|
||||
* ohnehin geprueft), und wenn der Name im Mandanten nicht eindeutig waere,
|
||||
* wuerde das Merken die automatische Zuordnung sogar blockieren - dann
|
||||
* lieber weiter von Hand zuordnen.
|
||||
*/
|
||||
function paypal_remember_payer_name(PDO $pdo, int $tenantId, int $participantId, string $payerName): ?string
|
||||
{
|
||||
$payerName = trim($payerName);
|
||||
if ($payerName === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
$stmt = $pdo->prepare('SELECT display_name, paypal_name FROM participants WHERE id = ? AND tenant_id = ?');
|
||||
$stmt->execute([$participantId, $tenantId]);
|
||||
$participant = $stmt->fetch();
|
||||
if ($participant === false) {
|
||||
return null;
|
||||
}
|
||||
if (trim((string) ($participant['paypal_name'] ?? '')) !== '') {
|
||||
return null;
|
||||
}
|
||||
if (strcasecmp(trim((string) $participant['display_name']), $payerName) === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Wuerde der Name auf ein weiteres Mitglied passen, bliebe die Zuordnung
|
||||
// mehrdeutig (imports_find_participant verlangt genau einen Treffer).
|
||||
$stmt = $pdo->prepare(
|
||||
'SELECT COUNT(*) FROM participants
|
||||
WHERE tenant_id = ?
|
||||
AND id <> ?
|
||||
AND (LOWER(paypal_name) = LOWER(?) OR LOWER(display_name) = LOWER(?))'
|
||||
);
|
||||
$stmt->execute([$tenantId, $participantId, $payerName, $payerName]);
|
||||
if ((int) $stmt->fetchColumn() > 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $payerName;
|
||||
}
|
||||
|
||||
function paypal_assign_payment(PDO $pdo, int $tenantId, int $paymentId, int $participantId, ?int $actorUserId): array
|
||||
{
|
||||
$stmt = $pdo->prepare("SELECT id, net_cents, status, payer_name, note, paid_at FROM paypal_payments WHERE id = ? AND tenant_id = ?");
|
||||
@@ -349,11 +395,22 @@ function paypal_assign_payment(PDO $pdo, int $tenantId, int $paymentId, int $par
|
||||
return ['ok' => false, 'error' => 'Das gewählte Mitglied wurde nicht gefunden.'];
|
||||
}
|
||||
|
||||
// Aus der Handarbeit lernen: heisst jemand bei PayPal anders als in der
|
||||
// Kaffeeliste, greift die automatische Zuordnung nie - denn sie verlangt
|
||||
// exakte Uebereinstimmung. Nach der ersten manuellen Zuordnung wird der
|
||||
// Zahlername deshalb beim Mitglied hinterlegt, damit die naechste Zahlung
|
||||
// von allein ankommt.
|
||||
$gemerkterName = paypal_remember_payer_name($pdo, $tenantId, $participantId, (string) $payment['payer_name']);
|
||||
|
||||
try {
|
||||
$pdo->beginTransaction();
|
||||
$ledgerId = paypal_book_payment($pdo, $tenantId, $participant, (int) $payment['net_cents'], $actorUserId, paypal_booking_note($payment));
|
||||
$pdo->prepare("UPDATE paypal_payments SET participant_id = ?, ledger_entry_id = ?, status = 'booked' WHERE id = ?")
|
||||
->execute([$participantId, $ledgerId, $paymentId]);
|
||||
if ($gemerkterName !== null) {
|
||||
$pdo->prepare('UPDATE participants SET paypal_name = ? WHERE id = ? AND tenant_id = ?')
|
||||
->execute([$gemerkterName, $participantId, $tenantId]);
|
||||
}
|
||||
$pdo->commit();
|
||||
} catch (Throwable $e) {
|
||||
if ($pdo->inTransaction()) {
|
||||
@@ -366,9 +423,10 @@ function paypal_assign_payment(PDO $pdo, int $tenantId, int $paymentId, int $par
|
||||
app_audit_log($pdo, $tenantId, $actorUserId, 'paypal_import.manual_assigned', 'paypal_payment', $paymentId, [
|
||||
'participant_id' => $participantId,
|
||||
'net_cents' => (int) $payment['net_cents'],
|
||||
'learned_paypal_name' => $gemerkterName,
|
||||
]);
|
||||
|
||||
return ['ok' => true];
|
||||
return ['ok' => true, 'learned_paypal_name' => $gemerkterName];
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user