badge-outline-primary ist nur im Corporate-Theme definiert; im aktiven Theme fiel der Text auf color:#fff zurueck. Solides badge-primary wie in den uebrigen Ansichten. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
254 lines
22 KiB
PHP
254 lines
22 KiB
PHP
@extends('layouts.layout-2')
|
||
|
||
@section('content')
|
||
@php
|
||
// Baum-Definition der aufrufenden Uebersicht; Fallback fuer direkte Aufrufe ohne Controller-Variable.
|
||
$selectedTree = $selectedTree ?? ($details['tree'] ?? \App\Services\Backoffice\BackofficeDashboardService::TREE_COMMISSION);
|
||
@endphp
|
||
<h4 class="font-weight-bold py-2 mb-2 d-flex justify-content-between align-items-center w-100">
|
||
<div>
|
||
{{ __('navigation.statistics') }} / {{ $details['metric_label'] }}
|
||
<span class="badge badge-secondary ml-2">VIP</span>
|
||
@if (! empty($details['only_new']))
|
||
<span class="badge badge-success ml-1">Nur neue im {{ $details['month'] }}/{{ $details['year'] }}</span>
|
||
@endif
|
||
</div>
|
||
<div>
|
||
<a href="{{ route('user_backoffice_statistics_export', [
|
||
'line' => $details['line'],
|
||
'metric' => $details['metric'],
|
||
'month' => $selectedMonth,
|
||
'year' => $selectedYear,
|
||
'tree' => $selectedTree,
|
||
'only_new' => ($details['only_new'] ?? false) ? 1 : 0,
|
||
]) }}"
|
||
class="btn btn-sm btn-outline-secondary mr-2">
|
||
<span class="ion ion-md-download mr-1"></span> CSV
|
||
</a>
|
||
<a href="{{ route('user_backoffice_statistics', ['month' => $selectedMonth, 'year' => $selectedYear, 'tree' => $selectedTree]) }}"
|
||
class="btn btn-sm btn-default">
|
||
{{ __('back') }}
|
||
</a>
|
||
</div>
|
||
</h4>
|
||
|
||
<div class="card mb-4">
|
||
<div class="card-body">
|
||
<div class="row">
|
||
<div class="col-md-3 mb-2">
|
||
<div class="text-muted small">Linie</div>
|
||
<strong>{{ $details['line_label'] }}</strong>
|
||
</div>
|
||
<div class="col-md-3 mb-2">
|
||
<div class="text-muted small">Zeitraum</div>
|
||
<strong>{{ $details['month'] }}/{{ $details['year'] }}</strong>
|
||
</div>
|
||
<div class="col-md-3 mb-2">
|
||
<div class="text-muted small">Kennzahl</div>
|
||
<strong>{{ $details['metric_label'] }}</strong>
|
||
</div>
|
||
<div class="col-md-3 mb-2">
|
||
<div class="text-muted small">Treffer</div>
|
||
<strong>{{ number_format($details['summary']['count'], 0, ',', '.') }}</strong>
|
||
</div>
|
||
<div class="col-md-12">
|
||
<div class="text-muted small">Baum-Definition</div>
|
||
<span class="badge badge-primary">{{ $details['tree_label'] ?? '' }}</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="card-body p-0">
|
||
<div class="alert alert-warning rounded-0 border-left-0 border-right-0 border-top-0 mb-0">
|
||
<strong>Datenschutz-Hinweis:</strong>
|
||
Die Anzeige personenbezogener Detaildaten befindet sich noch in rechtlicher Klärung und ist aktuell nur für berechtigte VIP-Auswertungen vorgesehen.
|
||
</div>
|
||
@if ($details['rows'] === [])
|
||
<div class="p-4">
|
||
<p class="text-muted mb-0">{{ __('tables.no_data_available') }}</p>
|
||
</div>
|
||
@else
|
||
<div class="p-3 border-bottom">
|
||
<div class="input-group">
|
||
<div class="input-group-prepend">
|
||
<span class="input-group-text">
|
||
<span class="ion ion-ios-search"></span>
|
||
</span>
|
||
</div>
|
||
<input type="search" id="backoffice-statistics-detail-search" class="form-control"
|
||
placeholder="Detailtabelle durchsuchen...">
|
||
</div>
|
||
<small class="text-muted d-block mt-2">
|
||
Suche nach Name, E-Mail, Status, Punkten oder Datum. Die Summenzeile bleibt unverändert.
|
||
</small>
|
||
</div>
|
||
<div class="table-responsive">
|
||
<table class="table table-hover mb-0" id="backoffice-statistics-detail-table">
|
||
<thead>
|
||
<tr>
|
||
<th data-sortable="true"><span class="sortable-label">Name <i class="ion ion-ios-swap sort-icon"></i></span></th>
|
||
<th data-sortable="true"><span class="sortable-label">E-Mail <i class="ion ion-ios-swap sort-icon"></i></span></th>
|
||
<th data-sortable="true"><span class="sortable-label">Karriere-Level <i class="ion ion-ios-swap sort-icon"></i></span></th>
|
||
@if ($details['metric'] === 'team_customer_abos')
|
||
<th class="text-right" data-sortable="true" data-sort-type="number"><span class="sortable-label justify-content-end">Kundenabos <i class="ion ion-ios-swap sort-icon"></i></span></th>
|
||
<th class="text-right" data-sortable="true" data-sort-type="number"><span class="sortable-label justify-content-end">Volumenpunkte gesamt <i class="ion ion-ios-swap sort-icon"></i></span></th>
|
||
@elseif ($details['metric'] === 'team_partner_abos')
|
||
<th data-sortable="true"><span class="sortable-label">Berater <i class="ion ion-ios-swap sort-icon"></i></span></th>
|
||
<th class="text-right" data-sortable="true" data-sort-type="number"><span class="sortable-label justify-content-end">Abo-Punkte <i class="ion ion-ios-swap sort-icon"></i></span></th>
|
||
<th data-sortable="true"><span class="sortable-label">Status <i class="ion ion-ios-swap sort-icon"></i></span></th>
|
||
<th data-sortable="true" data-sort-type="date"><span class="sortable-label">Besteht seit <i class="ion ion-ios-swap sort-icon"></i></span></th>
|
||
<th data-sortable="true" data-sort-type="date"><span class="sortable-label">Nächste Ausführung <i class="ion ion-ios-swap sort-icon"></i></span></th>
|
||
<th class="text-right" data-sortable="true" data-sort-type="number"><span class="sortable-label justify-content-end">Lieferungen <i class="ion ion-ios-swap sort-icon"></i></span></th>
|
||
@elseif (in_array($details['metric'], ['own_points', 'external_points', 'customer_abo_points', 'customer_single_order_points', 'customer_other_points', 'total_points', 'shop_1000'], true))
|
||
<th class="text-right" data-sortable="true" data-sort-type="number" style="background-color:#d4edda;"><span class="sortable-label justify-content-end">Eigenpunkte <i class="ion ion-ios-swap sort-icon"></i></span></th>
|
||
<th class="text-right" data-sortable="true" data-sort-type="number"><span class="sortable-label justify-content-end">Shop-Punkte <i class="ion ion-ios-swap sort-icon"></i></span></th>
|
||
<th class="text-right" data-sortable="true" data-sort-type="number"><span class="sortable-label justify-content-end">Abo-Punkte <i class="ion ion-ios-swap sort-icon"></i></span></th>
|
||
<th class="text-right" data-sortable="true" data-sort-type="number"><span class="sortable-label justify-content-end">Sonstige Punkte <i class="ion ion-ios-swap sort-icon"></i></span></th>
|
||
<th class="text-right" data-sortable="true" data-sort-type="number" style="background-color:#d4edda;"><span class="sortable-label justify-content-end">Kundenpunkte <i class="ion ion-ios-swap sort-icon"></i></span></th>
|
||
<th class="text-right" data-sortable="true" data-sort-type="number"><span class="sortable-label justify-content-end">Gesamtpunkte <i class="ion ion-ios-swap sort-icon"></i></span></th>
|
||
@elseif ($details['metric'] === 'new_partners')
|
||
<th data-sortable="true"><span class="sortable-label">Telefon <i class="ion ion-ios-swap sort-icon"></i></span></th>
|
||
<th data-sortable="true"><span class="sortable-label">Sponsor <i class="ion ion-ios-swap sort-icon"></i></span></th>
|
||
<th class="text-right" data-sortable="true" data-sort-type="number" title="Punkte aus den Bestellungen SEINER Kunden (Shop und Abo) — ohne seine eigenen Bestellungen."><span class="sortable-label justify-content-end">Punkte seiner Kunden <i class="ion ion-ios-swap sort-icon"></i></span></th>
|
||
<th class="text-right" data-sortable="true" data-sort-type="number" title="Punkte seiner Kunden PLUS seine eigenen Bestellungen — hier steckt vor allem das Starterpaket drin."><span class="sortable-label justify-content-end">Gesamt (inkl. Eigenbestellung) <i class="ion ion-ios-swap sort-icon"></i></span></th>
|
||
<th data-sortable="true" data-sort-type="date"><span class="sortable-label">Aktiv seit <i class="ion ion-ios-swap sort-icon"></i></span></th>
|
||
<th data-sortable="true" data-sort-type="date"><span class="sortable-label">Account gültig bis <i class="ion ion-ios-swap sort-icon"></i></span></th>
|
||
@else
|
||
<th data-sortable="true" data-sort-type="date"><span class="sortable-label">Aktiv seit <i class="ion ion-ios-swap sort-icon"></i></span></th>
|
||
<th data-sortable="true" data-sort-type="date"><span class="sortable-label">Account gültig bis <i class="ion ion-ios-swap sort-icon"></i></span></th>
|
||
@endif
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
@foreach ($details['rows'] as $row)
|
||
<tr
|
||
class="{{ isset($row['is_account_active']) && ! $row['is_account_active'] ? 'table-danger' : '' }} {{ ! empty($row['is_new_this_month']) ? 'table-success' : '' }}">
|
||
<td class="font-weight-semibold">{{ $row['name'] }}</td>
|
||
<td>{{ $row['email'] ?? '-' }}</td>
|
||
<td>{{ $row['career_level'] ?? '-' }}</td>
|
||
@if ($details['metric'] === 'team_customer_abos')
|
||
<td class="text-right" data-sort-value="{{ $row['abo_count'] }}">{{ number_format($row['abo_count'], 0, ',', '.') }}</td>
|
||
<td class="text-right" data-sort-value="{{ $row['points'] }}">
|
||
<span class="font-weight-bold">{{ \App\Services\Util::formatNumber($row['points']) }}</span>
|
||
@if (! empty($row['abos']))
|
||
<a class="d-block small" data-toggle="collapse"
|
||
href="#customer-abos-{{ $loop->index }}" role="button">
|
||
Abos anzeigen
|
||
</a>
|
||
<div class="collapse text-left" id="customer-abos-{{ $loop->index }}">
|
||
<ul class="list-unstyled small text-muted mt-2 mb-0">
|
||
@foreach ($row['abos'] as $aboItem)
|
||
<li>
|
||
{{ $aboItem['start_date'] ?? '-' }} →
|
||
{{ $aboItem['next_date'] ?? '-' }}:
|
||
<span class="font-weight-semibold">{{ \App\Services\Util::formatNumber($aboItem['points']) }}</span> P.
|
||
@if (! empty($aboItem['is_new_this_month']))
|
||
<span class="badge badge-success ml-1">Neu</span>
|
||
@endif
|
||
</li>
|
||
@endforeach
|
||
</ul>
|
||
</div>
|
||
@endif
|
||
</td>
|
||
@elseif ($details['metric'] === 'team_partner_abos')
|
||
<td>{{ $row['consultant_name'] ?? $row['name'] }}</td>
|
||
<td class="text-right" data-sort-value="{{ $row['points'] }}">{{ \App\Services\Util::formatNumber($row['points']) }}</td>
|
||
<td data-sort-value="{{ $row['status_label'] ?? '' }}">
|
||
{!! $row['status_badge'] ?? '' !!}
|
||
@if (! empty($row['status_reason']))
|
||
<div class="small text-muted mt-1">{{ $row['status_reason'] }}</div>
|
||
@endif
|
||
</td>
|
||
<td data-sort-value="{{ $row['start_date_sort'] ?? '' }}">
|
||
{{ $row['start_date'] ?? '-' }}
|
||
@if (! empty($row['is_new_this_month']))
|
||
<span class="badge badge-success ml-1">Neu</span>
|
||
@endif
|
||
</td>
|
||
<td data-sort-value="{{ $row['next_date_sort'] ?? '' }}">{{ $row['next_date'] ?? '-' }}</td>
|
||
<td class="text-right" data-sort-value="{{ $row['deliveries'] }}">{{ number_format($row['deliveries'], 0, ',', '.') }}</td>
|
||
@elseif (in_array($details['metric'], ['own_points', 'external_points', 'customer_abo_points', 'customer_single_order_points', 'customer_other_points', 'total_points', 'shop_1000'], true))
|
||
<td class="text-right" data-sort-value="{{ $row['own_points'] }}"><span class="badge" style="background-color:#d4edda;color:#155724;font-size:90%;">{{ \App\Services\Util::formatNumber($row['own_points']) }}</span></td>
|
||
<td class="text-right" data-sort-value="{{ $row['customer_single_order_points'] }}">{{ \App\Services\Util::formatNumber($row['customer_single_order_points']) }}</td>
|
||
<td class="text-right" data-sort-value="{{ $row['customer_abo_points'] }}">{{ \App\Services\Util::formatNumber($row['customer_abo_points']) }}</td>
|
||
<td class="text-right" data-sort-value="{{ $row['customer_other_points'] }}">{{ \App\Services\Util::formatNumber($row['customer_other_points']) }}</td>
|
||
<td class="text-right font-weight-bold" data-sort-value="{{ $row['external_points'] }}"><span class="badge" style="background-color:#d4edda;color:#155724;font-size:90%;">{{ \App\Services\Util::formatNumber($row['external_points']) }}</span></td>
|
||
<td class="text-right font-weight-bold" data-sort-value="{{ $row['total_points'] }}">
|
||
{{ \App\Services\Util::formatNumber($row['total_points']) }}
|
||
@if (! empty($row['storno_floor_points']))
|
||
<div class="text-muted small font-weight-normal" title="Negativer Monatssaldo — die Provisionsberechnung wertet ihn mit 0.">Saldo −{{ \App\Services\Util::formatNumber($row['storno_floor_points']) }} → 0</div>
|
||
@endif
|
||
</td>
|
||
@elseif ($details['metric'] === 'new_partners')
|
||
<td>{{ ($row['phone'] ?? '') !== '' ? $row['phone'] : '-' }}</td>
|
||
<td>{{ $row['sponsor'] ?? '-' }}</td>
|
||
<td class="text-right font-weight-bold" data-sort-value="{{ $row['customer_points'] ?? 0 }}">{{ \App\Services\Util::formatNumber($row['customer_points'] ?? 0) }}</td>
|
||
<td class="text-right font-weight-bold" data-sort-value="{{ $row['total_points'] ?? 0 }}">{{ \App\Services\Util::formatNumber($row['total_points'] ?? 0) }}</td>
|
||
<td data-sort-value="{{ $row['active_date_sort'] ?? '' }}">{{ $row['active_date'] ?? '-' }}</td>
|
||
<td data-sort-value="{{ $row['payment_account_sort'] ?? '' }}">{{ $row['payment_account'] ?? '-' }}</td>
|
||
@else
|
||
<td data-sort-value="{{ $row['active_date_sort'] ?? '' }}">{{ $row['active_date'] ?? '-' }}</td>
|
||
<td data-sort-value="{{ $row['payment_account_sort'] ?? '' }}">
|
||
{{ $row['payment_account'] ?? '-' }}
|
||
@if (isset($row['is_account_active']))
|
||
<span
|
||
class="badge badge-{{ $row['is_account_active'] ? 'success' : 'danger' }} ml-1">
|
||
{{ $row['account_status'] }}
|
||
</span>
|
||
@endif
|
||
</td>
|
||
@endif
|
||
</tr>
|
||
@endforeach
|
||
</tbody>
|
||
<tfoot>
|
||
<tr class="font-weight-bold bg-light">
|
||
<td>Summe</td>
|
||
<td class="text-muted">{{ number_format($details['summary']['count'], 0, ',', '.') }} Einträge</td>
|
||
<td></td>
|
||
@if ($details['metric'] === 'team_customer_abos')
|
||
<td class="text-right">{{ number_format($details['summary']['abo_count'], 0, ',', '.') }}</td>
|
||
<td class="text-right">{{ \App\Services\Util::formatNumber($details['summary']['points']) }}</td>
|
||
@elseif ($details['metric'] === 'team_partner_abos')
|
||
<td></td>
|
||
<td class="text-right">{{ \App\Services\Util::formatNumber($details['summary']['points']) }}</td>
|
||
<td></td>
|
||
<td></td>
|
||
<td></td>
|
||
<td class="text-right">{{ number_format($details['summary']['deliveries'], 0, ',', '.') }}</td>
|
||
@elseif (in_array($details['metric'], ['own_points', 'external_points', 'customer_abo_points', 'customer_single_order_points', 'customer_other_points', 'total_points', 'shop_1000'], true))
|
||
<td class="text-right" style="background-color:#d4edda;">{{ \App\Services\Util::formatNumber($details['summary']['own_points']) }}</td>
|
||
<td class="text-right">{{ \App\Services\Util::formatNumber($details['summary']['customer_single_order_points']) }}</td>
|
||
<td class="text-right">{{ \App\Services\Util::formatNumber($details['summary']['customer_abo_points']) }}</td>
|
||
<td class="text-right">{{ \App\Services\Util::formatNumber($details['summary']['customer_other_points']) }}</td>
|
||
<td class="text-right" style="background-color:#d4edda;">{{ \App\Services\Util::formatNumber($details['summary']['external_points']) }}</td>
|
||
<td class="text-right">{{ \App\Services\Util::formatNumber($details['summary']['total_points']) }}</td>
|
||
@elseif ($details['metric'] === 'new_partners')
|
||
<td></td>
|
||
<td></td>
|
||
<td class="text-right">{{ \App\Services\Util::formatNumber($details['summary']['customer_points'] ?? 0) }}</td>
|
||
<td class="text-right">{{ \App\Services\Util::formatNumber($details['summary']['total_points'] ?? 0) }}</td>
|
||
<td></td>
|
||
<td></td>
|
||
@else
|
||
<td></td>
|
||
<td></td>
|
||
@endif
|
||
</tr>
|
||
</tfoot>
|
||
</table>
|
||
</div>
|
||
@endif
|
||
</div>
|
||
</div>
|
||
|
||
@if ($details['rows'] !== [])
|
||
@include('components._sortable_table', [
|
||
'tableId' => 'backoffice-statistics-detail-table',
|
||
'searchId' => 'backoffice-statistics-detail-search',
|
||
])
|
||
@endif
|
||
@endsection
|