mivita/app/Console/Commands/TestUserLevelUpdate.php
2026-01-23 17:35:23 +01:00

321 lines
12 KiB
PHP

<?php
namespace App\Console\Commands;
use App\User;
use App\Models\UserBusiness;
use App\Models\UserLevel;
use App\Cron\UserLevelUpdate;
use App\Console\Commands\BusinessStoreOptimized;
use Illuminate\Console\Command;
use ReflectionClass;
class TestUserLevelUpdate extends Command
{
/**
* php artisan test:user-level-update {month} {year} {--user_id=} {--send-mail} {--dry-run}
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'test:user-level-update {month} {year} {--user_id= : Test für spezifischen User} {--send-mail : E-Mail senden} {--dry-run : Nur anzeigen, nicht speichern}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Testet die UserLevelUpdate-Funktion aus BusinessStoreOptimized für einen Monat/Jahr oder spezifischen User';
/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
try {
$month = (int) $this->argument('month');
$year = (int) $this->argument('year');
$userId = $this->option('user_id') ? (int) $this->option('user_id') : null;
$sendMail = $this->option('send-mail');
$dryRun = $this->option('dry-run');
$this->info("===========================================");
$this->info("UserLevelUpdate Test");
$this->info("===========================================");
$this->line("Monat: {$month}");
$this->line("Jahr: {$year}");
if ($userId) {
$this->line("User ID: {$userId}");
}
$this->line("E-Mail senden: " . ($sendMail ? 'Ja' : 'Nein'));
$this->line("Dry-Run (nur zeigen): " . ($dryRun ? 'Ja' : 'Nein'));
$this->line("");
if ($dryRun) {
// Im Dry-Run Modus zeigen wir nur die Analyse
$this->performDryRunAnalysis($month, $year, $userId);
} else {
// Nutze die originale Funktion aus BusinessStoreOptimized
$this->runOriginalFunction($month, $year, $sendMail);
}
$this->info("");
$this->info("===========================================");
$this->info("Test abgeschlossen!");
$this->info("===========================================");
return 0;
} catch (\Exception $e) {
$this->error('Test fehlgeschlagen: ' . $e->getMessage());
$this->error('Stack trace: ' . $e->getTraceAsString());
return 1;
}
}
/**
* Führt die originale userLevelUpdate Funktion aus BusinessStoreOptimized aus
*/
private function runOriginalFunction(int $month, int $year, bool $sendMail)
{
$this->info("Erstelle BusinessStoreOptimized Instanz...");
// Erstelle BusinessStoreOptimized Command-Instanz
$businessStoreCommand = new BusinessStoreOptimized();
// Setze Output auf aktuellen Command (damit Ausgaben weitergeleitet werden)
$businessStoreCommand->setOutput($this->output);
// Setze Monat und Jahr über Reflection (da private)
$reflection = new ReflectionClass($businessStoreCommand);
$monthProperty = $reflection->getProperty('month');
$monthProperty->setAccessible(true);
$monthProperty->setValue($businessStoreCommand, $month);
$yearProperty = $reflection->getProperty('year');
$yearProperty->setAccessible(true);
$yearProperty->setValue($businessStoreCommand, $year);
$timeStartProperty = $reflection->getProperty('timeStart');
$timeStartProperty->setAccessible(true);
$timeStartProperty->setValue($businessStoreCommand, microtime(true));
// Setze sendUpdateMail
$businessStoreCommand->setSendUpdateMail($sendMail);
$this->info("Führe originale userLevelUpdate() Funktion aus...");
$this->line("");
// Rufe die originale Funktion auf
$businessStoreCommand->userLevelUpdate();
}
/**
* Führt Dry-Run Analyse durch
*/
private function performDryRunAnalysis(int $month, int $year, ?int $userId)
{
$userLevelUpdate = new UserLevelUpdate($month, $year);
if ($userId) {
// Test für spezifischen User
$this->testSingleUserDryRun($userLevelUpdate, $userId);
} else {
// Test für alle User
$this->testAllUsersDryRun($userLevelUpdate);
}
}
/**
* Dry-Run Analyse für einen spezifischen User
*/
private function testSingleUserDryRun(UserLevelUpdate $userLevelUpdate, int $userId)
{
$userBusiness = UserBusiness::with('user')
->where('month', $this->argument('month'))
->where('year', $this->argument('year'))
->where('user_id', $userId)
->whereNotNull('next_qual_user_level')
->whereRaw("JSON_LENGTH(next_qual_user_level) > 0")
->first();
if (!$userBusiness) {
$this->warn("Keine UserBusiness mit next_qual_user_level gefunden für User ID: {$userId}");
// Zeige vorhandene UserBusiness-Daten
$anyUserBusiness = UserBusiness::where('user_id', $userId)
->where('month', $this->argument('month'))
->where('year', $this->argument('year'))
->first();
if ($anyUserBusiness) {
$this->info("UserBusiness existiert, aber hat kein next_qual_user_level");
$this->line("Current Level ID: " . ($anyUserBusiness->m_level_id ?? 'NULL'));
$this->line("next_qual_user_level: " . (is_null($anyUserBusiness->next_qual_user_level) ? 'NULL' : json_encode($anyUserBusiness->next_qual_user_level)));
} else {
$this->warn("Keine UserBusiness gefunden für diesen Monat/Jahr");
}
return;
}
$this->displayUserBusinessInfo($userBusiness);
$this->info("");
$this->info("DRY-RUN MODUS: Änderungen werden nicht gespeichert");
$this->analyzeLevelUpdate($userBusiness);
}
/**
* Dry-Run Analyse für alle User
*/
private function testAllUsersDryRun(UserLevelUpdate $userLevelUpdate)
{
$levelUpdateUsers = $userLevelUpdate->getUserBusinessByMonthYear();
$this->info("Gefunden: " . $levelUpdateUsers->count() . " UserBusiness-Einträge mit next_qual_user_level");
$this->line("");
if ($levelUpdateUsers->count() === 0) {
$this->warn("Keine UserBusiness-Einträge mit Level-Updates gefunden.");
return;
}
$this->info("DRY-RUN MODUS: Änderungen werden nicht gespeichert");
$this->line("");
foreach ($levelUpdateUsers as $userBusiness) {
$this->line("---------------------------------------------------");
$this->displayUserBusinessInfo($userBusiness);
$this->analyzeLevelUpdate($userBusiness);
$this->line("");
}
}
/**
* Zeigt Informationen über UserBusiness
*/
private function displayUserBusinessInfo(UserBusiness $userBusiness)
{
$user = $userBusiness->user;
$this->line("User ID: " . ($user ? $user->id : 'NULL'));
$this->line("E-Mail: " . ($user ? $user->email : 'N/A'));
$this->line("Aktuelles Level: " . ($user && $user->m_level ? $user->m_level . ' (' . $this->getLevelName($user->m_level) . ')' : 'Kein Level'));
$this->line("UserBusiness Level ID: " . ($userBusiness->m_level_id ?? 'NULL'));
$this->line("UserBusiness Level Name: " . ($userBusiness->user_level_name ?? 'NULL'));
$nextQual = $userBusiness->next_qual_user_level;
if (is_array($nextQual)) {
if (isset($nextQual['id'])) {
// Einzelnes Level
$this->line("Nächstes qualifiziertes Level: ID " . $nextQual['id'] . ' - ' . ($nextQual['name'] ?? 'N/A') . ' (POS: ' . ($nextQual['pos'] ?? 'N/A') . ')');
$this->line(" Bereits aktualisiert: " . (isset($nextQual['hasUpdated']) && $nextQual['hasUpdated'] == 1 ? 'Ja' : 'Nein'));
} else {
// Array von Leveln
$this->line("Nächste qualifizierte Level: " . count($nextQual) . " Level gefunden");
foreach ($nextQual as $idx => $level) {
if (is_array($level) && isset($level['id'])) {
$updated = isset($level['hasUpdated']) && $level['hasUpdated'] == 1 ? ' (bereits aktualisiert)' : '';
$this->line(" [{$idx}] ID " . $level['id'] . ' - ' . ($level['name'] ?? 'N/A') . ' (POS: ' . ($level['pos'] ?? 'N/A') . ')' . $updated);
}
}
}
} else {
$this->line("next_qual_user_level: " . (is_null($nextQual) ? 'NULL' : gettype($nextQual)));
}
$this->line("Total Qual PP: " . ($userBusiness->total_qual_pp ?? 0));
}
/**
* Analysiert ob und wie ein Level-Update durchgeführt würde (Dry-Run)
*/
private function analyzeLevelUpdate(UserBusiness $userBusiness)
{
$user = $userBusiness->user;
if (!$user) {
$this->warn("⚠ Kein User-Objekt vorhanden");
return;
}
$nextQual = $userBusiness->next_qual_user_level;
if (!is_array($nextQual) || empty($nextQual)) {
$this->warn("⚠ next_qual_user_level ist kein gültiges Array");
return;
}
// Lade UserLevels für Vergleich
$userLevels = UserLevel::where('active', 1)->orderBy('pos')->get()->keyBy('id');
// Prüfe ob einzelnes Level oder Array
$levelArray = isset($nextQual['id']) ? [$nextQual] : $nextQual;
$currentUserLevel = null;
if ($user->m_level) {
$currentUserLevel = $userLevels->get($user->m_level);
}
$this->info("");
$this->info("📊 Analyse:");
if ($currentUserLevel) {
$this->line(" Aktuelles Level POS: {$currentUserLevel->pos}");
} else {
$this->line(" Aktuelles Level: Kein Level gesetzt");
}
$wouldUpdate = false;
$highestLevel = null;
$highestPos = 0;
foreach ($levelArray as $levelData) {
if (!is_array($levelData) || !isset($levelData['id'])) {
continue;
}
if (isset($levelData['hasUpdated']) && $levelData['hasUpdated'] == 1) {
$this->line(" ⏭ Level ID {$levelData['id']} wurde bereits aktualisiert");
continue;
}
$newLevel = $userLevels->get($levelData['id']);
$newLevelPos = $newLevel ? $newLevel->pos : ($levelData['pos'] ?? 0);
$levelName = $levelData['name'] ?? 'N/A';
$this->line(" 📈 Level ID {$levelData['id']} ({$levelName}): POS {$newLevelPos}");
if (!$currentUserLevel || $newLevelPos > $currentUserLevel->pos) {
if ($newLevelPos > $highestPos) {
$highestPos = $newLevelPos;
$highestLevel = $levelData;
$wouldUpdate = true;
}
} else {
$this->line(" ⚠ Level ist nicht höher als aktuelles Level (POS {$currentUserLevel->pos})");
}
}
if ($wouldUpdate && $highestLevel) {
$this->info("");
$highestLevelName = $highestLevel['name'] ?? 'N/A';
$this->info("✅ Würde Level aktualisieren zu: {$highestLevel['id']} ({$highestLevelName})");
$this->line(" Von: " . ($currentUserLevel ? "POS {$currentUserLevel->pos}" : "Kein Level") . " → Zu: POS {$highestPos}");
} else {
$this->info("");
$this->warn("⚠ Kein Level-Update würde durchgeführt:");
if (!$wouldUpdate) {
$this->line(" Kein höheres Level gefunden");
}
}
}
/**
* Holt Level-Name nach ID
*/
private function getLevelName($levelId)
{
$level = UserLevel::find($levelId);
return $level ? $level->name : 'Unbekannt';
}
}