10.April 2026
This commit is contained in:
parent
a00c42e770
commit
f58c709945
208 changed files with 19280 additions and 2914 deletions
|
|
@ -1,27 +1,27 @@
|
|||
@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;
|
||||
|
|
@ -29,9 +29,13 @@
|
|||
// Live-Berechnung über TreeCalcBot (für aktuellen Monat)
|
||||
$isLiveCalculation = true;
|
||||
try {
|
||||
$treeCalcBot = new \App\Services\BusinessPlan\TreeCalcBot((int)$selectedMonth, (int)$selectedYear, 'member');
|
||||
$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;
|
||||
}
|
||||
|
|
@ -40,48 +44,50 @@
|
|||
$teamPaylinePoints = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Direkte Neupartner (Firstlines) in diesem Monat
|
||||
$directNewPartners = \App\User::where('m_sponsor', $user->id)
|
||||
->whereColumn('id', '!=', 'm_sponsor')
|
||||
->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) {
|
||||
$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)
|
||||
->whereColumn('id', '!=', 'm_sponsor')
|
||||
->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)) {
|
||||
|
|
@ -90,21 +96,21 @@
|
|||
->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')
|
||||
->where('is_for', 'ot')
|
||||
->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)) {
|
||||
|
|
@ -116,131 +122,152 @@
|
|||
}
|
||||
@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>
|
||||
@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>
|
||||
|
||||
{{-- 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 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 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>
|
||||
{{-- 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>
|
||||
</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>
|
||||
|
||||
{{-- 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>
|
||||
</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>
|
||||
{{-- 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>
|
||||
</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>
|
||||
{{-- 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 class="ml-3">
|
||||
<div class="text-muted small">{{ __('home.team_subscriptions') }}</div>
|
||||
<div class="font-weight-bold text-large">{{ $teamAbos }}</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>
|
||||
</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();
|
||||
}
|
||||
<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();
|
||||
$('#stats-month-filter, #stats-year-filter').on('change', function() {
|
||||
updateStatsFilter();
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</script>
|
||||
@endif
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue