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>
82 lines
3 KiB
PHP
82 lines
3 KiB
PHP
<?php
|
|
|
|
namespace App\Providers;
|
|
|
|
use App\Services\Backoffice\BackofficeDashboardService;
|
|
use App\Services\Payment\Payone\PayonePaymentService;
|
|
use App\Services\Payment\Stripe\StripeClientWrapper;
|
|
use App\Services\Util;
|
|
use Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider;
|
|
use Illuminate\Pagination\Paginator;
|
|
use Illuminate\Support\Facades\Schema;
|
|
use Illuminate\Support\Facades\URL;
|
|
use Illuminate\Support\ServiceProvider;
|
|
|
|
class AppServiceProvider extends ServiceProvider
|
|
{
|
|
/**
|
|
* Bootstrap any application services.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function boot()
|
|
{
|
|
Schema::defaultStringLength(191);
|
|
Paginator::defaultView('pagination::bootstrap-4');
|
|
Paginator::defaultSimpleView('pagination::simple-bootstrap-4');
|
|
|
|
if ($this->app->environment('production')) {
|
|
URL::forceScheme('https');
|
|
}
|
|
|
|
// Domain-bewusster View Composer für user_shop
|
|
// HOTFIX: DomainContext temporär deaktiviert
|
|
// TODO: Nach Claude v2 Implementation wieder aktivieren
|
|
\View::composer('*', function ($view) {
|
|
try {
|
|
// $context = app(\App\Domain\DomainContext::class);
|
|
// if ($context->type === 'main') {
|
|
// $view->with('user_shop', null);
|
|
// } else {
|
|
// $userShop = $context->userShop ?? \App\Services\Util::getUserShop();
|
|
// $view->with('user_shop', $userShop);
|
|
// }
|
|
|
|
// Temporär: Verwende immer das normale Verhalten
|
|
$view->with('user_shop', Util::getUserShop());
|
|
} catch (\Exception $e) {
|
|
// Fallback bei Fehlern
|
|
$view->with('user_shop', Util::getUserShop());
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Register any application services.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function register()
|
|
{
|
|
// PAYONE payment service: built from merchant defaults, real Guzzle client at runtime.
|
|
// The per-request `mode` is always passed explicitly to the service methods, so the
|
|
// shared singleton needs only the base defaults from config.
|
|
$this->app->singleton(PayonePaymentService::class, function () {
|
|
return new PayonePaymentService(config('payone.defaults'));
|
|
});
|
|
|
|
// Stripe: lazy Client-Hülle; Hard-Fail erst bei Nutzung ohne STRIPE_SECRET
|
|
// (Dark-Launch-fähig, siehe config/stripe.php + dev/2026-07-08-stripe/).
|
|
$this->app->singleton(StripeClientWrapper::class, function () {
|
|
return new StripeClientWrapper(config('stripe.secret'));
|
|
});
|
|
|
|
// Dashboard-Services teilen die Baum-Traversierung (lineBuckets-Memo):
|
|
// als Singleton läuft die Downline-BFS pro Request/Prozess nur einmal je Root.
|
|
$this->app->singleton(BackofficeDashboardService::class);
|
|
|
|
if ($this->app->environment() !== 'production' && class_exists(IdeHelperServiceProvider::class)) {
|
|
$this->app->register(IdeHelperServiceProvider::class);
|
|
}
|
|
}
|
|
}
|