mivita/app/Services/BusinessPlan/SYSTEM-OVERVIEW.md
2026-01-23 17:35:23 +01:00

25 KiB

BusinessPlan System - Gesamtübersicht

📋 Inhaltsverzeichnis

  1. System-Architektur
  2. Datei-Übersicht
  3. Datenfluss
  4. Punktetypen & Begriffe
  5. Level-System
  6. Provisionsberechnung
  7. Cron-Job (Monatsabschluss)
  8. Dashboard-Integration

System-Architektur

┌─────────────────────────────────────────────────────────────────────┐
│                        FRONTEND / VIEWS                             │
├─────────────────────────────────────────────────────────────────────┤
│  dashboard/_statistics.blade.php  │  dashboard/_points.blade.php   │
│  user/team/*.blade.php           │  admin/business/*.blade.php    │
└───────────────────┬─────────────────────────────────────────────────┘
                    │
                    ▼
┌─────────────────────────────────────────────────────────────────────┐
│                         CONTROLLER                                   │
├─────────────────────────────────────────────────────────────────────┤
│  HomeController       │  TeamController       │  AdminController    │
└───────────────────────┼─────────────────────────────────────────────┘
                        │
                        ▼
┌─────────────────────────────────────────────────────────────────────┐
│                   BUSINESS PLAN SERVICES                            │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  ┌─────────────────────────────────────────────────────────────┐   │
│  │              TreeCalcBotOptimized.php                        │   │
│  │  - Hauptklasse für MLM-Strukturberechnungen                  │   │
│  │  - Initialisiert Business-User Strukturen                    │   │
│  │  - Berechnet Punkte über alle Ebenen                        │   │
│  │  - Delegiert an Repository, Renderer, Calculator            │   │
│  └──────────────────────┬──────────────────────────────────────┘   │
│                         │                                           │
│    ┌────────────────────┼────────────────────────────┐             │
│    │                    │                            │             │
│    ▼                    ▼                            ▼             │
│ ┌──────────────┐  ┌──────────────────────┐  ┌──────────────────┐  │
│ │ Business     │  │ BusinessUserItem     │  │ GrowthBonus      │  │
│ │ User         │  │ Optimized.php        │  │ Calculator.php   │  │
│ │ Repository   │  │                      │  │                  │  │
│ │ .php         │  │ - User-Datenbehälter │  │ - Tiefenbonus    │  │
│ │              │  │ - Qualifikations-    │  │ - Differenz-     │  │
│ │ - DB Queries │  │   berechnung         │  │   Logik          │  │
│ │ - Caching    │  │ - Provisions-        │  │                  │  │
│ │ - Relations  │  │   berechnung         │  │                  │  │
│ └──────────────┘  └──────────────────────┘  └──────────────────┘  │
│                                                                     │
│  ┌─────────────────────────────────────────────────────────────┐   │
│  │              SalesPointsVolume.php                           │   │
│  │  - Punkteerfassung bei Bestellungen                         │   │
│  │  - KP/TP Punkte-Unterscheidung                              │   │
│  │  - Neuberechnung bei Änderungen                             │   │
│  └─────────────────────────────────────────────────────────────┘   │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘
                        │
                        ▼
┌─────────────────────────────────────────────────────────────────────┐
│                          MODELS                                      │
├─────────────────────────────────────────────────────────────────────┤
│  User              │  UserBusiness       │  UserSalesVolume        │
│  UserLevel         │  UserBusinessStruct │  UserAbo                │
│  ShoppingOrder     │  ShoppingUser       │                          │
└─────────────────────────────────────────────────────────────────────┘

Datei-Übersicht

Datei Zweck Abhängigkeiten
TreeCalcBotOptimized.php Hauptklasse für MLM-Strukturberechnungen Repository, Renderer, Logger
BusinessUserItemOptimized.php User-Datenbehälter mit Berechnungslogik GrowthBonusCalculator
BusinessUserRepository.php Optimierte DB-Abfragen mit Caching User, UserBusiness Models
GrowthBonusCalculator.php Tiefenbonus-Berechnung (Differenz-Logik) BusinessUserItemOptimized
SalesPointsVolume.php Punkteerfassung bei Bestellungen UserSalesVolume, ShoppingOrder
TreeHtmlRenderer.php HTML-Ausgabe für Struktur-Ansichten -
TreeHelperOptimized.php Hilfsfunktionen für Tree-Operationen -

Dokumentation

Datei Inhalt
TreeCalcBotOptimized.md Technische Dokumentation der Hauptklasse
Growth-Bonus.md Erklärung der Tiefenbonus-Logik
Growth-Bonus-Matrix.md Matrix-Darstellung des Tiefenbonus

Datenfluss

1. Punkteerfassung (bei Bestellung)

┌──────────────────┐     ┌────────────────────┐     ┌──────────────────┐
│  ShoppingOrder   │────▶│ SalesPointsVolume  │────▶│ UserSalesVolume  │
│  wird erstellt   │     │ ::addSalesPoints   │     │ wird erstellt    │
└──────────────────┘     │ VolumeUser()       │     └──────────────────┘
                         └────────────────────┘              │
                                  │                          │
                                  ▼                          ▼
                         ┌────────────────────┐     ┌──────────────────┐
                         │ reCalculateSales   │────▶│ month_KP_points  │
                         │ PointsVolume()     │     │ month_TP_points  │
                         └────────────────────┘     │ month_shop_points│
                                                    └──────────────────┘

2. Strukturberechnung (Live oder Cron)

┌───────────────────────────────────────────────────────────────────────┐
│                    TreeCalcBotOptimized                               │
│                                                                       │
│  1. initStructureAdmin() oder initStructureUser()                    │
│     │                                                                 │
│     ├─▶ Prüfe gespeicherte Struktur (UserBusinessStructure)          │
│     │   └─▶ Falls vorhanden und !forceLiveCalculation → laden        │
│     │                                                                 │
│     └─▶ buildFreshStructure()                                        │
│         │                                                             │
│         ├─▶ loadRootUsers() - Top-Sponsoren ohne Parent              │
│         │                                                             │
│         ├─▶ loadParentsUsers() - Rekursive Downline                  │
│         │   └─▶ readParentsBusinessUsers() für jeden User            │
│         │                                                             │
│         ├─▶ calculateUserPointsOptimized()                           │
│         │   └─▶ Punkte pro Ebene (business_lines[1..n])              │
│         │                                                             │
│         └─▶ calcQualPP() für jeden User                              │
│             ├─▶ calcuQualLevel() - Erreichte Stufe                   │
│             ├─▶ setNextUserLevel() - Nächste Stufe                   │
│             └─▶ calculateCommissions() - Provisionen                  │
│                 ├─▶ Payline-Provisionen (Ebene 1-6)                  │
│                 └─▶ Growth Bonus (ab Ebene 7+)                       │
│                     └─▶ GrowthBonusCalculator                        │
└───────────────────────────────────────────────────────────────────────┘

3. Monatlicher Cron-Job

┌───────────────────────────────────────────────────────────────────────┐
│              BusinessUsersStoreOptimized (Cron)                       │
│                                                                       │
│  Ausführung: Einmal pro Monat (nach Monatsende)                      │
│                                                                       │
│  1. storeUserBusinessStructure()                                     │
│     └─▶ Erstellt UserBusinessStructure mit allen User-IDs            │
│                                                                       │
│  2. storeBusinessUsersDetail()                                       │
│     └─▶ Für jeden User: initBusinesslUserDetail() mit forceLive=true │
│         └─▶ Speichert UserBusiness Datensatz                         │
│                                                                       │
│  3. storeBusinessCompleted()                                         │
│     └─▶ Markiert Struktur als "completed"                            │
└───────────────────────────────────────────────────────────────────────┘

Punktetypen & Begriffe

Punktearten

Kürzel Name Beschreibung
KP Kunden-Punkte Eigene Bestellungen + Kundenbestellungen (Shop)
TP Team-Punkte KP + Punkte aus der Downline (Payline)
PP Payline-Punkte Summe der TP aus allen Ebenen bis zur Payline-Tiefe

Felder in UserSalesVolume

Feld Beschreibung
points Punkte dieser einzelnen Transaktion
month_KP_points Kumulierte KP-Punkte des Monats
month_TP_points Kumulierte TP-Punkte des Monats
month_shop_points Kumulierte Shop-Punkte des Monats
status 1=Berater-Bestellung, 2=Shop, 3=Shop-Pending, 4=Gutschrift, 5=Registrierung
status_points 1=KP+TP, 2=nur KP

Felder in UserBusiness

Feld Beschreibung
sales_volume_KP_points KP-Punkte
sales_volume_TP_points TP-Punkte
sales_volume_points_shop Shop-Punkte
sales_volume_points_KP_sum KP + Shop
sales_volume_points_TP_sum TP + Shop
payline_points Summe der Ebenen 1 bis Payline-Tiefe
payline_points_qual_kp payline_points + Rest-KP
business_lines JSON: Punkte pro Ebene {1: {points: X}, 2: {points: Y}...}
qual_user_level Erreichtes Qualifikations-Level (Array)
qual_user_level_next Nächste Provisions-Stufe
next_qual_user_level Nächstes erreichbares Level
commission_pp_total Payline-Provision
commission_shop_sales Shop-Provision
commission_growth_total Growth-Bonus (Tiefenbonus)

Level-System

Qualifikationsbedingungen

Level Name Min. KP (qual_kp) Min. PP (qual_pp) Paylines Growth Bonus
1 Junior Berater 150 0 3 -
2 Aktiv Junior Berater 250 500 3 -
3 Berater 350 1.000 4 -
4 Aktiv Berater 450 2.500 5 -
5 Vertriebspartner 600 5.000 6 -
6 Vertriebsleiter 600 9.000 6 -
7 Bronze Member 600 (690*) 18.000 6 1,0%
8 Silber Member 600 30.000 6 1,5%
9 Gold Member 600 50.000 6 2,0%
10 Diamant Member 600 100.000 6 2,5%
11 Platin Member* 600 250.000 7 3,0%
12 Platin Member** 600 500.000 7 3,5%
13 Platin Member*** 600 1.000.000 8 4,0%

*690 Punkte zur Auszahlung (Schecksicherung)

Payline-Prozentsätze (pr_line_X) - OHNE Growth Bonus

⚠️ Diese Werte sind NUR der Payline-Anteil. Growth Bonus wird separat berechnet!

Level E1 E2 E3 E4 E5 E6 E7 E8 Growth
Junior Berater 6% 3% 1% - - - - - -
Aktiv Junior Berater 6% 4% 2% - - - - - -
Berater 6% 5% 3% 2% - - - - -
Aktiv Berater 6% 5% 4% 2% 1% - - - -
Vertriebspartner 6% 6% 5% 3% 2% 1% - - -
Vertriebsleiter 6% 6% 6% 4% 2% 1% - - -
Bronze Member 6% 6% 6% 4% 2% 2% - - 1,0%
Silber Member 7% 7% 7% 4% 2% 2% - - 1,5%
Gold Member 7% 7% 7% 4% 2% 2% - - 2,0%
Diamant Member 7% 7% 7% 4% 2% 2% - - 2,5%
Platin Member* 7% 7% 7% 4% 3% 2% 1% - 3,0%
Platin Member** 7% 7% 7% 4% 3% 2% 1% - 3,5%
Platin Member*** 7% 7% 7% 4% 4% 3% 2% 1% 4,0%

Gesamt-Provision pro Ebene = pr_line_X + Growth Bonus (mit Differenz-Logik)

Qualifikations-Algorithmus

// In BusinessUserItemOptimized::calcuQualLevel()

1. Hole alle Levels wo qual_kp <= User's KP-Summe
2. Sortiere nach Position (höchstes zuerst)
3. Für jedes Level:
   a. Berechne payline_points für dieses Level (Ebenen 1 bis paylines)
   b. Berechne rest_kp = max(0, KP_sum - Level.qual_kp)
   c. payline_points_qual_kp = payline_points + rest_kp
   d. Wenn payline_points_qual_kp >= Level.qual_pp  QUALIFIZIERT
4. Return erstes qualifiziertes Level (höchstes)

Provisionsberechnung

1. Payline-Provisionen (Unilevel)

Feste Prozentsätze auf Teamumsatz, begrenzt auf Payline-Tiefe.

⚠️ WICHTIG: Die pr_line_X Werte in der DB sind NUR Payline (ohne Growth Bonus)!

Beispiel Gold Member (6 Paylines) - korrekte Werte:

Ebene Payline (pr_line_X) Growth Bonus Gesamt
1 7% +2% 9%
2 7% +2% 9%
3 7% +2% 9%
4 4% +2% 6%
5 2% +2% 4%
6 2% +2% 4%
7+ - +2% 2%
// In BusinessUserItemOptimized::calculateCommissions()
for ($i = 1; $i <= $qualUserLevel->paylines; $i++) {
    $points = $business_lines[$i]['points'];
    $margin = $qual_user_level['pr_line_' . $i];  // NUR Payline-Prozentsatz
    $commission = round($points / 100 * $margin, 2);
}
// Growth Bonus wird SEPARAT berechnet (siehe unten)

2. Growth Bonus (Tiefenbonus / Differenz-Bonus)

Aktivierung: Ab Bronze Member (Level 7+)

⚠️ Bug-Fix November 2025:

  • VOR Nov 2025: Growth Bonus war IN den pr_line_X Werten enthalten UND wurde nochmal separat berechnet = Doppelte Auszahlung!
  • AB Nov 2025: Growth Bonus wird NUR separat berechnet, pr_line_X enthält nur Payline-Anteil

Logik: Differenz zwischen eigenem Anspruch und bereits verteiltem Prozentsatz

Beispiel:
- User A: Diamant (2,5% Anspruch)
- User B (in A's Downline): Silber (1,5% Anspruch)

Punkte UNTER B:
- B erhält: 1,5% (sein voller Anspruch)
- A erhält: 2,5% - 1,5% = 1,0% (Differenz)

Punkte von B selbst (GAP):
- B erhält: 0% (kein Bonus auf sich selbst)
- A erhält: 2,5% (voller Anspruch, da B nicht "schützt")

Implementation: Siehe GrowthBonusCalculator.php und Growth-Bonus.md

3. Shop-Provision

$commission_shop_sales = sales_volume_total_shop / 100 * margin_shop;

Cron-Job (Monatsabschluss)

Datei: app/Cron/BusinessUsersStoreOptimized.php

Ausführung

# Typischerweise am 1. des Folgemonats
php artisan schedule:run
# Oder manuell:
php artisan business:store-monthly {month} {year}

Ablauf

  1. storeUserBusinessStructure()

    • Prüft ob bereits Struktur für Monat/Jahr existiert
    • Erstellt neue UserBusinessStructure mit allen User-IDs
    • Speichert komplette Baumstruktur als JSON
  2. storeBusinessUsersDetail()

    • Iteriert über alle User (aus users Array)
    • Für jeden nicht-abgeschlossenen User:
      • TreeCalcBotOptimized::initBusinesslUserDetail(user, forceLive=true)
      • Speichert UserBusiness Datensatz
      • Markiert User als "completed" in Struktur
  3. storeBusinessCompleted()

    • Prüft ob alle User abgeschlossen
    • Setzt completed = true auf Struktur

Performance

  • Typische Laufzeit: 10-60 Minuten (je nach User-Anzahl)
  • Memory: 512MB-1GB empfohlen
  • Kann in Batches/Chunks aufgeteilt werden

Dashboard-Integration

Dashboard-Statistiken (dashboard/_statistics.blade.php)

Metrik Datenquelle Beschreibung
Kunden-Umsatz Punkte UserSalesVolume.getPointsKPSum() KP + Shop
Team-Umsatz Punkte UserBusiness.payline_points Payline-Summe
Direkte Neupartner User WHERE m_sponsor = $userId AND active_date IN month Neue Firstlines
Neupartner im Team UserSalesVolume WHERE status = 5 (registration) Registrierungspunkte
Kundenabos UserAbo WHERE member_id = $userId Kunden-Abos
Teamabos UserAbo WHERE user_id IN firstline_ids Team-Abos

Punkte-Tabelle (dashboard/_points.blade.php)

Zeigt detaillierte UserSalesVolume Einträge für gewählten Monat/Jahr:

  • Datum, Punkte, Netto-Umsatz
  • Status (Berater-Bestellung, Shop, Gutschrift, Registrierung)
  • Bestellungs-Link, Kundeninformationen

Erweiterungen & TODO

Geplante Änderungen

  1. Dashboard-Statistiken erweitern

    • Monats/Jahr-Filter implementiert
    • Statistik-Kacheln hinzugefügt
  2. Marketingplan-Anpassungen (in Arbeit)

    • Level-Struktur überprüfen
    • Provisionsberechnung validieren
    • Growth-Bonus Differenz-Logik testen

Bekannte Einschränkungen

  • Growth Bonus nur ab November 2025 mit neuer Differenz-Logik
  • Vor November 2025: Legacy-Berechnung (pauschal ab Ebene 7+)
  • Struktur-Tiefe begrenzt auf 20-30 Ebenen (Performance)

Kontakt & Wartung

Letzte Aktualisierung: Dezember 2025 Version: BusinessPlan System v2.0

Log-Dateien

  • storage/logs/laravel.log - Allgemeine Logs
  • BusinessUserItem/TreeCalcBot Logs mit Prefix "BusinessUserItem:" / "TreeCalcBot:"

Cache löschen

// In Repository
$repository->clearCache();

// Oder manuell
Cache::forget("stored_structure_{$month}_{$year}");
Cache::forget("root_users_{$month}_{$year}");