mivita/dev/2026-07-22/neupartner-zahlungsmonat.md
Kevin b7e8bbd951 Statistik: Neupartner zaehlen im Monat der Zahlung, nicht der Registrierung
Wer Ende August registriert und am 1. September bezahlt hat, tauchte in keiner
Neupartner-Zaehlung auf: Der August-Snapshot wurde um 04:45 eingefroren, da
fehlte noch das Abrechnungskonto; im September lag active_date im falschen
Monat. Betroffen sind 2026 acht Partner, auch im Recruiting ihrer Sponsoren.

Kundenentscheidung 16.09.2026: der Zeitpunkt der Zahlung ist massgeblich.

Neue Spalte users.partner_paid_at, gesetzt bei der ersten Kontozahlung
(Payment::paymentStatusPaidAction) und bei manueller Freischaltung durch den
Admin — nur, solange sie leer ist; Verlaengerung und Wiederherstellung aendern
sie nicht. Bestehende Partner werden per Migration aus der ersten bezahlten
Registrierungsbestellung rueckgefuellt (Zeitstempel der Punktebuchung, ersatzweise
Bestelldatum, ohne Bestellung das Aktivierungsdatum). Bewusst nicht
payment_account minus ein Jahr: das ergaebe bei Verlaengerern den Jahrestag der
Erstzahlung.

User::scopeNewPartnerIn() und isNewPartnerIn() lesen jetzt partner_paid_at —
damit Kachel, Recruiter-Ranking, Top 3 und Neupartner-Liste gleichermassen.
Die Liste und der CSV-Export zeigen "Bezahlt am" neben "Registriert am".

Unveraendert: die Teamstruktur haengt weiter an active_date (auch im
Provisionsbaum). Wer ist neu dazugekommen und wer gehoert zur Linie sind zwei
verschiedene Fragen.

Die eingefrorenen Monate Januar bis August enthalten sieben dieser Partner
nicht; ob sie per --force neu gebaut werden, ist eine Entscheidung — siehe
dev/2026-07-22/neupartner-zahlungsmonat.md.

Mit drin: die handgebaute SQLite-Tabelle in BackofficeDashboardServiceTest
kannte status_reason aus d6efe56 noch nicht.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-16 14:48:01 +00:00

4.7 KiB
Raw Blame History

Neupartner zählen im Monat der Zahlung

Entscheidung der Kundin, 16.09.2026. Ein neuer Vertriebspartner gehört in den Monat, in dem er bezahlt hat — nicht in den Monat seiner Registrierung. Das gilt für jede Stelle, die Neupartner zählt: Kachel, Recruiter-Ranking, Top 3 „Recruiter des Monats", Neupartner-Liste, CSV-Export.

Der Fall, der es ausgelöst hat

Partner 1623 (Sponsor 454): registriert am 28.08., erster Zahlungslink abgelaufen, zweiter am 01.09. um 06:49 bezahlt. Der Snapshot für August wurde am 01.09. um 04:45 eingefroren — da hatte er noch kein Abrechnungskonto und fiel im August raus. Im September lag sein Aktivierungsdatum im falschen Monat. Er tauchte nirgends auf, auch nicht beim Recruiting seines Sponsors.

Das ist kein Einzelfall: 2026 betrifft es 8 Partner, jeweils Ende des Monats registriert und Anfang des Folgemonats bezahlt — 2 im Januar, 1 im April, 1 im Juni, 3 im Juli, 1 im September.

Was sich geändert hat

Die Neupartner-Regel hing an users.active_date (Abschluss der Registrierung). Neu ist die Spalte users.partner_paid_at: der Zeitpunkt der ersten Kontozahlung.

vorher jetzt
Neupartner im Monat X active_date in X partner_paid_at in X
Abrechnungskonto gültig am Stichtag ja ja, unverändert
Mitgliedsebene gesetzt ja ja, unverändert

Die Regel steht an einer Stelle — User::scopeNewPartnerIn() und das PHP-Gegenstück User::isNewPartnerIn() — und alle Zählungen gehen darüber.

Gesetzt wird partner_paid_at bei der ersten Kontozahlung (Payment::paymentStatusPaidAction, Produktaktion payment_for_account) und bei manueller Kontofreischaltung durch den Admin. Beides über UserUtil::markPartnerPaid(), das den Wert nur setzt, solange er leer ist. Eine Verlängerung oder eine Wiederherstellung ändert ihn nicht — sonst würde ein alter Partner in der Neupartner-Statistik wieder auftauchen.

Rückgefüllt wurde per Migration aus der ersten bezahlten Registrierungsbestellung (shopping_orders.payment_for = 1): die Punktebuchung dazu entsteht im Moment der Zahlung, deren Zeitstempel ist der Wert. Ohne Buchung das Änderungsdatum der Bestellung; ohne Bestellung (Konto vom Admin freigeschaltet, 14 Fälle) das Aktivierungsdatum. Nicht verwendet wurde payment_account minus ein Jahr: bei Verlängerungen wird vom alten Ablaufdatum aus verlängert, das Ergebnis wäre der Jahrestag der Erstzahlung und jeder Verlängerer ein „Neupartner".

Was sich nicht geändert hat

Die Teamstruktur. Ob jemand zum Monatsende zur Linie gehört, hängt weiterhin an active_date — so auch im Provisionsbaum. Das ist eine andere Frage als „wer ist neu dazugekommen": Partner 1623 steht im September in der Struktur seines Sponsors, und er ist der September-Neupartner. Ein Partner, der am 28.09. registriert und am 02.10. bezahlt, steht im September schon in der Struktur, zählt aber erst im Oktober als neu.

Provisionen, Gutschriften, Marketingplan. Unberührt. Die Migration fügt eine leere Spalte hinzu und füllt sie; keine vorhandene Zeile wird sonst geändert.

Wiederhergestellte Partner

Vier Partner haben ein active_date Jahre nach ihrer Registrierungszahlung (414, 522, 610, 663) — sie wurden offenbar wiederhergestellt, und restoreUser() setzt active_date neu. Unter der alten Regel zählten sie als Neupartner im Monat der Wiederherstellung. Unter der neuen Regel zählen sie im Monat ihrer ursprünglichen Zahlung (2021–2023), also nicht als Neupartner 2026. Das ist fachlich richtig, wenn eine Wiederherstellung keine Neuwerbung ist. Falls die Kundin das anders sieht, müsste restoreUser() den Wert zurücksetzen — bewusst nicht gemacht.

Die eingefrorenen Monate

Die Snapshots Januar bis August wurden mit der alten Regel gebaut. Sieben der acht Partner von oben fehlen darin vollständig — in beiden Monaten. Der Snapshot friert bewusst ein (siehe monatsabschluss-eingefrorene-statistik.md), ein Neuaufbau ist deshalb eine Entscheidung, keine Routine:

php artisan backoffice:store-statistics-snapshots --force

Damit landen die sieben in ihren Zahlungsmonaten. Wie am 10.09. gilt: der Neuaufbau friert die Teamstruktur des Ausführungstags ein, nicht die des damaligen Monatsendes. Wer seit dem 10.09. verschoben wurde oder dazukam, steht danach an seiner heutigen Stelle in den historischen Zahlen.

Sichtprüfung nach dem Deploy

  • Backoffice → September → Neupartner-Liste: Partner 1623 steht drin, Spalte „Bezahlt am" = 01.09.2026, „Registriert am" = 28.08.2026.
  • Recruiter-Ranking September: Sponsor 454 hat ihn angerechnet.
  • Backoffice → August (eingefroren): unverändert, solange kein Neuaufbau läuft.