# Konzept: Erweiterte Detailansicht für Growth Bonus (Matrix-View) Die Anforderung ist, eine **Matrix-Ansicht** zu erstellen, bei der die Ebenen (Level 1, 2, 3...) als Spalten und die einzelnen Linien (Legs/Beine) als Zeilen dargestellt werden. Dies soll auch dann geschehen, wenn der Bonus gekappt ist, um volle Transparenz zu gewährleisten. ## 1. Datenstruktur-Erweiterung (`GrowthBonusCalculator`) Die bisherige Aggregation (`getVolumeByProtectionLevel`) gruppiert Volumen nach "Schutz-Level". Das ist gut für die Berechnung, aber für die Visualisierung "Ebene für Ebene" brauchen wir die Rohdaten pro Ebene. Wir benötigen eine neue Methode `getMatrixDetails`, die rekursiv die Struktur traversiert und für jedes Bein eine flache Liste von Ebenen-Volumen zurückgibt, angereichert mit Status-Informationen. ### Struktur des Ergebnis-Arrays: ```php [ // Ein Eintrag pro Firstline (Bein) [ 'user' => [ 'id' => 123, 'name' => 'Max Mustermann', 'level' => 'Gold' ], 'levels' => [ 1 => [ // Ebene 1 (relativ zu mir, also der Firstline-User selbst) 'volume' => 500, 'user_level' => 'Gold', 'protection_percent' => 2.0, // Was der User für sich beansprucht 'my_percent' => 2.5, // Mein Anspruch 'diff_percent' => 0.5, // Resultierende Provision 'commission' => 2.50, 'is_blocked' => false ], 2 => [ // Ebene 2 (User unter Max) 'volume' => 1000, 'user_level' => 'Silver', 'protection_percent' => 1.5, 'my_percent' => 2.5, 'diff_percent' => 1.0, 'commission' => 10.00, 'is_blocked' => false ], // ... weitere Ebenen bis max Tiefe oder Abbruchbedingung ], 'totals' => [ 'volume' => 1500, 'commission' => 12.50 ] ], // ... weitere Beine ] ``` ## 2. Implementierungsschritte 1. **`GrowthBonusCalculator.php`**: Methode `getMatrixDetails` hinzufügen. * Muss rekursiv durch die `businessUserItems` laufen. * Muss tracken, welcher "Schutz-Level" von oben kommt (rekursiv weitergegeben). * Muss aber `protection_percent` lokal pro User neu bewerten (max(incoming, own)). 2. **`BusinessUserItemOptimized.php`**: Aufruf in `getGrowthBonusBreakdown` anpassen oder neue Methode `getGrowthBonusMatrix` hinzufügen. 3. **View `_user_detail_in.blade.php`**: Umbau der Tabelle zu einer Matrix. ### Herausforderung: Tiefe und Breite Eine komplette Matrix kann sehr breit und lang werden. * **Begrenzung:** Wir sollten die Tiefe standardmäßig begrenzen (z.B. 10-20 Ebenen) oder nur relevante Ebenen (wo Volumen > 0) anzeigen. * **Breite:** In der Tabelle werden die Spalten "Ebene 1", "Ebene 2", ... sein. ## 3. Code-Anpassung `GrowthBonusCalculator.php` ```php /** * Liefert eine Matrix-Sicht für die detaillierte Darstellung * Zeilen = Beine (Legs), Spalten = Ebenen (Levels) */ public function getMatrixDetails(BusinessUserItemOptimized $userItem, $qualUserLevel): array { $details = []; if (empty($qualUserLevel->growth_bonus) || $qualUserLevel->growth_bonus <= 0) { return $details; } $myGrowthPercent = (float) $qualUserLevel->growth_bonus; foreach ($userItem->businessUserItems as $childItem) { $legData = [ 'user' => [ 'id' => $childItem->user_id, 'name' => $childItem->first_name . ' ' . $childItem->last_name, 'level' => $childItem->user_level_name ], 'levels' => [], 'total_commission' => 0.0, 'total_volume' => 0.0 ]; // Rekursiv die Ebenen dieses Beins einsammeln // Start bei Ebene 1 (das ist das Kind selbst) // Initial Protection ist 0 (vom Upline/Mir kommt kein Schutz, der relevant wäre, da ICH ja der Empfänger bin) $this->collectLegLevels($childItem, 1, 0.0, $myGrowthPercent, $legData); if (!empty($legData['levels'])) { // Sortieren nach Ebenen-Index ksort($legData['levels']); $details[] = $legData; } } // Sortieren nach Gesamt-Provision usort($details, function($a, $b) { return $b['total_commission'] <=> $a['total_commission']; }); return $details; } private function collectLegLevels(BusinessUserItemOptimized $item, int $level, float $incomingProtection, float $myPercent, array &$legData) { // 1. Eigenen Status ermitteln (Schutz für Downline) $myProtection = 0.0; if ($item->isQualLevel()) { $qual = $item->qual_user_level; $growth = is_array($qual) ? ($qual['growth_bonus'] ?? 0) : ($qual->growth_bonus ?? 0); if ($growth > 0) { $myProtection = (float) $growth; } } // Der effektive Schutz, der AUF diesen User wirkt (von oben kommend + sein eigener Anspruch) // WICHTIG: Für die Provision auf DIESEN User zählt der $incomingProtection (Schutz von oben). // Für die Weitergabe nach unten zählt max($incoming, $myProtection). // Berechnung für diesen User (Ebene) $volume = (float) ($item->sales_volume_points_TP_sum ?? 0); if ($volume > 0) { // Differenz: Mein Anspruch - Schutz von oben $diffPercent = max(0, $myPercent - $incomingProtection); $commission = round($volume / 100 * $diffPercent, 2); // Speichern in Matrix // Wir summieren Volumen pro Ebene (falls durch parallele Zweige im Bein mehrere User auf gleicher Ebene sind - hier aber linearer Abstieg) // Moment, businessUserItems ist ein Baum. Ein Bein kann breit werden. // Wir müssen pro Ebene summieren. if (!isset($legData['levels'][$level])) { $legData['levels'][$level] = [ 'volume' => 0.0, 'commission' => 0.0, 'details' => [] // Optional für Hover ]; } $legData['levels'][$level]['volume'] += $volume; $legData['levels'][$level]['commission'] += $commission; // Metadaten für Anzeige (nur beim ersten Eintrag pro Ebene oder aggregiert?) // Bei Matrix-View (Spalten=Ebenen) summieren wir alles auf Ebene X in diesem Bein. // Das "Problem": In Ebene X können User mit unterschiedlichem Schutz-Status sein. // Daher ist eine einfache Summe evtl. irreführend bei der %-Anzeige. // Alternative: Wir zeigen pro Ebene den "dominanten" Status oder listen auf. // Für die Tabelle ist eine Zelle pro Ebene vorgesehen. // Wir speichern Detail-Infos für Tooltip. $legData['levels'][$level]['details'][] = [ 'u' => $item->user_id, 'v' => $volume, 'p' => $incomingProtection, // Protected by 'd' => $diffPercent ]; $legData['total_volume'] += $volume; $legData['total_commission'] += $commission; } // Protection für nächste Ebene: Maximum aus was von oben kam und was dieser User beansprucht $nextProtection = max($incomingProtection, $myProtection); // Rekursion // Max Tiefe z.B. 20 if ($level < 20 && !empty($item->businessUserItems)) { foreach ($item->businessUserItems as $child) { $this->collectLegLevels($child, $level + 1, $nextProtection, $myPercent, $legData); } } } ``` ## 4. Design der Tabelle (Blade) Spalten: Leg (Partner) | Ebene 1 | Ebene 2 | Ebene 3 | ... | Ebene 10 | Total Zeilen: Partner A | ... | ... | ... Zellen-Inhalt: * Oben: Provision (€) * Unten: Volumen (Pkt) * Farbe: Grün (Volle %), Gelb (Teil %), Rot (0% / Block) Da die Ebenen dynamisch sind, ermitteln wir `max_level` über alle Legs.