mivita/resources/views/user/backoffice/statistics/my.blade.php
Kevin 7a620d66ae Backoffice-Statistik: Punkte-Fix (kumulative Snapshots) & Meine Statistik
Punkte/Umsatz korrekt aus per-Zeile points/total_net je status berechnen
statt SUM der kumulativen month_*-Snapshots (zaehlte massiv mehrfach).
Zentralisiert in SalesVolumePoints, genutzt von Dashboard- & Drilldown-Service.

Detail-Tabelle neu gegliedert: Eigenpunkte | Shop | Abo | Sonstige |
Kundenpunkte (=Summe) | Gesamt, mit gruener Hervorhebung der Basis-/Summenspalten.

Neue VIP-Seite "Meine Statistik" (Untermenue neben Team-Statistik):
KPI-Karten + nachvollziehbare Detailtabellen, gruppiert nach eigenen
Bestellungen, Shop-Bestellungen und Abos (PersonalStatisticsService).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 13:31:14 +00:00

204 lines
9.9 KiB
PHP

@extends('layouts.layout-2')
@section('content')
@php
$totals = $statistics['totals'];
$selectedMonthName = $filterMonths[(int) $selectedMonth] ?? $selectedMonth;
$fmt = fn($value) => \App\Services\Util::formatNumber($value);
$kpiCards = [
[
'label' => 'Eigenpunkte',
'value' => $totals['own_points'],
'icon' => 'ion-md-person',
'color' => 'success',
'highlight' => true,
],
[
'label' => 'Shop-Punkte',
'value' => $totals['shop_points'],
'icon' => 'ion-md-cart',
'color' => 'primary',
'highlight' => false,
],
[
'label' => 'Abo-Punkte',
'value' => $totals['abo_points'],
'icon' => 'ion-md-repeat',
'color' => 'info',
'highlight' => false,
],
[
'label' => 'Gesamtpunkte',
'value' => $totals['total_points'],
'icon' => 'ion-md-stats',
'color' => 'success',
'highlight' => true,
],
];
@endphp
<h4 class="font-weight-bold py-2 mb-2 d-flex justify-content-between align-items-center w-100">
<div>
{{ __('navigation.my_statistics') }}
<span class="badge badge-secondary ml-2">VIP</span>
</div>
</h4>
<div class="card mb-4">
<div class="card-body">
<div class="row align-items-center">
<div class="col-md-8">
<h5 class="mb-2">{{ __('navigation.my_statistics') }} — {{ $selectedMonthName }} {{ $selectedYear }}
</h5>
<p class="text-muted mb-md-0">
Nachvollziehbare Auflistung deiner Punkte und Umsätze des Monats, getrennt nach eigenen
Bestellungen, Shop-Bestellungen und Abos.
</p>
</div>
<div class="col-md-4 mt-3 mt-md-0">
<form method="GET" action="{{ route('user_my_statistics') }}"
class="form-inline justify-content-md-end">
<select name="month" class="form-control custom-select form-control-sm mr-2">
@foreach ($filterMonths as $monthNumber => $monthName)
<option value="{{ $monthNumber }}"
{{ (int) $selectedMonth === (int) $monthNumber ? 'selected' : '' }}>
{{ $monthName }}
</option>
@endforeach
</select>
<select name="year" class="form-control custom-select form-control-sm mr-2">
@foreach ($filterYears as $year)
<option value="{{ $year }}"
{{ (int) $selectedYear === (int) $year ? 'selected' : '' }}>
{{ $year }}
</option>
@endforeach
</select>
<button type="submit" class="btn btn-sm btn-primary">Anzeigen</button>
</form>
</div>
</div>
</div>
</div>
<div class="row mb-2">
@foreach ($kpiCards as $card)
<div class="col-md-6 col-lg-3 mb-4">
<div class="card h-100"
@if ($card['highlight']) style="background-color:#eafaf0;border:1px solid #c3e6cb;" @endif>
<div class="card-body d-flex justify-content-between align-items-center">
<div>
<div class="text-muted small">{{ $card['label'] }}</div>
<div class="display-4 font-weight-bold text-{{ $card['color'] }}">{{ $fmt($card['value']) }}
</div>
</div>
<span class="ion {{ $card['icon'] }} display-4 text-muted"></span>
</div>
</div>
</div>
@endforeach
</div>
<div class="card mb-4">
<div class="card-body py-3 d-flex flex-wrap align-items-center">
<span class="mr-4 mb-1">
<span class="text-muted small">Gesamtpunkte:</span>
<strong>{{ $fmt($totals['total_points']) }}</strong>
</span>
<span class="mb-1">
<span class="text-muted small">Umsatz (netto):</span>
<strong>{{ $fmt($totals['turnover_net']) }} &euro;</strong>
</span>
</div>
</div>
@foreach ($statistics['groups'] as $group)
@if ($group['rows'] !== [])
<div class="card mb-4">
<h5 class="card-header with-elements d-flex justify-content-between align-items-center flex-wrap">
<div class="card-header-title">{{ $group['label'] }}</div>
<div class="text-muted small">
{{ count($group['rows']) }} Einträge ·
<strong class="text-body">{{ $fmt($group['points']) }}</strong> Punkte ·
<strong class="text-body">{{ $fmt($group['net']) }} &euro;</strong>
</div>
</h5>
<div class="card-body p-0">
<div class="table-responsive">
<table class="table table-hover mb-0">
<thead>
<tr>
<th>Datum</th>
<th class="text-right">Punkte</th>
<th class="text-right">Netto</th>
<th>Typ</th>
<th>Bestellung</th>
@if (in_array($group['key'], ['shop', 'abo'], true))
<th>Kunde</th>
@endif
<th>Info</th>
</tr>
</thead>
<tbody>
@foreach ($group['rows'] as $row)
<tr>
<td class="font-weight-semibold">{{ $row['date'] }}</td>
<td class="text-right font-weight-semibold">{{ $fmt($row['points']) }}</td>
<td class="text-right">{{ $fmt($row['total_net']) }} &euro;</td>
<td>
<span
class="badge badge-pill badge-{{ $row['status_color'] }}">{{ $row['status_label'] }}</span>
</td>
<td>
@if ($row['order_id'] && $row['order_type'] === 'own')
<a href="{{ route('user_order_detail', [$row['order_id']]) }}"
class="btn btn-xs btn-primary">{{ $row['order_id'] }}</a>
@elseif ($row['order_id'] && $row['order_type'] === 'shop')
<a href="{{ route('user_shop_order_detail', [$row['order_id']]) }}"
class="btn btn-xs btn-secondary">{{ $row['order_id'] }}</a>
@else
<span class="text-muted">—</span>
@endif
</td>
@if (in_array($group['key'], ['shop', 'abo'], true))
<td>
@if ($row['customer_name'])
<span class="no-line-break">{{ $row['customer_name'] }}<br>
<small
class="text-muted">{{ $row['customer_email'] }}</small></span>
@else
<span class="text-muted">—</span>
@endif
</td>
@endif
<td><span class="no-line-break">{{ $row['info'] ?: $row['message'] }}</span></td>
</tr>
@endforeach
</tbody>
<tfoot>
<tr class="font-weight-bold bg-light">
<td>Summe</td>
<td class="text-right">{{ $fmt($group['points']) }}</td>
<td class="text-right">{{ $fmt($group['net']) }} &euro;</td>
<td colspan="{{ in_array($group['key'], ['shop', 'abo'], true) ? 4 : 3 }}"></td>
</tr>
</tfoot>
</table>
</div>
</div>
</div>
@endif
@endforeach
@php
$hasRows = collect($statistics['groups'])->contains(fn($group) => $group['rows'] !== []);
@endphp
@unless ($hasRows)
<div class="card mb-4">
<div class="card-body">
<p class="text-muted mb-0">{{ __('tables.no_data_available') }}</p>
</div>
</div>
@endunless
@endsection