User Statistik
This commit is contained in:
parent
70240d2b6a
commit
53bdba33cd
24 changed files with 2633 additions and 9 deletions
279
app/Http/Controllers/User/BackofficeStatisticsController.php
Normal file
279
app/Http/Controllers/User/BackofficeStatisticsController.php
Normal file
|
|
@ -0,0 +1,279 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\User;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Services\Backoffice\BackofficeDashboardService;
|
||||
use App\Services\Backoffice\BackofficeDrilldownService;
|
||||
use App\Services\HTMLHelper;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\View\View;
|
||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||
|
||||
class BackofficeStatisticsController extends Controller
|
||||
{
|
||||
private const SESSION_MONTH_KEY = 'backoffice_statistics_month';
|
||||
|
||||
private const SESSION_YEAR_KEY = 'backoffice_statistics_year';
|
||||
|
||||
public function __construct(
|
||||
private BackofficeDashboardService $dashboardService,
|
||||
private BackofficeDrilldownService $drilldownService
|
||||
) {
|
||||
$this->middleware('active.account');
|
||||
}
|
||||
|
||||
public function index(Request $request): View
|
||||
{
|
||||
if (! $request->user()?->isVIP()) {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
[$selectedMonth, $selectedYear] = $this->selectedPeriod($request);
|
||||
$startTime = microtime(true);
|
||||
$statistics = $this->dashboardService->overview($request->user(), $selectedMonth, $selectedYear);
|
||||
$performance = [
|
||||
'duration_ms' => round((microtime(true) - $startTime) * 1000, 2),
|
||||
'source_label' => $statistics['_meta']['source_label'] ?? 'Live',
|
||||
'calculated_at' => $statistics['_meta']['calculated_at'] ?? null,
|
||||
];
|
||||
|
||||
return view('user.backoffice.statistics.index', [
|
||||
'selectedMonth' => $selectedMonth,
|
||||
'selectedYear' => $selectedYear,
|
||||
'filterMonths' => HTMLHelper::getTransMonths(),
|
||||
'filterYears' => HTMLHelper::getYearRange(2022),
|
||||
'statistics' => $statistics,
|
||||
'performance' => $performance,
|
||||
]);
|
||||
}
|
||||
|
||||
public function details(Request $request): View
|
||||
{
|
||||
if (! $request->user()?->isVIP()) {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
[$selectedMonth, $selectedYear] = $this->selectedPeriod($request);
|
||||
$line = (int) $request->get('line', 1);
|
||||
$metric = (string) $request->get('metric', 'consultants');
|
||||
|
||||
return view('user.backoffice.statistics.details', [
|
||||
'selectedMonth' => $selectedMonth,
|
||||
'selectedYear' => $selectedYear,
|
||||
'details' => $this->drilldownService->details($request->user(), $line, $metric, $selectedMonth, $selectedYear),
|
||||
]);
|
||||
}
|
||||
|
||||
public function export(Request $request): StreamedResponse
|
||||
{
|
||||
if (! $request->user()?->isVIP()) {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
[$selectedMonth, $selectedYear] = $this->selectedPeriod($request);
|
||||
$line = (int) $request->get('line', 1);
|
||||
$metric = (string) $request->get('metric', 'consultants');
|
||||
$details = $this->drilldownService->details($request->user(), $line, $metric, $selectedMonth, $selectedYear);
|
||||
$filename = sprintf(
|
||||
'backoffice-statistik-%s-linie-%s-%02d-%d.csv',
|
||||
$metric,
|
||||
$line === 0 ? 'alle' : $line,
|
||||
$selectedMonth,
|
||||
$selectedYear
|
||||
);
|
||||
|
||||
return response()->streamDownload(function () use ($details): void {
|
||||
$output = fopen('php://output', 'w');
|
||||
|
||||
fwrite($output, "\xEF\xBB\xBF");
|
||||
fputcsv($output, $this->csvHeaders($details['metric']), ';');
|
||||
|
||||
foreach ($details['rows'] as $row) {
|
||||
fputcsv($output, $this->csvRow($details['metric'], $row), ';');
|
||||
}
|
||||
|
||||
fputcsv($output, []);
|
||||
fputcsv($output, $this->csvSummaryRow($details), ';');
|
||||
|
||||
fclose($output);
|
||||
}, $filename, [
|
||||
'Content-Type' => 'text/csv; charset=UTF-8',
|
||||
]);
|
||||
}
|
||||
|
||||
public function overviewExport(Request $request): StreamedResponse
|
||||
{
|
||||
if (! $request->user()?->isVIP()) {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
[$selectedMonth, $selectedYear] = $this->selectedPeriod($request);
|
||||
$statistics = $this->dashboardService->overview($request->user(), $selectedMonth, $selectedYear);
|
||||
$filename = sprintf('backoffice-statistik-uebersicht-%02d-%d.csv', $selectedMonth, $selectedYear);
|
||||
|
||||
return response()->streamDownload(function () use ($statistics): void {
|
||||
$output = fopen('php://output', 'w');
|
||||
|
||||
fwrite($output, "\xEF\xBB\xBF");
|
||||
fputcsv($output, $this->overviewCsvHeaders(), ';');
|
||||
|
||||
foreach ($statistics['lines'] as $line) {
|
||||
fputcsv($output, $this->overviewCsvRow($line), ';');
|
||||
}
|
||||
|
||||
fputcsv($output, []);
|
||||
fputcsv($output, $this->overviewCsvRow($statistics['totals']), ';');
|
||||
|
||||
fclose($output);
|
||||
}, $filename, [
|
||||
'Content-Type' => 'text/csv; charset=UTF-8',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{0: int, 1: int}
|
||||
*/
|
||||
private function selectedPeriod(Request $request): array
|
||||
{
|
||||
$selectedMonth = max(1, min(12, (int) $request->get('month', session(self::SESSION_MONTH_KEY, now()->month))));
|
||||
$selectedYear = (int) $request->get('year', session(self::SESSION_YEAR_KEY, now()->year));
|
||||
|
||||
session([
|
||||
self::SESSION_MONTH_KEY => $selectedMonth,
|
||||
self::SESSION_YEAR_KEY => $selectedYear,
|
||||
]);
|
||||
|
||||
return [$selectedMonth, $selectedYear];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
private function overviewCsvHeaders(): array
|
||||
{
|
||||
return [
|
||||
'Linie',
|
||||
'Berater',
|
||||
'Neupartner',
|
||||
'Teamabos',
|
||||
'Neue Teamabos',
|
||||
'Teamkundenabos',
|
||||
'Neue Teamkundenabos',
|
||||
'Eigenpunkte',
|
||||
'Externe Punkte',
|
||||
'Kundenabo-Punkte',
|
||||
'Einzelbestellungs-Punkte',
|
||||
'Sonstige Kundenpunkte',
|
||||
'Gesamtpunkte',
|
||||
'1000 Punkte Shop',
|
||||
'Umsatz Netto',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $row
|
||||
* @return array<int, mixed>
|
||||
*/
|
||||
private function overviewCsvRow(array $row): array
|
||||
{
|
||||
return [
|
||||
$row['label'] ?? '',
|
||||
$row['consultants'] ?? 0,
|
||||
$row['new_partners'] ?? 0,
|
||||
$row['team_partner_abos'] ?? 0,
|
||||
$row['team_partner_abos_new'] ?? 0,
|
||||
$row['team_customer_abos'] ?? 0,
|
||||
$row['team_customer_abos_new'] ?? 0,
|
||||
$row['own_points'] ?? 0,
|
||||
$row['external_points'] ?? 0,
|
||||
$row['customer_abo_points'] ?? 0,
|
||||
$row['customer_single_order_points'] ?? 0,
|
||||
$row['customer_other_points'] ?? 0,
|
||||
$row['total_points'] ?? 0,
|
||||
$row['shop_1000'] ?? 0,
|
||||
$row['turnover_net'] ?? 0,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
private function csvHeaders(string $metric): array
|
||||
{
|
||||
if (in_array($metric, ['team_partner_abos', 'team_customer_abos'], true)) {
|
||||
return ['Name', 'E-Mail', 'Karriere-Level', 'Berater', 'Abo-Punkte', 'Status', 'Status-Grund', 'Besteht seit', 'Naechste Ausfuehrung', 'Lieferungen'];
|
||||
}
|
||||
|
||||
if (in_array($metric, ['own_points', 'external_points', 'customer_abo_points', 'customer_single_order_points', 'customer_other_points', 'total_points', 'shop_1000'], true)) {
|
||||
return ['Name', 'E-Mail', 'Karriere-Level', 'Eigenpunkte', 'Externe Punkte', 'Kundenabo-Punkte', 'Einzelbestellungs-Punkte', 'Sonstige Kundenpunkte', 'Gesamtpunkte'];
|
||||
}
|
||||
|
||||
return ['Name', 'E-Mail', 'Karriere-Level', 'Aktiv seit', 'Account gueltig bis', 'Account Status'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $row
|
||||
* @return array<int, mixed>
|
||||
*/
|
||||
private function csvRow(string $metric, array $row): array
|
||||
{
|
||||
if (in_array($metric, ['team_partner_abos', 'team_customer_abos'], true)) {
|
||||
return [
|
||||
$row['name'] ?? '',
|
||||
$row['email'] ?? '',
|
||||
$row['career_level'] ?? '',
|
||||
$row['consultant_name'] ?? $row['name'] ?? '',
|
||||
$row['points'] ?? 0,
|
||||
$row['status_label'] ?? '',
|
||||
$row['status_reason'] ?? '',
|
||||
$row['start_date'] ?? '',
|
||||
$row['next_date'] ?? '',
|
||||
$row['deliveries'] ?? 0,
|
||||
];
|
||||
}
|
||||
|
||||
if (in_array($metric, ['own_points', 'external_points', 'customer_abo_points', 'customer_single_order_points', 'customer_other_points', 'total_points', 'shop_1000'], true)) {
|
||||
return [
|
||||
$row['name'] ?? '',
|
||||
$row['email'] ?? '',
|
||||
$row['career_level'] ?? '',
|
||||
$row['own_points'] ?? 0,
|
||||
$row['external_points'] ?? 0,
|
||||
$row['customer_abo_points'] ?? 0,
|
||||
$row['customer_single_order_points'] ?? 0,
|
||||
$row['customer_other_points'] ?? 0,
|
||||
$row['total_points'] ?? 0,
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
$row['name'] ?? '',
|
||||
$row['email'] ?? '',
|
||||
$row['career_level'] ?? '',
|
||||
$row['active_date'] ?? '',
|
||||
$row['payment_account'] ?? '',
|
||||
$row['account_status'] ?? '',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $details
|
||||
* @return array<int, mixed>
|
||||
*/
|
||||
private function csvSummaryRow(array $details): array
|
||||
{
|
||||
$metric = $details['metric'];
|
||||
$summary = $details['summary'];
|
||||
|
||||
if (in_array($metric, ['team_partner_abos', 'team_customer_abos'], true)) {
|
||||
return ['Summe', $summary['count'].' Eintraege', '', '', $summary['points'], '', '', '', '', $summary['deliveries']];
|
||||
}
|
||||
|
||||
if (in_array($metric, ['own_points', 'external_points', 'customer_abo_points', 'customer_single_order_points', 'customer_other_points', 'total_points', 'shop_1000'], true)) {
|
||||
return ['Summe', $summary['count'].' Eintraege', '', $summary['own_points'], $summary['external_points'], $summary['customer_abo_points'], $summary['customer_single_order_points'], $summary['customer_other_points'], $summary['total_points']];
|
||||
}
|
||||
|
||||
return ['Summe', $summary['count'].' Eintraege', '', '', '', ''];
|
||||
}
|
||||
}
|
||||
|
|
@ -87,6 +87,7 @@ class CheckoutController extends Controller
|
|||
'is_for' => $is_for,
|
||||
'is_abo' => $is_abo,
|
||||
'abo_interval' => $abo_interval,
|
||||
'customer_order_source_options' => ShoppingOrder::customerOrderSourceOptions(),
|
||||
'shopping_data' => $shopping_data,
|
||||
'user_shop' => Util::getUserShop(),
|
||||
'shopping_user' => $shopping_user,
|
||||
|
|
@ -225,6 +226,11 @@ class CheckoutController extends Controller
|
|||
'accepted_data_checkbox' => 'accepted',
|
||||
];
|
||||
|
||||
if (Request::get('is_from') === 'shopping') {
|
||||
$rules['customer_order_source'] = 'required|in:'.implode(',', array_keys(ShoppingOrder::customerOrderSourceOptions()));
|
||||
$rules['customer_order_source_comment'] = 'nullable|string|max:500';
|
||||
}
|
||||
|
||||
if (Request::get('same_as_billing')) {
|
||||
$rules = array_merge($rules, [
|
||||
'shipping_firstname' => 'required',
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue