mivita/resources/views/dashboard/_statistics.blade.php
2026-01-23 17:35:23 +01:00

246 lines
11 KiB
PHP

@php
$selectedMonth = request()->get('stats_month', date('n'));
$selectedYear = request()->get('stats_year', date('Y'));
// Start- und Enddatum für den Monat
$startDate = \Carbon\Carbon::createFromDate($selectedYear, $selectedMonth, 1)->startOfMonth();
$endDate = \Carbon\Carbon::createFromDate($selectedYear, $selectedMonth, 1)->endOfMonth();
// UserBusiness für den Monat laden (enthält Payline-Punkte)
$userBusiness = \App\Models\UserBusiness::where('user_id', $user->id)
->where('month', $selectedMonth)
->where('year', $selectedYear)
->first();
// UserSalesVolume für KP-Punkte
$userSalesVolume = $user->getUserSalesVolume($selectedMonth, $selectedYear, 'first');
// Kunden-Umsatz Punkte (KP - Eigene Punkte + Shop)
$customerPoints = $userSalesVolume ? $userSalesVolume->getPointsKPSum() : 0;
// Team-Umsatz Punkte (Payline) - Live-Berechnung wenn UserBusiness nicht verfügbar
$teamPaylinePoints = 0;
$isLiveCalculation = false;
if ($userBusiness) {
// Gespeicherte Daten aus UserBusiness verwenden
$teamPaylinePoints = $userBusiness->payline_points ?? 0;
} else {
// Live-Berechnung über TreeCalcBot (für aktuellen Monat)
$isLiveCalculation = true;
try {
$treeCalcBot = new \App\Services\BusinessPlan\TreeCalcBot((int)$selectedMonth, (int)$selectedYear, 'member');
$treeCalcBot->initBusinesslUserDetail($user);
if ($treeCalcBot->business_user) {
$teamPaylinePoints = $treeCalcBot->business_user->payline_points ?? 0;
}
} catch (\Exception $e) {
\Log::warning("Live-Berechnung Payline-Punkte fehlgeschlagen für User {$user->id}: " . $e->getMessage());
$teamPaylinePoints = 0;
}
}
// Direkte Neupartner (Firstlines) in diesem Monat
$directNewPartners = \App\User::where('m_sponsor', $user->id)
->where('active_date', '>=', $startDate)
->where('active_date', '<=', $endDate)
->where('m_level', '!=', null)
->where('payment_account', '!=', null)
->count();
// ===== REKURSIVE TEAM-STRUKTUR =====
// Hilfsfunktion um alle Team-Mitglieder rekursiv zu sammeln (inkl. Sponsor-Kette)
$getAllTeamMemberIds = function($sponsorId, $maxDepth = 20) use (&$getAllTeamMemberIds) {
static $cache = [];
if (isset($cache[$sponsorId])) {
return $cache[$sponsorId];
}
$teamIds = [];
$currentLevel = [$sponsorId];
$depth = 0;
while (!empty($currentLevel) && $depth < $maxDepth) {
$children = \App\User::whereIn('m_sponsor', $currentLevel)
->where('m_level', '!=', null)
->where('payment_account', '!=', null)
->whereNull('deleted_at')
->pluck('id')
->toArray();
$teamIds = array_merge($teamIds, $children);
$currentLevel = $children;
$depth++;
}
$cache[$sponsorId] = $teamIds;
return $teamIds;
};
// Alle Team-Mitglieder rekursiv laden
$allTeamMemberIds = $getAllTeamMemberIds($user->id);
// Neupartner im gesamten Team (rekursiv im Marketingplan)
$teamNewPartners = 0;
if (!empty($allTeamMemberIds)) {
$teamNewPartners = \App\User::whereIn('id', $allTeamMemberIds)
->where('active_date', '>=', $startDate)
->where('active_date', '<=', $endDate)
->count();
}
// Kundenabos (is_for = 'customer' oder shop-bezogen)
$customerAbos = \App\Models\UserAbo::where('member_id', $user->id)
->where('is_for', 'customer')
->whereIn('status', [1, 2]) // aktive Abos
->where('active', true)
->count();
// Eigene Abos
$ownAbos = \App\Models\UserAbo::where('user_id', $user->id)
->where('is_for', 'me')
->whereIn('status', [1, 2])
->where('active', true)
->count();
// Team-Abos (rekursiv über gesamtes Team im Marketingplan)
$teamAbos = 0;
if (!empty($allTeamMemberIds)) {
$teamAbos = \App\Models\UserAbo::whereIn('user_id', $allTeamMemberIds)
->where('is_for', 'me')
->whereIn('status', [1, 2])
->where('active', true)
->count();
}
@endphp
@if($user->isActiveAccount())
<div class="d-flex col-xl-12 align-items-stretch">
<div class="card w-100 mb-4">
<h5 class="card-header with-elements d-flex justify-content-between align-items-center flex-wrap">
<div class="card-header-title">
<i class="ion ion-md-stats mr-2"></i>{{__('home.monthly_statistics') }} - {{ HTMLHelper::getMonth($selectedMonth) }} {{ $selectedYear }}
</div>
<div class="d-flex align-items-center mt-2 mt-md-0">
<select id="stats-month-filter" class="form-control custom-select form-control-sm mr-2" style="width: auto;">
@foreach(HTMLHelper::getTransMonths() as $monthNum => $monthName)
<option value="{{ $monthNum }}" {{ $selectedMonth == $monthNum ? 'selected' : '' }}>{{ $monthName }}</option>
@endforeach
</select>
<select id="stats-year-filter" class="form-control custom-select form-control-sm" style="width: auto;">
@foreach(HTMLHelper::getYearRange() as $year)
<option value="{{ $year }}" {{ $selectedYear == $year ? 'selected' : '' }}>{{ $year }}</option>
@endforeach
</select>
</div>
</h5>
<div class="card-body">
<div class="row">
{{-- Kunden-Umsatz Punkte --}}
<div class="col-md-6 col-lg-4 mb-4">
<div class="d-flex align-items-center">
<div class="bg-primary text-white rounded-circle d-flex align-items-center justify-content-center" style="width: 50px; height: 50px;">
<i class="ion ion-md-cart" style="font-size: 1.5rem;"></i>
</div>
<div class="ml-3">
<div class="text-muted small">{{ __('home.customer_turnover_points') }}</div>
<div class="font-weight-bold text-large">{{ number_format($customerPoints, 0, ',', '.') }}</div>
</div>
</div>
</div>
{{-- Team-Umsatz Punkte (Payline) --}}
<div class="col-md-6 col-lg-4 mb-4">
<div class="d-flex align-items-center">
<div class="bg-success text-white rounded-circle d-flex align-items-center justify-content-center" style="width: 50px; height: 50px;">
<i class="ion ion-md-people" style="font-size: 1.5rem;"></i>
</div>
<div class="ml-3">
<div class="text-muted small">
{{ __('home.team_turnover_points') }} (Payline)
@if($isLiveCalculation)
<span class="badge badge-pill badge-info ml-1" title="{{ __('home.live_calculation_hint') }}">Live</span>
@endif
</div>
<div class="font-weight-bold text-large">{{ number_format($teamPaylinePoints, 0, ',', '.') }}</div>
</div>
</div>
</div>
{{-- Direkte Neupartner --}}
<div class="col-md-6 col-lg-4 mb-4">
<div class="d-flex align-items-center">
<div class="bg-info text-white rounded-circle d-flex align-items-center justify-content-center" style="width: 50px; height: 50px;">
<i class="ion ion-md-person-add" style="font-size: 1.5rem;"></i>
</div>
<div class="ml-3">
<div class="text-muted small">{{ __('home.direct_new_partners') }}</div>
<div class="font-weight-bold text-large">{{ $directNewPartners }}</div>
</div>
</div>
</div>
{{-- Neupartner im Team --}}
<div class="col-md-6 col-lg-4 mb-4">
<div class="d-flex align-items-center">
<div class="bg-warning text-white rounded-circle d-flex align-items-center justify-content-center" style="width: 50px; height: 50px;">
<i class="ion ion-md-contacts" style="font-size: 1.5rem;"></i>
</div>
<div class="ml-3">
<div class="text-muted small">{{ __('home.team_new_partners') }}</div>
<div class="font-weight-bold text-large">{{ $teamNewPartners }}</div>
</div>
</div>
</div>
{{-- Kundenabos --}}
<div class="col-md-6 col-lg-4 mb-4">
<div class="d-flex align-items-center">
<div class="bg-secondary text-white rounded-circle d-flex align-items-center justify-content-center" style="width: 50px; height: 50px;">
<i class="ion ion-md-repeat" style="font-size: 1.5rem;"></i>
</div>
<div class="ml-3">
<div class="text-muted small">{{ __('home.customer_subscriptions') }}</div>
<div class="font-weight-bold text-large">{{ $customerAbos }} + {{ $ownAbos }} {{ __('home.own') }}</div>
</div>
</div>
</div>
{{-- Team-Abos --}}
<div class="col-md-6 col-lg-4 mb-4">
<div class="d-flex align-items-center">
<div class="bg-dark text-white rounded-circle d-flex align-items-center justify-content-center" style="width: 50px; height: 50px;">
<i class="ion ion-md-sync" style="font-size: 1.5rem;"></i>
</div>
<div class="ml-3">
<div class="text-muted small">{{ __('home.team_subscriptions') }}</div>
<div class="font-weight-bold text-large">{{ $teamAbos }}</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
$(document).ready(function() {
// Filter für Monat/Jahr - Statistiken
function updateStatsFilter() {
var month = $('#stats-month-filter').val();
var year = $('#stats-year-filter').val();
var url = new URL(window.location.href);
url.searchParams.set('stats_month', month);
url.searchParams.set('stats_year', year);
window.location.href = url.toString();
}
$('#stats-month-filter, #stats-year-filter').on('change', function() {
updateStatsFilter();
});
});
</script>
@endif