Audit 18.09.: Zahlungsdatum nur bei Zahlung, Neupartner-IDs im Snapshot, Pausenende folgt dem Termin
F1: partner_paid_at wird beim Rechnungskauf (paymentStatusPaidAction mit paid=false) nicht mehr gesetzt, sondern erst bei der Rechnungszahlung; der Backfill nimmt das Aktivierungsdatum nur noch ohne jede Registrierungsbestellung (offene Rechnung bleibt leer). F2: Snapshots speichern je Linie new_partner_ids, die Neupartner-Liste zeigt genau diese; aeltere Snapshots ohne IDs rechnen mit der damaligen Regel (Registrierungsmonat, scopeNewPartnerInByActiveDate), damit Kachel und Liste uebereinstimmen. Keine Payload-Versionsaenderung, kein Neuaufbau noetig. F3: Liefertag-/Termin-Aenderung waehrend einer Pause zieht paused_until mit; eine Ausfuehrung loescht auch den paused_by_*-Grund. F4: expiredCount der Firstlines-Seite (Controller, View, Sprachen) zum bereits committeten Test nachgezogen. F5: Backfills schreiben ohne updated_at (toBase()->update, timestamps=false). Kuendigungsbestaetigung abo_cancel_confirm wird im Selfservice serverseitig verlangt. AboStatusExplainer laedt die Historie je Abo und Aktion nur einmal. Stellungnahme und Deploy-Folgen im Audit-Dokument, Regressionstests je Befund. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
b7e8bbd951
commit
03416b0afe
27 changed files with 560 additions and 21 deletions
|
|
@ -49,7 +49,7 @@ class BackofficeDrilldownService
|
|||
|
||||
$rows = match ($metric) {
|
||||
'consultants' => $this->consultantRows($userIds),
|
||||
'new_partners' => $this->newPartnerRows($userIds, $month, $year),
|
||||
'new_partners' => $this->newPartnerRows($userIds, $month, $year, $frozen !== null ? $this->frozenNewPartnerIds($frozen, $line) : null, $frozen !== null),
|
||||
'team_partner_abos' => $this->partnerAboRows($userIds, $month, $year, $onlyNew, $frozenAboIds),
|
||||
'team_customer_abos' => $this->customerAboRows($userIds, $month, $year, $onlyNew, $frozenAboIds),
|
||||
'own_points', 'external_points', 'customer_abo_points', 'customer_single_order_points', 'customer_other_points', 'total_points', 'shop_1000' => $this->pointsRows($userIds, $month, $year, $metric),
|
||||
|
|
@ -149,13 +149,19 @@ class BackofficeDrilldownService
|
|||
* @param int[] $userIds
|
||||
* @return array<int, array<string, mixed>>
|
||||
*/
|
||||
private function newPartnerRows(array $userIds, int $month, int $year): array
|
||||
private function newPartnerRows(array $userIds, int $month, int $year, ?array $frozenIds = null, bool $frozen = false): array
|
||||
{
|
||||
// Eingefrorener Monat: exakt die im Snapshot gezaehlten Partner. Aeltere
|
||||
// Snapshots ohne gespeicherte IDs wurden mit der Regel "Registrierungsmonat"
|
||||
// gebaut — die Liste rechnet dann mit derselben Regel, sonst zeigt die
|
||||
// Kachel 1 und die Liste 0 (Audit 18.09., F2).
|
||||
$partners = User::query()
|
||||
->with(['account', 'user_level'])
|
||||
->whereIn('id', $userIds)
|
||||
->newPartnerIn($month, $year)
|
||||
->whereIn('id', $frozenIds ?? $userIds)
|
||||
->when($frozenIds === null && $frozen, fn (Builder $query) => $query->newPartnerInByActiveDate($month, $year))
|
||||
->when($frozenIds === null && ! $frozen, fn (Builder $query) => $query->newPartnerIn($month, $year))
|
||||
->orderBy('partner_paid_at')
|
||||
->orderBy('active_date')
|
||||
->get();
|
||||
|
||||
$sponsors = User::query()
|
||||
|
|
@ -274,6 +280,34 @@ class BackofficeDrilldownService
|
|||
return array_values(array_unique($ids));
|
||||
}
|
||||
|
||||
/**
|
||||
* Neupartner einer Linie zum Monatsabschluss; null, wenn der Snapshot die IDs
|
||||
* noch nicht kennt (gebaut vor dem 18.09.2026) — dann gilt die damalige Regel.
|
||||
*
|
||||
* @param array<int, array<string, mixed>> $frozen
|
||||
* @return int[]|null
|
||||
*/
|
||||
private function frozenNewPartnerIds(array $frozen, int $line): ?array
|
||||
{
|
||||
$ids = [];
|
||||
|
||||
foreach ($frozen as $index => $row) {
|
||||
if ($line !== 0 && (int) ($row['line'] ?? $index) !== $line) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (! array_key_exists('new_partner_ids', $row)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach ($row['new_partner_ids'] as $id) {
|
||||
$ids[] = (int) $id;
|
||||
}
|
||||
}
|
||||
|
||||
return array_values(array_unique($ids));
|
||||
}
|
||||
|
||||
/**
|
||||
* Abos einer Linie zum Monatsabschluss; Linie 0 = das ganze Team. Gibt es zu der
|
||||
* Kennzahl keine eingefrorene Liste, wird null zurueckgegeben (Live-Auswertung).
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue