319 lines
12 KiB
PHP
319 lines
12 KiB
PHP
<?php
|
|
|
|
namespace App\Console\Commands;
|
|
|
|
use Illuminate\Console\Command;
|
|
use App\Services\BusinessPlan\TreeCalcBotOptimized;
|
|
use App\Services\BusinessPlan\BusinessUserItemOptimized;
|
|
use App\Services\BusinessPlan\GrowthBonusCalculator;
|
|
use App\User;
|
|
use App\Models\UserBusiness;
|
|
use Carbon\Carbon;
|
|
|
|
class TestGrowthBonusCalculation extends Command
|
|
{
|
|
protected $signature = 'test:growth-bonus
|
|
{user_id : Die User-ID für den Test}
|
|
{--month=12 : Der Monat}
|
|
{--year=2025 : Das Jahr}
|
|
{--debug : Zeigt detaillierte Debug-Informationen}
|
|
{--from-db : Verwendet gespeicherte Daten und simuliert Berechnung}';
|
|
|
|
protected $description = 'Testet die Growth Bonus Berechnung für einen User';
|
|
|
|
public function handle()
|
|
{
|
|
$userId = $this->argument('user_id');
|
|
$month = (int) $this->option('month');
|
|
$year = (int) $this->option('year');
|
|
$debug = $this->option('debug');
|
|
$fromDb = $this->option('from-db');
|
|
|
|
$this->info("=== Growth Bonus Test ===");
|
|
$this->info("User: {$userId}, Monat: {$month}/{$year}");
|
|
$this->newLine();
|
|
|
|
// User laden
|
|
$user = User::find($userId);
|
|
if (!$user) {
|
|
$this->error("User {$userId} nicht gefunden!");
|
|
return 1;
|
|
}
|
|
|
|
$date = Carbon::createFromDate($year, $month, 1);
|
|
|
|
// Gespeicherte UserBusiness-Daten laden
|
|
$userBusiness = UserBusiness::where('user_id', $userId)
|
|
->where('month', $month)
|
|
->where('year', $year)
|
|
->first();
|
|
|
|
if ($userBusiness) {
|
|
$this->info("=== GESPEICHERTE DATEN (UserBusiness) ===");
|
|
$qualLevel = $userBusiness->qual_user_level;
|
|
$this->table(
|
|
['Feld', 'Wert'],
|
|
[
|
|
['user_id', $userBusiness->user_id],
|
|
['qual_user_level (Name)', $qualLevel['name'] ?? 'NULL'],
|
|
['Growth Bonus (aus qual_user_level)', $qualLevel['growth_bonus'] ?? 'NULL'],
|
|
['active_growth_bonus (gespeichert)', $userBusiness->active_growth_bonus ?? 'NULL'],
|
|
['commission_growth_total', $userBusiness->commission_growth_total ?? 0],
|
|
]
|
|
);
|
|
} else {
|
|
$this->warn("Keine gespeicherten UserBusiness-Daten für {$month}/{$year}");
|
|
if (!$fromDb) {
|
|
$this->info("Versuche Live-Berechnung...");
|
|
} else {
|
|
$this->error("--from-db erfordert gespeicherte Daten!");
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
if ($fromDb && $userBusiness) {
|
|
$this->testFromDatabase($userId, $month, $year, $debug);
|
|
} else {
|
|
$this->testLiveCalculation($user, $date, $month, $year, $debug);
|
|
}
|
|
|
|
$this->newLine();
|
|
$this->info("=== TEST ABGESCHLOSSEN ===");
|
|
|
|
return 0;
|
|
}
|
|
|
|
private function testFromDatabase(int $userId, int $month, int $year, bool $debug): void
|
|
{
|
|
$this->newLine();
|
|
$this->info("=== ANALYSE AUS DATENBANK ===");
|
|
|
|
// Lade User und seine Firstlines
|
|
$userBusiness = UserBusiness::where('user_id', $userId)
|
|
->where('month', $month)
|
|
->where('year', $year)
|
|
->first();
|
|
|
|
$qualLevel = $userBusiness->qual_user_level;
|
|
$myGrowthBonus = (float) ($qualLevel['growth_bonus'] ?? 0);
|
|
|
|
$this->info("Mein Growth Bonus Anspruch: {$myGrowthBonus}%");
|
|
|
|
if ($myGrowthBonus <= 0) {
|
|
$this->warn("Kein Growth Bonus Anspruch!");
|
|
return;
|
|
}
|
|
|
|
// Lade Firstlines
|
|
$firstlineIds = User::where('m_sponsor', $userId)->pluck('id')->toArray();
|
|
$this->info("Anzahl Firstlines: " . count($firstlineIds));
|
|
|
|
$this->newLine();
|
|
$this->info("=== FIRSTLINE ANALYSE ===");
|
|
|
|
$totalExpectedGrowth = 0;
|
|
$problemsFound = false;
|
|
|
|
foreach ($firstlineIds as $flId) {
|
|
$flBusiness = UserBusiness::where('user_id', $flId)
|
|
->where('month', $month)
|
|
->where('year', $year)
|
|
->first();
|
|
|
|
if (!$flBusiness) {
|
|
continue;
|
|
}
|
|
|
|
$flQualLevel = $flBusiness->qual_user_level;
|
|
$flGrowthBonus = (float) ($flQualLevel['growth_bonus'] ?? 0);
|
|
$flLevelName = $flQualLevel['name'] ?? 'Kein Level';
|
|
$flTPSum = (float) ($flBusiness->sales_volume_points_TP_sum ?? 0);
|
|
|
|
if ($flTPSum <= 0) {
|
|
continue;
|
|
}
|
|
|
|
// Berechne erwartete Differenz
|
|
$expectedDiff = max(0, $myGrowthBonus - $flGrowthBonus);
|
|
$expectedCommission = round($flTPSum / 100 * $expectedDiff, 2);
|
|
|
|
// Problem-Erkennung: Wenn FL einen Growth Bonus hat aber wir
|
|
// trotzdem den vollen Betrag bekommen
|
|
$isPotentialProblem = $flGrowthBonus > 0 && $expectedDiff < $myGrowthBonus;
|
|
|
|
$this->info("--- Firstline User {$flId} ---");
|
|
$this->table(
|
|
['Feld', 'Wert'],
|
|
[
|
|
['Level erreicht', $flLevelName],
|
|
['Growth Bonus (FL)', $flGrowthBonus . '%'],
|
|
['Team-Punkte (TP_sum)', number_format($flTPSum, 0, ',', '.')],
|
|
['Mein Anspruch', $myGrowthBonus . '%'],
|
|
['Differenz (erwartet)', $expectedDiff . '%'],
|
|
['Erwartete Provision', number_format($expectedCommission, 2, ',', '.') . ' €'],
|
|
['ACHTUNG: Blockade?', $isPotentialProblem ? 'JA - FL sollte blockieren!' : 'Nein'],
|
|
]
|
|
);
|
|
|
|
if ($isPotentialProblem) {
|
|
$problemsFound = true;
|
|
$this->error(" ⚠️ User {$flId} hat {$flLevelName} ({$flGrowthBonus}%) erreicht!");
|
|
$this->error(" Differenz sollte nur {$expectedDiff}% sein, nicht {$myGrowthBonus}%!");
|
|
}
|
|
|
|
$totalExpectedGrowth += $expectedCommission;
|
|
}
|
|
|
|
$this->newLine();
|
|
$this->info("=== ZUSAMMENFASSUNG ===");
|
|
$this->info("Erwartete Growth Bonus Summe (mit korrekter Differenz): " . number_format($totalExpectedGrowth, 2, ',', '.') . ' €');
|
|
$this->info("Gespeicherte Growth Bonus Summe: " . number_format($userBusiness->commission_growth_total ?? 0, 2, ',', '.') . ' €');
|
|
|
|
if ($problemsFound) {
|
|
$this->newLine();
|
|
$this->error("⚠️ PROBLEME GEFUNDEN! Die Blockade durch qualifizierte Firstlines funktioniert möglicherweise nicht korrekt.");
|
|
}
|
|
|
|
// Detailanalyse: Wie wurde die Berechnung durchgeführt?
|
|
if ($debug) {
|
|
$this->newLine();
|
|
$this->info("=== DEBUG: Rekursive Volumen-Analyse ===");
|
|
$this->analyzeVolumeDistribution($userId, $month, $year, $myGrowthBonus, 1);
|
|
}
|
|
}
|
|
|
|
private function analyzeVolumeDistribution(int $userId, int $month, int $year, float $myPercent, int $depth = 1): array
|
|
{
|
|
if ($depth > 10) {
|
|
return ['0.0' => 0];
|
|
}
|
|
|
|
$userBusiness = UserBusiness::where('user_id', $userId)
|
|
->where('month', $month)
|
|
->where('year', $year)
|
|
->first();
|
|
|
|
if (!$userBusiness) {
|
|
return ['0.0' => 0];
|
|
}
|
|
|
|
$qualLevel = $userBusiness->qual_user_level;
|
|
$myProtection = (float) ($qualLevel['growth_bonus'] ?? 0);
|
|
|
|
$indent = str_repeat(" ", $depth);
|
|
|
|
// Eigenes Volumen (TP_sum - aber nur direkte Punkte, nicht Team)
|
|
// Bei gespeicherten Daten ist das schwer zu unterscheiden
|
|
// Vereinfachung: Für den Test nehmen wir TP_sum als Gesamt-Volumen
|
|
|
|
$this->line("{$indent}User {$userId}: Protection={$myProtection}%");
|
|
|
|
// Lade Kinder
|
|
$childIds = User::where('m_sponsor', $userId)->pluck('id')->toArray();
|
|
|
|
$volumes = [];
|
|
|
|
foreach ($childIds as $childId) {
|
|
$childBusiness = UserBusiness::where('user_id', $childId)
|
|
->where('month', $month)
|
|
->where('year', $year)
|
|
->first();
|
|
|
|
if (!$childBusiness) {
|
|
continue;
|
|
}
|
|
|
|
$childTP = (float) ($childBusiness->sales_volume_points_TP_sum ?? 0);
|
|
if ($childTP <= 0) {
|
|
continue;
|
|
}
|
|
|
|
$childQual = $childBusiness->qual_user_level;
|
|
$childProtection = (float) ($childQual['growth_bonus'] ?? 0);
|
|
$childLevelName = $childQual['name'] ?? 'Kein Level';
|
|
|
|
// Berechne Differenz
|
|
$diff = max(0, $myPercent - $childProtection);
|
|
$commission = round($childTP / 100 * $diff, 2);
|
|
|
|
$this->line("{$indent} └─ Child {$childId}: {$childLevelName}, Protection={$childProtection}%, TP={$childTP}");
|
|
$this->line("{$indent} Differenz: {$myPercent}% - {$childProtection}% = {$diff}%");
|
|
$this->line("{$indent} Provision: {$childTP} * {$diff}% = {$commission}€");
|
|
|
|
if ($childProtection > 0) {
|
|
$this->warn("{$indent} ⚠️ BLOCKADE durch {$childLevelName}!");
|
|
}
|
|
}
|
|
|
|
return $volumes;
|
|
}
|
|
|
|
private function testLiveCalculation(User $user, Carbon $date, int $month, int $year, bool $debug): void
|
|
{
|
|
$this->newLine();
|
|
$this->info("=== LIVE-BERECHNUNG ===");
|
|
|
|
// TreeCalcBot erstellen
|
|
$treeCalcBot = new TreeCalcBotOptimized($month, $year, 'member', true);
|
|
|
|
// BusinessUserItem erstellen
|
|
$businessUserItem = new BusinessUserItemOptimized($date, $treeCalcBot);
|
|
$businessUserItem->makeUserFromModel($user, true);
|
|
$businessUserItem->addUserID();
|
|
|
|
// Kinder laden
|
|
$businessUserItem->readParentsBusinessUsers(true, 0);
|
|
|
|
// Qualifikation berechnen
|
|
$businessUserItem->calcQualPP(true);
|
|
|
|
$qualUserLevel = $businessUserItem->getQualUserLevel();
|
|
|
|
$this->table(
|
|
['Feld', 'Wert'],
|
|
[
|
|
['user_id', $businessUserItem->user_id],
|
|
['isQualLevel()', $businessUserItem->isQualLevel() ? 'JA' : 'NEIN'],
|
|
['isQualificationCalculated()', $businessUserItem->isQualificationCalculated() ? 'JA' : 'NEIN'],
|
|
['getQualUserLevel() (Name)', $qualUserLevel['name'] ?? 'NULL'],
|
|
['Growth Bonus (qual_user_level)', $qualUserLevel['growth_bonus'] ?? 'NULL'],
|
|
['getActiveGrowthBonus()', $businessUserItem->getActiveGrowthBonus()],
|
|
['getQualifiedGrowthBonus()', $businessUserItem->getQualifiedGrowthBonus()],
|
|
]
|
|
);
|
|
|
|
$this->newLine();
|
|
$this->info("=== FIRSTLINES (Kinder) ===");
|
|
|
|
if (empty($businessUserItem->businessUserItems)) {
|
|
$this->warn("Keine Firstlines geladen!");
|
|
} else {
|
|
foreach ($businessUserItem->businessUserItems as $index => $childItem) {
|
|
$childQual = $childItem->getQualUserLevel();
|
|
|
|
$this->info("--- Firstline " . ($index + 1) . " ---");
|
|
$this->table(
|
|
['Feld', 'Wert'],
|
|
[
|
|
['user_id', $childItem->user_id],
|
|
['isQualLevel()', $childItem->isQualLevel() ? 'JA' : 'NEIN'],
|
|
['getQualUserLevel() (Name)', $childQual['name'] ?? 'NULL'],
|
|
['Growth Bonus (qual_user_level)', $childQual['growth_bonus'] ?? 'NULL'],
|
|
['getActiveGrowthBonus()', $childItem->getActiveGrowthBonus()],
|
|
['getQualifiedGrowthBonus()', $childItem->getQualifiedGrowthBonus()],
|
|
['sales_volume_points_TP_sum', $childItem->sales_volume_points_TP_sum ?? 0],
|
|
]
|
|
);
|
|
}
|
|
}
|
|
|
|
if ($qualUserLevel && ($qualUserLevel['growth_bonus'] ?? 0) > 0) {
|
|
$calculator = new GrowthBonusCalculator();
|
|
$qualData = (object) $qualUserLevel;
|
|
$totalGrowthBonus = $calculator->calculate($businessUserItem, $qualData);
|
|
|
|
$this->newLine();
|
|
$this->info("Berechneter Growth Bonus: {$totalGrowthBonus}");
|
|
}
|
|
}
|
|
}
|