Statistiken: Kundenfeedback 2026-08-19 komplett (N1-N8) + Review-Fixes + VP-/Incentive-Repair gehärtet

Statistik-Änderungen 2026-08-19 (dev/2026-07-22/entwicklungsplan-2026-08-19.md, alle 8 Pakete gemäß beantworteten F-Fragen):
- N1 Monatsstatistik: Team-Cluster (Firstlines klickbar -> neue Seite user_team_firstlines, Teampartner gesamt/Payline [nur aktive], Abos Payline mit +N) + Level-Kachel (Quali-Stufe, fehlende Payline-/persönliche Punkte, Karriere-Level); LiveCommissionService-Snapshot v3 reicht Level-/Quali-Daten durch
- N2 Abo-Kacheln auf Home monatsbezogen (aboStockCount-Rückrechnung über cancel/deleted/Status-Historie; VIP-Statistik bleibt tagesaktuell)
- N3 VIP-Statistik 'Recruiter des Monats' (Neupartner-Definition wie KPI, rekursives Ketten-Volumen als Gesamtpunkte inkl. Starterpaket) + Drilldown/CSV-Spalte 'Punkte gesamt'
- N4 Prognose-Block 'Level & Provision laut Prognose (Stand 25.)' mit unverbindlich-Kennzeichnung (ebenengenaue offene Abo-Punkte + TP-Laufstände)
- N5 Checkout-Herkunft: Dropdown raus, Pflicht-Freitext (lokalisierte Fehlermeldung)
- N6 Berater-Profilfoto (user_accounts.profile_image, Einwilligung als Sprachkey-Platzhalter, DSGVO-Löschung) + teaminterne Top-3-Karte (TopResultsService, Scope-Schalter)
- N7 USt-Optionen: 'nicht umsatzsteuerpflichtig' zuerst + '§ 19 UStG'-Textfix
- N8 Jahresgebühr-Nachfassliste je Berater (AnnualFeeDueService, überfällig/1-3 Monate, Sidenav)

Kontroll-Review (8 Perspektiven) angewendet: next-Level-Fallback im Steady-State (resolveNextLevel — sonst 'Höchstes Level erreicht' für Normalfälle), _calculated-Punktebasis bei mehr Paylines, keine Wiederbelebung deaktivierter Abos in der Monatsrückrechnung, Payline-Abo-Kachel monatskonsistent, Top-3-Nachrücker; Performance: BackofficeDashboardService als Singleton mit lineBuckets-Memo (+flushLineBucketsMemo), level_forecast 6h-Cache; Reuse: User-Scopes firstlinesOf/newPartnerIn, SalesVolumePoints::totalPointsByUser, Slim::storeCroppedImage (3 Upload-Kopien vereinigt), activeAbo-Scope statt Inline-Prädikate, Form::open-Konvention, Return-Types

Repair-Härtung (Kundenentscheide): VP-Nachtrepair dedupliziert über shopping_order_id (Live-Pfad schreibt sie jetzt mit), zählende Alt-Zeilen-Erkennung, Vormonats-Scan für Monatswechsel, Firmenaccount-Buchungen (config mivita.company_user_id) werden automatisch auf den Berater umgebucht (in place bzw. per Gegenbuchung bei geschlossenem Monat; Echtfall Anna Schall Order 58797 -> Christina Schuder), Berater-zu-Berater nur Warnung; Incentive-Repair: m_sponsor=NULL löscht nicht mehr, FK-Repair vor Stale-Bereinigung, gebatchte Lookups, zentrales Incentive::qualificationWindow(); .env aus dem Git-Tracking entfernt (Pflege per SFTP)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Kevin 2026-08-21 10:44:44 +00:00
parent 517d010d58
commit d65922adfe
88 changed files with 4480 additions and 425 deletions

View file

@ -27,7 +27,7 @@ return [
'reverse_charge_procedure' => 'Reverse Charge Verfahren',
'tax_number' => 'Steuernummer',
'taxable_sales_1' => 'umsatzsteuerpflichtig (Ich mache eine UST-Voranmeldung pro Monat / Quartal / Jahr ans Finanzamt)',
'taxable_sales_2' => 'nicht umsatzsteuerpflichtig (Kleinunternehmer im Sinne von $ 19',
'taxable_sales_2' => 'nicht umsatzsteuerpflichtig (Kleinunternehmer im Sinne von § 19 UStG)',
'validator_creditcard' => 'Geben Sie bitte eine gültige Kreditkarten-Nummer ein',
'validator_date' => 'Bitte geben Sie ein gültiges Datum ein.',
'validator_digits' => 'Geben Sie bitte nur Ziffern ein.',
@ -45,4 +45,12 @@ return [
'language_settings' => 'Spracheinstellungen',
'preferred_language' => 'Bevorzugte Sprache',
'language_hint' => 'Diese Sprache wird für Ihre Rechnungen, Provisionsabrechnungen und Lieferscheine verwendet.',
// N6: Berater-Profilfoto. Der finale Einwilligungstext wird von der Kundin
// nachgeliefert — profile_image_consent ist bis dahin ein Platzhaltertext.
'profile_image' => 'Profilfoto',
'profile_image_copy' => 'Dein Foto wird teamintern angezeigt, z. B. in Ranglisten und Übersichten.',
'profile_image_consent' => 'Ich bin einverstanden, dass mein Foto teamintern in Ranglisten und Übersichten angezeigt wird.',
'profile_image_consent_required' => 'Bitte bestätige zuerst die Einwilligung zur teaminternen Anzeige deines Fotos.',
'profile_image_delete' => 'Foto löschen',
];

View file

@ -70,4 +70,32 @@ return [
'own' => 'Eigene',
'live_calculation_hint' => 'Live-Berechnung (noch nicht abgeschlossen)',
'live_calculation_hint_text' => 'Wird erst zum Monatsende berechnet.',
'stats_group_team' => 'Team',
'firstlines_count' => 'Firstlines',
'team_partner_total' => 'Teampartner gesamt',
'payline_partner_count' => 'Teampartner in der Payline',
'payline_abo_count' => 'Abos in der Payline',
'level_current' => 'Aktuelles Level',
'level_career' => 'Karriere-Level',
'level_next_missing' => 'Zum nächsten Level :level fehlen noch :points Payline-Punkte.',
'level_next_missing_personal' => 'Zusätzlich fehlen :points Punkte persönliches Volumen.',
'level_top_reached' => 'Höchstes Level erreicht.',
'level_hint' => 'Monatliche Qualifikationsstufe aus dem Live-Lauf. Payline-Punkte = Teampunkte deiner bezahlten Ebenen inkl. deines Kundenpunkte-Überschusses.',
'forecast_level_title' => 'Level & Provision laut Prognose (Stand 25.)',
'forecast_unverbindlich' => 'unverbindlich',
'forecast_level_disclaimer' => 'Schätzung auf Basis der heutigen Punkte plus der noch offenen Abo-Lieferungen. Rang-/Strukturänderungen im Team sind nicht berücksichtigt - verbindlich ist erst der Monatsabschluss.',
'forecast_level_reached' => 'Laut Prognose erreichst du das nächste Level :level - sofern dein persönliches Volumen von :volume Punkten erreicht wird.',
'forecast_level_missing' => 'Laut Prognose fehlen zum nächsten Level :level noch :points Payline-Punkte.',
'forecast_level_missing_personal' => 'Zusätzlich fehlen :points Punkte persönliches Volumen.',
'forecast_commission' => 'Voraussichtliche Provision laut Prognose: :amount (auf Basis Level :level).',
// N6: "Die besten Ergebnisse des Monats" (teamintern)
'top_results_title' => 'Die besten Ergebnisse des Monats (Team)',
'top_results_volume' => 'Top 3 persönliches Volumen',
'top_results_recruiters' => 'Top 3 Neupartner',
'top_results_new_abos' => 'Top 3 neue Abos',
'top_results_empty' => 'Noch keine Ergebnisse in diesem Monat.',
'top_results_unit_points' => 'Punkte',
'top_results_unit_partners' => 'Neupartner',
'top_results_unit_abos' => 'Abos',
];

View file

@ -77,6 +77,7 @@ return [
'dhl_cockpit' => 'DHL Cockpit',
'revenue' => 'Umsatz',
'level_reports' => 'Level Reports',
'annual_fee' => 'Jahresgebühr',
'dashboard_news' => 'Dashboard News',
'teamabos' => 'Team Abos',
'team_customer_abos' => 'Team Kunden-Abos',

View file

@ -126,4 +126,5 @@ return [
'free_shipping_reached' => 'Ab :amount € versandkostenfrei',
'free_shipping_info' => 'Noch :missing € bis zum versandkostenfreien Versand (ab :amount €)',
'source_comment_required' => 'Bitte schreib uns kurz, wie du auf uns aufmerksam geworden bist - z. B. der Name der Person, die dich empfohlen hat, oder die genaue Messe/Veranstaltung.',
];

View file

@ -154,4 +154,19 @@ return [
'not_available' => 'N/A',
'growth_bonus_details_description' => 'L1 = Direkte Partner (bekommt immer den Tiefenbonus), L2 = Members (ab hier wird der Tiefenbonus geteilt, wenn der Member qualifiziert ist), etc. | Zeigt Provision (€) und Volumen (Pkt) pro Ebene.',
// Jahresgebühr-Nachfassliste (N8)
'annual_fee_title' => 'Jahresgebühr ausstehend',
'annual_fee_hint' => 'Hinweis: Teampartner mit abgelaufenem Account werden ca. 2 Wochen nach Ablauf automatisch deaktiviert und nach 2 Monaten aus dem System entfernt. Überfällige Einträge siehst du hier daher nur für begrenzte Zeit — fasse am besten frühzeitig nach.',
'annual_fee_no_data' => 'Aktuell läuft bei keinem deiner Teampartner die Account-Gültigkeit in den nächsten 3 Monaten ab.',
'annual_fee_group_overdue' => 'Überfällig',
'annual_fee_group_due_1_month' => 'Fällig in ≤ 1 Monat',
'annual_fee_group_due_2_months' => 'Fällig in ≤ 2 Monaten',
'annual_fee_group_due_3_months' => 'Fällig in ≤ 3 Monaten',
'firstlines' => 'Firstlines',
'firstlines_copy' => 'Deine direkten Teampartner mit Umsatz und Kontaktdaten - sortiert nach Punkten des gewählten Monats.',
'firstlines_none' => 'Du hast noch keine direkten Teampartner.',
'firstlines_points' => 'Umsatz (Punkte)',
'active_since' => 'Aktiv seit',
'account_inactive' => 'Account inaktiv',
];