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 ec3ecad noch nicht.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
86 lines
4.7 KiB
Markdown
86 lines
4.7 KiB
Markdown
# 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](monatsabschluss-eingefrorene-statistik.md)), ein
|
||
Neuaufbau ist deshalb eine Entscheidung, keine Routine:
|
||
|
||
```bash
|
||
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.
|