23-01-2026

This commit is contained in:
Kevin Adametz 2026-01-23 17:35:23 +01:00
parent a939cd51ef
commit a8b395e20d
248 changed files with 29342 additions and 4805 deletions

View file

@ -6,6 +6,7 @@ use App\Models\UserBusiness;
use App\Models\UserLevel;
use App\User;
use Illuminate\Support\Collection;
use App\Services\BusinessPlan\TreeCalcBotOptimized;
class LevelReportService
{
@ -67,16 +68,29 @@ class LevelReportService
// Lade aktuellen User Level
$currentUser = $currentUserLevels->get($userBusiness->user_id);
$currentUserLevelName = 'Unbekannt';
$currentUserLevel = null;
if ($currentUser && $currentUser->m_level) {
$currentUserLevel = $userLevels->get($currentUser->m_level);
$currentUserLevelName = $currentUserLevel ? $currentUserLevel->name : 'Level ID: ' . $currentUser->m_level;
}
// Lade neues Level für POS-Vergleich (wird für Filter und level_updated benötigt)
$newLevel = $userLevels->get($newLevelId);
$newLevelPos = $newLevelData['pos'] ?? ($newLevel ? $newLevel->pos : 0);
// Filter: Nur User die noch nicht auf das neue Level umgestellt wurden
if ($onlyNotUpdated) {
if (!$currentUser || $currentUser->m_level == $newLevelId) {
continue; // Skip - User ist bereits auf das neue Level umgestellt
// Skip wenn:
// 1. User existiert nicht oder hat kein Level
// 2. User ist bereits auf dem neuen Level (gleiche ID)
// 3. User hat bereits ein höheres oder gleichwertiges Level (POS >= neue Level POS)
if (
!$currentUser ||
$currentUser->m_level == $newLevelId ||
($currentUserLevel && $currentUserLevel->pos >= $newLevelPos)
) {
continue; // Skip - User ist bereits auf das neue Level umgestellt oder hat bereits ein höheres Level
}
}
@ -100,7 +114,7 @@ class LevelReportService
'to_level_pos' => $newLevelData['pos'] ?? 0,
'current_user_level_id' => $currentUser ? $currentUser->m_level : null,
'current_user_level_name' => $currentUserLevelName,
'level_updated' => $onlyNotUpdated ? 'Nein' : ($currentUser && $currentUser->m_level == $newLevelId ? 'Ja' : 'Nein'),
'level_updated' => $onlyNotUpdated ? 'Nein' : ($currentUser && ($currentUser->m_level == $newLevelId || ($currentUserLevel && $currentUserLevel->pos >= $newLevelPos)) ? 'Ja' : 'Nein'),
'total_pp' => $userBusiness->total_pp ?? 0,
'total_qual_pp' => $userBusiness->total_qual_pp ?? 0,
'payline_points_qual_kp' => $userBusiness->payline_points_qual_kp ?? 0,
@ -155,7 +169,7 @@ class LevelReportService
return $stats;
}
public function exportToCsv(Collection $promotions, string $filename = null): string
public function exportToCsv(Collection $promotions, ?string $filename = null): string
{
if (!$filename) {
$filename = 'level_promotions_' . date('Y-m-d_H-i-s') . '.csv';
@ -229,4 +243,100 @@ class LevelReportService
return $filepath;
}
/**
* Holt Level-Aufstiege für ein Team basierend auf TreeCalcBotOptimized
* Nur für einen spezifischen Monat/Jahr und nur für Team-Mitglieder
*/
public function getTeamLevelPromotions(TreeCalcBotOptimized $treeCalcBot, int $month, int $year, array $filters = []): Collection
{
$onlyNotUpdated = $filters['only_not_updated'] ?? false;
// Lade UserLevels für Referenz
$userLevels = UserLevel::where('active', 1)->orderBy('pos')->get()->keyBy('id');
// Extrahiere alle User-IDs aus dem Team
$teamUserIds = $this->extractTeamUserIds($treeCalcBot);
if (empty($teamUserIds)) {
return collect([]);
}
// Lade UserBusiness Einträge für Team-Mitglieder mit Level-Aufstiegen
$userBusinesses = UserBusiness::whereIn('user_id', $teamUserIds)
->where('month', $month)
->where('year', $year)
->whereNotNull('next_qual_user_level')
->whereRaw("JSON_LENGTH(next_qual_user_level) > 0")
->orderBy('user_id')
->get();
return $this->processLevelPromotions($userBusinesses, $userLevels, $onlyNotUpdated);
}
/**
* Extrahiert alle User-IDs aus TreeCalcBotOptimized-Struktur
* Ähnlich wie getTeamUsersFromStructure im TeamController, aber nur IDs
*/
private function extractTeamUserIds(TreeCalcBotOptimized $treeCalcBot): array
{
$userIds = [];
$processedIds = [];
// Sammle User-IDs aus Root-Items
$businessUsers = $treeCalcBot->getItems();
foreach ($businessUsers as $businessUser) {
$userId = $businessUser->user_id ?? null;
if ($userId && !isset($processedIds[$userId])) {
$processedIds[$userId] = true;
$userIds[] = $userId;
$this->collectUserIdsRecursive($businessUser->businessUserItems ?? [], $userIds, $processedIds);
}
}
// Sammle parentless User-IDs
if ($treeCalcBot->isParentless()) {
$parentless = $treeCalcBot->__get('parentless');
if (is_array($parentless)) {
foreach ($parentless as $businessUser) {
if ($businessUser) {
$userId = $businessUser->user_id ?? null;
if ($userId && !isset($processedIds[$userId])) {
$processedIds[$userId] = true;
$userIds[] = $userId;
$this->collectUserIdsRecursive($businessUser->businessUserItems ?? [], $userIds, $processedIds);
}
}
}
}
}
return $userIds;
}
/**
* Sammelt rekursiv User-IDs aus businessUserItems
*/
private function collectUserIdsRecursive(array $businessUserItems, array &$userIds, array &$processedIds, int $depth = 0): void
{
$maxDepth = 20;
if ($depth > $maxDepth) {
return;
}
foreach ($businessUserItems as $businessUserItem) {
if ($businessUserItem) {
$userId = $businessUserItem->user_id ?? null;
if ($userId && !isset($processedIds[$userId])) {
$processedIds[$userId] = true;
$userIds[] = $userId;
// Rekursiv für verschachtelte Items
if (isset($businessUserItem->businessUserItems) && is_array($businessUserItem->businessUserItems)) {
$this->collectUserIdsRecursive($businessUserItem->businessUserItems, $userIds, $processedIds, $depth + 1);
}
}
}
}
}
}