User Statistik
This commit is contained in:
parent
70240d2b6a
commit
53bdba33cd
24 changed files with 2633 additions and 9 deletions
|
|
@ -47,6 +47,7 @@ return [
|
|||
'settings' => 'Einstellungen',
|
||||
'shipping_costs' => 'Versandkosten',
|
||||
'start_site' => 'Startseite Shop',
|
||||
'statistics' => 'Statistik',
|
||||
'structure' => 'Struktur',
|
||||
'system_settings' => 'System-E.',
|
||||
'translate' => 'Übersetzungen',
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ return [
|
|||
'settings' => 'settings',
|
||||
'shipping_costs' => 'shipping',
|
||||
'start_site' => 'home page',
|
||||
'statistics' => 'Statistics',
|
||||
'structure' => 'structure',
|
||||
'system_settings' => 'system E.',
|
||||
'tags' => 'Tags',
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ return [
|
|||
'settings' => 'ajustes',
|
||||
'shipping_costs' => 'envío',
|
||||
'start_site' => 'pagina de inicio',
|
||||
'statistics' => 'Estadísticas',
|
||||
'structure' => 'estructura',
|
||||
'system_settings' => 'sistema E.',
|
||||
'tags' => 'Etiquetas',
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ return [
|
|||
'settings' => 'Paramètres',
|
||||
'shipping_costs' => 'Frais de livraison',
|
||||
'start_site' => 'Page d’accueil boutique',
|
||||
'statistics' => 'Statistiques',
|
||||
'structure' => 'Structure',
|
||||
'system_settings' => 'Param. système',
|
||||
'translate' => 'Traductions',
|
||||
|
|
|
|||
|
|
@ -185,6 +185,15 @@
|
|||
<div class="text-muted small">{{ __('order.points_total') }}</div>
|
||||
{{ $shopping_order->getFormattedPoints() }}
|
||||
</div>
|
||||
@if ((int) $shopping_order->payment_for === 6 && $shopping_order->customer_order_source)
|
||||
<div class="col-md-3 mb-3">
|
||||
<div class="text-muted small">Herkunft</div>
|
||||
{{ $shopping_order->getCustomerOrderSourceLabel() }}
|
||||
@if ($shopping_order->customer_order_source_comment)
|
||||
<div class="small text-muted mt-1">{{ $shopping_order->customer_order_source_comment }}</div>
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
<hr class="m-0">
|
||||
|
|
|
|||
|
|
@ -55,6 +55,17 @@
|
|||
<div>{{ __('navigation.news_archive') }}</div>
|
||||
</a>
|
||||
</li>
|
||||
@if (Auth::user()->isVIP())
|
||||
<li class="sidenav-item{{ Request::is('user/backoffice/statistics*') ? ' active' : '' }}">
|
||||
<a href="{{ route('user_backoffice_statistics') }}" class="sidenav-link"><i
|
||||
class="sidenav-icon ion ion-ios-stats"></i>
|
||||
<div>{{ __('navigation.statistics') }}</div>
|
||||
<div class="pl-1 ml-auto">
|
||||
<div class="badge badge-secondary">VIP</div>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
@endif
|
||||
<li class="sidenav-item @if (Request::is('user/team/*')) open @endif">
|
||||
<a href="javascript:void(0)" class="sidenav-link sidenav-toggle">
|
||||
<i class="sidenav-icon ion ion-ios-people"></i>
|
||||
|
|
|
|||
279
resources/views/user/backoffice/statistics/details.blade.php
Normal file
279
resources/views/user/backoffice/statistics/details.blade.php
Normal file
|
|
@ -0,0 +1,279 @@
|
|||
@extends('layouts.layout-2')
|
||||
|
||||
@section('content')
|
||||
<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>
|
||||
</div>
|
||||
<div>
|
||||
<a href="{{ route('user_backoffice_statistics_export', [
|
||||
'line' => $details['line'],
|
||||
'metric' => $details['metric'],
|
||||
'month' => $selectedMonth,
|
||||
'year' => $selectedYear,
|
||||
]) }}"
|
||||
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]) }}"
|
||||
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>
|
||||
</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 (in_array($details['metric'], ['team_partner_abos', 'team_customer_abos'], true))
|
||||
<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"><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">Externe 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">Kundenabo-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">Einzelbestellungs-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 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>
|
||||
@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 (in_array($details['metric'], ['team_partner_abos', 'team_customer_abos'], true))
|
||||
<td>{{ $row['consultant_name'] ?? $row['name'] }}</td>
|
||||
<td class="text-right">{{ \App\Services\Util::formatNumber($row['points']) }}</td>
|
||||
<td>
|
||||
{!! $row['status_badge'] ?? '' !!}
|
||||
@if (! empty($row['status_reason']))
|
||||
<div class="small text-muted mt-1">{{ $row['status_reason'] }}</div>
|
||||
@endif
|
||||
</td>
|
||||
<td>
|
||||
{{ $row['start_date'] ?? '-' }}
|
||||
@if (! empty($row['is_new_this_month']))
|
||||
<span class="badge badge-success ml-1">Neu</span>
|
||||
@endif
|
||||
</td>
|
||||
<td>{{ $row['next_date'] ?? '-' }}</td>
|
||||
<td class="text-right">{{ 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">{{ \App\Services\Util::formatNumber($row['own_points']) }}</td>
|
||||
<td class="text-right">{{ \App\Services\Util::formatNumber($row['external_points']) }}</td>
|
||||
<td class="text-right">{{ \App\Services\Util::formatNumber($row['customer_abo_points']) }}</td>
|
||||
<td class="text-right">{{ \App\Services\Util::formatNumber($row['customer_single_order_points']) }}</td>
|
||||
<td class="text-right">{{ \App\Services\Util::formatNumber($row['customer_other_points']) }}</td>
|
||||
<td class="text-right font-weight-bold">{{ \App\Services\Util::formatNumber($row['total_points']) }}</td>
|
||||
@else
|
||||
<td>{{ $row['active_date'] ?? '-' }}</td>
|
||||
<td>
|
||||
{{ $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 (in_array($details['metric'], ['team_partner_abos', 'team_customer_abos'], true))
|
||||
<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">{{ \App\Services\Util::formatNumber($details['summary']['own_points']) }}</td>
|
||||
<td class="text-right">{{ \App\Services\Util::formatNumber($details['summary']['external_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_single_order_points']) }}</td>
|
||||
<td class="text-right">{{ \App\Services\Util::formatNumber($details['summary']['customer_other_points']) }}</td>
|
||||
<td class="text-right">{{ \App\Services\Util::formatNumber($details['summary']['total_points']) }}</td>
|
||||
@else
|
||||
<td></td>
|
||||
<td></td>
|
||||
@endif
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if ($details['rows'] !== [])
|
||||
<style>
|
||||
#backoffice-statistics-detail-table {
|
||||
min-width: 980px;
|
||||
}
|
||||
|
||||
#backoffice-statistics-detail-table th,
|
||||
#backoffice-statistics-detail-table td {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
#backoffice-statistics-detail-table th[data-sortable="true"] {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
#backoffice-statistics-detail-table .sortable-label {
|
||||
align-items: center;
|
||||
display: inline-flex;
|
||||
gap: .25rem;
|
||||
white-space: nowrap;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#backoffice-statistics-detail-table .sort-icon {
|
||||
color: #adb5bd;
|
||||
flex: 0 0 auto;
|
||||
font-size: .875rem;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
#backoffice-statistics-detail-table th[data-sort-direction="asc"] .sort-icon,
|
||||
#backoffice-statistics-detail-table th[data-sort-direction="desc"] .sort-icon {
|
||||
color: #4e73df;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$('#backoffice-statistics-detail-search').on('keyup search', function() {
|
||||
var search = $(this).val().toLowerCase();
|
||||
|
||||
$('#backoffice-statistics-detail-table tbody tr').each(function() {
|
||||
var rowText = $(this).text().toLowerCase();
|
||||
$(this).toggle(rowText.indexOf(search) !== -1);
|
||||
});
|
||||
});
|
||||
|
||||
$('#backoffice-statistics-detail-table th[data-sortable="true"]').css('cursor', 'pointer').on('click',
|
||||
function() {
|
||||
var $header = $(this);
|
||||
var columnIndex = $header.index();
|
||||
var sortType = $header.data('sort-type') || 'text';
|
||||
var direction = $header.data('sort-direction') === 'asc' ? 'desc' : 'asc';
|
||||
var rows = $('#backoffice-statistics-detail-table tbody tr').get();
|
||||
|
||||
rows.sort(function(a, b) {
|
||||
var aValue = getSortValue($(a).children('td').eq(columnIndex).text(), sortType);
|
||||
var bValue = getSortValue($(b).children('td').eq(columnIndex).text(), sortType);
|
||||
|
||||
if (aValue < bValue) {
|
||||
return direction === 'asc' ? -1 : 1;
|
||||
}
|
||||
|
||||
if (aValue > bValue) {
|
||||
return direction === 'asc' ? 1 : -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
});
|
||||
|
||||
$('#backoffice-statistics-detail-table th[data-sortable="true"]')
|
||||
.removeData('sort-direction')
|
||||
.removeAttr('data-sort-direction');
|
||||
$header.data('sort-direction', direction).attr('data-sort-direction', direction);
|
||||
$.each(rows, function(index, row) {
|
||||
$('#backoffice-statistics-detail-table tbody').append(row);
|
||||
});
|
||||
});
|
||||
|
||||
function getSortValue(value, sortType) {
|
||||
value = $.trim(value);
|
||||
|
||||
if (sortType === 'number') {
|
||||
return parseFloat(value.replace(/\./g, '').replace(',', '.').replace(/[^\d.-]/g, '')) || 0;
|
||||
}
|
||||
|
||||
if (sortType === 'date') {
|
||||
var parts = value.match(/(\d{2})\.(\d{2})\.(\d{4})/);
|
||||
|
||||
if (!parts) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return new Date(parts[3], parts[2] - 1, parts[1]).getTime();
|
||||
}
|
||||
|
||||
return value.toLowerCase();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@endif
|
||||
@endsection
|
||||
237
resources/views/user/backoffice/statistics/index.blade.php
Normal file
237
resources/views/user/backoffice/statistics/index.blade.php
Normal file
|
|
@ -0,0 +1,237 @@
|
|||
@extends('layouts.layout-2')
|
||||
|
||||
@section('content')
|
||||
<h4 class="font-weight-bold py-2 mb-2 d-flex justify-content-between align-items-center w-100">
|
||||
<div>
|
||||
{{ __('navigation.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.statistics') }} / Backoffice MVP</h5>
|
||||
<p class="text-muted mb-md-0">
|
||||
Linienbasierte Übersicht für alle vorhandenen Team-Linien. Klickbare Zahlen führen direkt in die
|
||||
passenden Namen- und Detaillisten.
|
||||
</p>
|
||||
@if (! empty($performance))
|
||||
<div class="small text-muted mt-2">
|
||||
Datenquelle:
|
||||
<span class="badge badge-outline-default">{{ $performance['source_label'] }}</span>
|
||||
<span class="ml-2">Berechnet in {{ number_format($performance['duration_ms'], 2, ',', '.') }} ms</span>
|
||||
@if (! empty($performance['calculated_at']))
|
||||
<span class="ml-2">Snapshot vom {{ $performance['calculated_at'] }}</span>
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
<div class="col-md-4 mt-3 mt-md-0">
|
||||
<form method="GET" action="{{ route('user_backoffice_statistics') }}"
|
||||
class="form-inline justify-content-md-end">
|
||||
<a href="{{ route('user_backoffice_statistics_overview_export', ['month' => $selectedMonth, 'year' => $selectedYear]) }}"
|
||||
class="btn btn-sm btn-outline-secondary mr-2">
|
||||
<span class="ion ion-md-download mr-1"></span> CSV
|
||||
</a>
|
||||
<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>
|
||||
|
||||
@php
|
||||
$clickableMetrics = [
|
||||
'consultants',
|
||||
'new_partners',
|
||||
'team_partner_abos',
|
||||
'team_customer_abos',
|
||||
'own_points',
|
||||
'external_points',
|
||||
'customer_abo_points',
|
||||
'customer_single_order_points',
|
||||
'customer_other_points',
|
||||
'total_points',
|
||||
'shop_1000',
|
||||
];
|
||||
|
||||
$formatValue = function ($value, string $metric): string {
|
||||
if (
|
||||
in_array(
|
||||
$metric,
|
||||
[
|
||||
'own_points',
|
||||
'external_points',
|
||||
'customer_abo_points',
|
||||
'customer_single_order_points',
|
||||
'customer_other_points',
|
||||
'total_points',
|
||||
],
|
||||
true,
|
||||
)
|
||||
) {
|
||||
return \App\Services\Util::formatNumber($value);
|
||||
}
|
||||
|
||||
return number_format((float) $value, 0, ',', '.');
|
||||
};
|
||||
|
||||
$newAboMetric = function (array $row, string $metric): ?string {
|
||||
return match ($metric) {
|
||||
'team_partner_abos' => 'team_partner_abos_new',
|
||||
'team_customer_abos' => 'team_customer_abos_new',
|
||||
default => null,
|
||||
};
|
||||
};
|
||||
@endphp
|
||||
|
||||
<div class="card mb-4">
|
||||
<div class="card-body p-0">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover mb-0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Linie</th>
|
||||
<th class="text-right">Berater</th>
|
||||
<th class="text-right">Neupartner</th>
|
||||
<th class="text-right">Teamabos</th>
|
||||
<th class="text-right">Teamkundenabos</th>
|
||||
<th class="text-right">Eigenpunkte</th>
|
||||
<th class="text-right">Externe Punkte</th>
|
||||
<th class="text-right">Kundenabo-Punkte</th>
|
||||
<th class="text-right">Einzelbestellungs-Punkte</th>
|
||||
<th class="text-right">Sonstige Kundenpunkte</th>
|
||||
<th class="text-right">Gesamtpunkte</th>
|
||||
<th class="text-right">1000 Punkte Shop</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach ($statistics['lines'] as $line)
|
||||
<tr>
|
||||
<td class="font-weight-semibold">{{ $line['label'] }}</td>
|
||||
@foreach ($clickableMetrics as $metric)
|
||||
<td class="text-right">
|
||||
@if ($line[$metric] > 0)
|
||||
<a href="{{ route('user_backoffice_statistics_details', [
|
||||
'line' => $line['line'],
|
||||
'metric' => $metric,
|
||||
'month' => $selectedMonth,
|
||||
'year' => $selectedYear,
|
||||
]) }}"
|
||||
class="badge badge-pill badge-outline-default backoffice-statistics-click-badge">
|
||||
{{ $formatValue($line[$metric], $metric) }}
|
||||
</a>
|
||||
@php $newMetric = $newAboMetric($line, $metric); @endphp
|
||||
@if ($newMetric && $line[$newMetric] > 0)
|
||||
<span
|
||||
class="badge badge-pill badge-success ml-1">+{{ number_format($line[$newMetric], 0, ',', '.') }}</span>
|
||||
@endif
|
||||
@else
|
||||
<span
|
||||
class="badge badge-pill badge-light backoffice-statistics-empty-badge">0</span>
|
||||
@endif
|
||||
</td>
|
||||
@endforeach
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr class="font-weight-bold bg-light">
|
||||
<td>{{ $statistics['totals']['label'] }}</td>
|
||||
@foreach ($clickableMetrics as $metric)
|
||||
<td class="text-right">
|
||||
@if ($statistics['totals'][$metric] > 0)
|
||||
<a href="{{ route('user_backoffice_statistics_details', [
|
||||
'line' => 0,
|
||||
'metric' => $metric,
|
||||
'month' => $selectedMonth,
|
||||
'year' => $selectedYear,
|
||||
]) }}"
|
||||
class="badge badge-pill badge-secondary backoffice-statistics-click-badge">
|
||||
{{ $formatValue($statistics['totals'][$metric], $metric) }}
|
||||
</a>
|
||||
@php $newMetric = $newAboMetric($statistics['totals'], $metric); @endphp
|
||||
@if ($newMetric && $statistics['totals'][$newMetric] > 0)
|
||||
<span
|
||||
class="badge badge-pill badge-success ml-1">+{{ number_format($statistics['totals'][$newMetric], 0, ',', '.') }}</span>
|
||||
@endif
|
||||
@else
|
||||
<span
|
||||
class="badge badge-pill badge-light backoffice-statistics-empty-badge">0</span>
|
||||
@endif
|
||||
</td>
|
||||
@endforeach
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-4">
|
||||
<div class="card h-100">
|
||||
<div class="card-body">
|
||||
<h5 class="mb-2">Begriffe</h5>
|
||||
<p class="text-muted mb-2">
|
||||
Teamabos sind Berater-/Eigenabos im Team. Teamkundenabos sind Kundenabos, die einem Berater
|
||||
aus der jeweiligen Linie zugeordnet sind.
|
||||
</p>
|
||||
<p class="text-muted mb-0">
|
||||
Externe Punkte kommen aktuell aus `month_shop_points`, Eigenpunkte aus `month_KP_points`.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6 mb-4">
|
||||
<div class="card h-100">
|
||||
<div class="card-body">
|
||||
<h5 class="mb-2">Nächster Ausbau</h5>
|
||||
<p class="text-muted mb-0">
|
||||
Die Detailansichten liefern bereits Namen und Basisdaten. Im nächsten Schritt werden Abo-Punkte
|
||||
und Umsatzarten noch feiner nach Abo, Einzelbestellung und Shop getrennt.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.backoffice-statistics-click-badge,
|
||||
.backoffice-statistics-empty-badge {
|
||||
display: inline-block;
|
||||
font-size: .85rem;
|
||||
line-height: 1.35;
|
||||
min-width: 2.35rem;
|
||||
padding: .35rem .55rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.backoffice-statistics-click-badge {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.backoffice-statistics-click-badge:hover,
|
||||
.backoffice-statistics-click-badge:focus {
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
@endsection
|
||||
|
|
@ -550,6 +550,31 @@
|
|||
<span class="info-small">{{ __('customer.language_hint') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-3">
|
||||
<div class="col-md-12 col-sm-12">
|
||||
<div class="form-group {{($errors->has('customer_order_source') ? 'error' : '')}}">
|
||||
<label class="mt-0 fs-14 fw-400" for="customer_order_source">Wie bist du auf uns aufmerksam geworden? *</label>
|
||||
<select id="customer_order_source" name="customer_order_source" class="form-control custom-select">
|
||||
<option value="">Bitte auswählen</option>
|
||||
@foreach($customer_order_source_options as $sourceKey => $sourceLabel)
|
||||
<option value="{{ $sourceKey }}" {{ old('customer_order_source') === $sourceKey ? 'selected' : '' }}>{{ $sourceLabel }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
@if ($errors->has('customer_order_source'))
|
||||
<label for="customer_order_source" class="error text-danger small" style="display: block;">{{ $errors->first('customer_order_source') }}</label>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-12 col-sm-12">
|
||||
<div class="form-group {{($errors->has('customer_order_source_comment') ? 'error' : '')}}">
|
||||
<label class="mt-0 fs-14 fw-400" for="customer_order_source_comment">Ergänzung zur Herkunft (optional)</label>
|
||||
{!! Form::textarea('customer_order_source_comment', old('customer_order_source_comment'), ['class' => 'form-control '.($errors->has('customer_order_source_comment') ? 'error' : ''), 'id'=>'customer_order_source_comment', 'rows' => 3, 'maxlength' => 500]) !!}
|
||||
@if ($errors->has('customer_order_source_comment'))
|
||||
<label for="customer_order_source_comment" class="error text-danger small" style="display: block;">{{ $errors->first('customer_order_source_comment') }}</label>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@else
|
||||
<div class="is_from_user">
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue