mivita/dev/code/TreeCalcBot_Berechnungslogik.md
2025-08-12 18:01:59 +02:00

357 lines
No EOL
12 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# TreeCalcBot - Berechnungslogik Dokumentation
## Überblick des MLM-Berechnungssystems
Das Mivita MLM-System implementiert ein mehrstufiges Provisionsberechnungssystem basierend auf:
- **KP (Kundenpoints)** - Direkte Verkaufspunkte
- **TP (Teampoints)** - Punkte aus der Downline-Hierarchie
- **Shop Points** - E-Commerce-Verkäufe
- **Payline-System** - Ebenen-basierte Provisionsberechnung
- **Growth Bonus** - Zusätzliche Provisionen ab bestimmten Ebenen
---
## 1. PUNKTE-SAMMLUNG UND -AGGREGATION
### 1.1 Grundlegende Punktetypen
```php
// In BusinessUserItem->makeUser()
'sales_volume_KP_points' => $user->getUserSalesVolumeBy($month, $year, 'sales_volume_KP_points'), // Direkte Kundenpunkte
'sales_volume_TP_points' => $user->getUserSalesVolumeBy($month, $year, 'sales_volume_TP_points'), // Teampunkte
'sales_volume_points_shop' => $user->getUserSalesVolumeBy($month, $year, 'sales_volume_points_shop'), // Shop-Punkte
// Berechnete Summen
'sales_volume_points_KP_sum' => KP_points + points_shop, // KP + Shop kombiniert
'sales_volume_points_TP_sum' => TP_points + points_shop, // TP + Shop kombiniert
```
**🔍 POTENZIELLE BERECHNUNGSFEHLER:**
- Doppelzählung von `points_shop` in beiden Summen-Feldern
- Fehlende Validierung ob Shop-Punkte bereits in KP/TP enthalten sind
### 1.2 Hierarchische Punkteaggregation
```php
// TreeCalcBot->calcUserPoints() - Zeile 104-119
private function calcUserPoints($businessUserItems, $line) {
// Für jede Hierarchie-Ebene
foreach($businessUserItems as $business_user_item) {
// 1. REKURSION: Tiefere Ebenen erst berechnen
if(count($business_user_item->businessUserItems) > 0) {
$this->calcUserPoints($business_user_item->businessUserItems, $line+1);
}
// 2. PUNKTE ADDIEREN: TP_sum (TP + Shop) wird verwendet
$this->business_user->addBusinessLinePoints($line, $business_user_item->sales_volume_points_TP_sum);
$this->business_user->addTotal TP($business_user_item->sales_volume_points_TP_sum);
}
}
```
**📊 BERECHNUNGSABLAUF:**
```
Ebene 1: User A (100 TP) + User B (200 TP) = 300 Punkte
Ebene 2: User C (50 TP) + User D (75 TP) = 125 Punkte
Ebene 3: User E (25 TP) = 25 Punkte
Total Points: 300 + 125 + 25 = 450 Punkte
```
**🚨 KRITISCHE BERECHNUNGSFEHLER:**
1. **Inkonsistente Punktetypen:** Es wird `sales_volume_points_TP_sum` verwendet, aber eigentlich sollten nur Team-Punkte ohne eigene Verkäufe aggregiert werden
2. **Doppelzählung Risk:** Eigene Punkte des Users werden möglicherweise sowohl in KP als auch in der Hierarchie gezählt
---
## 2. QUALIFIKATIONS-BERECHNUNGSSYSTEM
### 2.1 Qualifikations-Voraussetzungen
```php
// BusinessUserItem->calcuQualLevel() - Zeile 215-231
public function calcuQualLevel() {
// 1. FILTER: Alle Level wo KP-Mindestanforderung erfüllt ist
$qualUserLevels = UserLevel::where('qual_kp', '<=', $this->sales_volume_points_KP_sum)
->where('pos', '<=', $this->user_level_active_pos)
->orderBy('qual_pp', 'desc')
->get();
// 2. PRÜFUNG: Für jeden möglichen Level
foreach($qualUserLevels as $qualUserLevel) {
$payline_points = $this->getPointsforPayline($qualUserLevel->paylines);
$payline_points_qual_kp = $payline_points + $this->getRestQualKP();
// 3. QUALIFIKATION: Wenn PP-Anforderung erfüllt
if($payline_points_qual_kp >= $qualUserLevel->qual_pp) {
return $qualUserLevel; // Höchster erreichter Level
}
}
return NULL; // Keine Qualifikation erreicht
}
```
### 2.2 Payline-Punkte Berechnung
```php
// BusinessUserItem->getPointsforPayline() - Zeile 235-243
private function getPointsforPayline($paylines) {
$payline_points = 0;
for ($i=1; $i <= $paylines; $i++) {
if(isset($this->business_lines[$i])) {
$payline_points += $this->business_lines[$i]->points;
}
}
return $payline_points;
}
```
### 2.3 Rest-KP Berechnung
```php
// BusinessUserItem->getRestQualKP() - Zeile 149-152
public function getRestQualKP() {
$ret = $this->sales_volume_points_KP_sum - $this->qual_kp;
return $ret > 0 ? $ret : 0;
}
```
**🔍 QUALIFIKATIONSLOGIK:**
```
Beispiel User Level "Gold":
- qual_kp = 500 (Mindest-Kundenpunkte)
- qual_pp = 1000 (Mindest-Payline-Punkte)
- paylines = 3 (Berücksichtigte Ebenen)
User hat:
- sales_volume_points_KP_sum = 600 KP ✅ (600 >= 500)
- Ebene 1: 300 Punkte
- Ebene 2: 400 Punkte
- Ebene 3: 200 Punkte
- payline_points = 300 + 400 + 200 = 900
- rest_kp = 600 - 500 = 100
- payline_points_qual_kp = 900 + 100 = 1000 ✅ (1000 >= 1000)
RESULTAT: User qualifiziert sich für "Gold" Level
```
**🚨 POTENZIELLE BERECHNUNGSFEHLER:**
1. **Doppelte KP-Nutzung:** Rest-KP werden sowohl für Qualifikation als auch für Payline-Berechnung verwendet
2. **Ebenen-Logik:** Die Sortierung `orderBy('qual_pp', 'desc')` könnte niedrigere Level überspringen
---
## 3. PROVISIONS-BERECHNUNGSSYSTEM
### 3.1 Payline-Provisionen
```php
// BusinessUserItem->calcQualPP() - Zeile 171-180
for ($i=1; $i <= $qualUserLevel->paylines; $i++) {
if(isset($this->business_lines[$i])) {
$object = $this->business_lines[$i];
$object->margin = $this->qual_user_level['pr_line_'.$i]; // Provision in %
$object->commission = round($object->points / 100 * $object->margin, 2);
$commission_pp_total += $object->commission;
$this->b_user->business_lines[$i] = $object;
}
}
```
### 3.2 Growth Bonus Berechnung
```php
// BusinessUserItem->calcQualPP() - Zeile 182-198
if($qualUserLevel->growth_bonus) {
$payline = (int) $this->qual_user_level['paylines'] + 1; // Ab Ebene nach Paylines
$maxlines = count($this->business_lines) + 1;
$growth_bonus = (float) $this->qual_user_level['growth_bonus'];
for ($i=$payline; $i <= $maxlines; $i++) {
if(isset($this->business_lines[$i])) {
$object = $this->business_lines[$i];
$object->margin = $growth_bonus; // Einheitlicher % für alle Ebenen
$object->commission = round($object->points / 100 * $object->margin, 2);
$commission_growth_total += $object->commission;
}
}
}
```
### 3.3 Shop-Provisionen
```php
// BusinessUserItem->makeUser() - Zeile 85
$this->b_user->commission_shop_sales = round(
$this->b_user->sales_volume_total_shop / 100 * $this->b_user->margin_shop,
2
);
```
### 3.4 Gesamt-Provisionen
```php
// BusinessUserItem->getCommissionTotal() - Zeile 154-156
public function getCommissionTotal() {
return round(
$this->commission_shop_sales + // Shop-Verkäufe
$this->commission_pp_total + // Payline-Provisionen
$this->commission_growth_total, // Growth Bonus
2
);
}
```
**📊 PROVISIONS-BEISPIEL:**
```
User "Gold" Level (3 Paylines, 2% Growth Bonus):
- pr_line_1 = 5% - Ebene 1: 300 Punkte → 15€ Provision
- pr_line_2 = 3% - Ebene 2: 400 Punkte → 12€ Provision
- pr_line_3 = 2% - Ebene 3: 200 Punkte → 4€ Provision
- Growth Bonus 2% - Ebene 4: 100 Punkte → 2€ Provision
- Ebene 5: 50 Punkte → 1€ Provision
Shop-Provision: 1000€ Umsatz × 10% = 100€
GESAMT: 15 + 12 + 4 + 2 + 1 + 100 = 134€
```
---
## 4. KRITISCHE BERECHNUNGSFEHLER-ANALYSE
### 🔴 FEHLER 1: Inkonsistente Punktetypen
**Problem:** Verschiedene Punktetypen werden vermischt ohne klare Trennung
```php
// Zeile 115: TP_sum wird für Payline-Berechnung verwendet
addBusinessLinePoints($line, $business_user_item->sales_volume_points_TP_sum);
// Aber Zeile 217: KP_sum wird für Qualifikation verwendet
where('qual_kp', '<=', $this->sales_volume_points_KP_sum)
```
**Fix:** Klare Definition welche Punkte für welche Berechnung verwendet werden
### 🔴 FEHLER 2: Doppelzählung Shop-Punkte
**Problem:** Shop-Punkte werden sowohl in KP_sum als auch TP_sum eingerechnet
```php
'sales_volume_points_KP_sum' => KP_points + points_shop,
'sales_volume_points_TP_sum' => TP_points + points_shop,
```
**Fix:** Shop-Punkte nur einmal berücksichtigen oder klar dokumentieren
### 🔴 FEHLER 3: Rest-KP Doppelnutzung
**Problem:** Rest-KP werden für Payline-Berechnung addiert, obwohl sie bereits in der Qualifikation verwendet wurden
```php
// Zeile 221: Rest-KP zu Payline-Punkten addiert
$payline_points_qual_kp = $payline_points + $this->getRestQualKP();
```
**Fix:** Klären ob Rest-KP zusätzliche "Bonus-Punkte" sind oder Doppelzählung
### 🟡 FEHLER 4: Fehlende Boundary-Checks
**Problem:** Keine Validierung für negative Werte oder Overflow
```php
// Zeile 108: Keine Überprüfung ob points negativ sein könnten
$obj->points += $points;
```
**Fix:** Input-Validierung und Boundary-Checks implementieren
### 🟡 FEHLER 5: Rundungsfehler-Akkumulation
**Problem:** Rundung nach jeder Berechnung kann zu Abweichungen führen
```php
// Zeile 175: Rundung pro Ebene
$object->commission = round($object->points / 100 * $object->margin, 2);
```
**Fix:** Erst am Ende der Gesamtberechnung runden
---
## 5. VALIDIERUNGSSCHRITTE FÜR BERECHNUNGEN
### ✅ Validierung 1: Punktesummen prüfen
```php
function validatePointSums($user) {
$kp_calculated = $user->sales_volume_KP_points + $user->sales_volume_points_shop;
$tp_calculated = $user->sales_volume_TP_points + $user->sales_volume_points_shop;
assert($kp_calculated == $user->sales_volume_points_KP_sum, "KP sum mismatch");
assert($tp_calculated == $user->sales_volume_points_TP_sum, "TP sum mismatch");
}
```
### ✅ Validierung 2: Hierarchie-Konsistenz
```php
function validateHierarchyPoints($businessUser) {
$calculated_total = 0;
foreach($businessUser->business_lines as $line => $data) {
$calculated_total += $data->points;
}
assert($calculated_total == $businessUser->total_pp, "Hierarchy total mismatch");
}
```
### ✅ Validierung 3: Provisions-Konsistenz
```php
function validateCommissions($businessUser) {
$calculated_pp = 0;
$calculated_growth = 0;
foreach($businessUser->business_lines as $line => $data) {
if(isset($data->payline) && $data->payline) {
$calculated_pp += $data->commission;
}
if(isset($data->growth_bonus) && $data->growth_bonus) {
$calculated_growth += $data->commission;
}
}
assert($calculated_pp == $businessUser->commission_pp_total, "PP commission mismatch");
assert($calculated_growth == $businessUser->commission_growth_total, "Growth commission mismatch");
}
```
---
## 6. EMPFOHLENE FIXES UND VERBESSERUNGEN
### 1. Punkt-Typ Standardisierung
```php
// Klare Trennung der Punktetypen
class PointTypes {
const CUSTOMER_POINTS = 'KP'; // Nur direkte Verkäufe
const TEAM_POINTS = 'TP'; // Nur Team-Hierarchie
const SHOP_POINTS = 'SP'; // Nur E-Commerce
const COMBINED_POINTS = 'CP'; // Für Berechnungen
}
```
### 2. Berechnungs-Pipeline
```php
class CalculationPipeline {
public function calculate($user) {
$this->validateInput($user);
$this->calculateHierarchyPoints($user);
$this->calculateQualifications($user);
$this->calculateCommissions($user);
$this->validateOutput($user);
}
}
```
### 3. Audit-Trail
```php
class CalculationAudit {
public function logCalculation($user, $step, $before, $after) {
Log::info("Calculation Step", [
'user_id' => $user->id,
'step' => $step,
'before' => $before,
'after' => $after,
'diff' => $after - $before
]);
}
}
```
Diese Dokumentation deckt alle kritischen Berechnungsaspekte ab und zeigt konkrete Stellen auf, wo Berechnungsfehler auftreten könnten.