Team-Statistik = Team-Struktur (Provisionsbaum, Umschalter) und Laufstand-Fix in user_sales_volumes
K11 aus dem September-Protokoll (Tickets C1 und C2 im Entwicklungsplan), live seit 14.09.2026. C1 – Statistik rechnet wie die Provision - Standard-Baum ist der Provisionsbaum (Mitglieder wie TreeCalcBot: Mitgliedsebene, Abrechnungskonto, active_date; ausgefilterte Knoten kappen ihren Unterbaum, max. 21 Linien). Gesamte Downline bleibt per Umschalter erreichbar, Wahl in der Session. - Punkte-Definition: Provisionspunkte (TP + Shop), reine Karrierepunkte ausgewiesen statt eingerechnet, negative Monatssalden je User wie in der Provision auf 0 gekappt. - Abgeschlossene Monate nehmen die Mitglieder je Linie aus dem gespeicherten Provisionslauf (user_businesses), Snapshots je Baum-Definition (Payload-Version 3, Migration). - Struktur-Modal: Gesamt aus den Linien-Punkten mit Dezimalen statt der int-Spalte total_pp. - Messlauf statistics:compare-trees (Downline / Provisionsbaum / Struktur je VIP, Laufstand-Drift). C2 – Laufstand-Race (Provision zu niedrig bei zeitgleichen Buchungen) - Neuberechnung liest die Zeilen des Beraters sperrend (FOR UPDATE), Index (user_id, year, month). - Paid-Pfad der Payone- und Stripe-Webhooks als DB::transaction mit 3 Anlaeufen; Deadlock und Lock-Timeout aus der Rechnungserstellung werden nicht mehr geschluckt. - Sicherheitsnetz sales:repair-running-totals taeglich 02:45 vor dem Provisionslauf; abgeschlossene Monate werden nicht angefasst (Entscheid 14.09.: keine Nachzahlung fuer 06/08). Doku: Entwicklungsplan zum Protokoll, Deploy-Notiz 14.09. (inkl. Migrations-Stolperstein: Migrationen tragen Werte als Literale, nicht als Konstanten aus dem Anwendungscode). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
8f4e105c0f
commit
d57687b4e3
33 changed files with 2321 additions and 139 deletions
|
|
@ -18,6 +18,8 @@ class BackofficeStatisticsController extends Controller
|
|||
|
||||
private const SESSION_YEAR_KEY = 'backoffice_statistics_year';
|
||||
|
||||
private const SESSION_TREE_KEY = 'backoffice_statistics_tree';
|
||||
|
||||
public function __construct(
|
||||
private BackofficeDashboardService $dashboardService,
|
||||
private BackofficeDrilldownService $drilldownService,
|
||||
|
|
@ -33,8 +35,9 @@ class BackofficeStatisticsController extends Controller
|
|||
}
|
||||
|
||||
[$selectedMonth, $selectedYear] = $this->selectedPeriod($request);
|
||||
$selectedTree = $this->selectedTree($request);
|
||||
$startTime = microtime(true);
|
||||
$statistics = $this->dashboardService->overview($request->user(), $selectedMonth, $selectedYear);
|
||||
$statistics = $this->dashboardService->overview($request->user(), $selectedMonth, $selectedYear, $selectedTree);
|
||||
$performance = [
|
||||
'duration_ms' => round((microtime(true) - $startTime) * 1000, 2),
|
||||
'source' => $statistics['_meta']['source'] ?? 'live',
|
||||
|
|
@ -45,6 +48,8 @@ class BackofficeStatisticsController extends Controller
|
|||
return view('user.backoffice.statistics.index', [
|
||||
'selectedMonth' => $selectedMonth,
|
||||
'selectedYear' => $selectedYear,
|
||||
'selectedTree' => $selectedTree,
|
||||
'treeLabels' => BackofficeDashboardService::treeLabels(),
|
||||
'filterMonths' => HTMLHelper::getTransMonths(),
|
||||
'filterYears' => HTMLHelper::getYearRange(2022),
|
||||
'statistics' => $statistics,
|
||||
|
|
@ -77,6 +82,7 @@ class BackofficeStatisticsController extends Controller
|
|||
}
|
||||
|
||||
[$selectedMonth, $selectedYear] = $this->selectedPeriod($request);
|
||||
$selectedTree = $this->selectedTree($request);
|
||||
$line = (int) $request->get('line', 1);
|
||||
$metric = (string) $request->get('metric', 'consultants');
|
||||
$onlyNew = $request->boolean('only_new');
|
||||
|
|
@ -84,7 +90,8 @@ class BackofficeStatisticsController extends Controller
|
|||
return view('user.backoffice.statistics.details', [
|
||||
'selectedMonth' => $selectedMonth,
|
||||
'selectedYear' => $selectedYear,
|
||||
'details' => $this->drilldownService->details($request->user(), $line, $metric, $selectedMonth, $selectedYear, $onlyNew),
|
||||
'selectedTree' => $selectedTree,
|
||||
'details' => $this->drilldownService->details($request->user(), $line, $metric, $selectedMonth, $selectedYear, $onlyNew, $selectedTree),
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
@ -95,10 +102,11 @@ class BackofficeStatisticsController extends Controller
|
|||
}
|
||||
|
||||
[$selectedMonth, $selectedYear] = $this->selectedPeriod($request);
|
||||
$selectedTree = $this->selectedTree($request);
|
||||
$line = (int) $request->get('line', 1);
|
||||
$metric = (string) $request->get('metric', 'consultants');
|
||||
$onlyNew = $request->boolean('only_new');
|
||||
$details = $this->drilldownService->details($request->user(), $line, $metric, $selectedMonth, $selectedYear, $onlyNew);
|
||||
$details = $this->drilldownService->details($request->user(), $line, $metric, $selectedMonth, $selectedYear, $onlyNew, $selectedTree);
|
||||
$filename = sprintf(
|
||||
'backoffice-statistik-%s%s-linie-%s-%02d-%d.csv',
|
||||
$metric,
|
||||
|
|
@ -134,8 +142,9 @@ class BackofficeStatisticsController extends Controller
|
|||
}
|
||||
|
||||
[$selectedMonth, $selectedYear] = $this->selectedPeriod($request);
|
||||
$statistics = $this->dashboardService->overview($request->user(), $selectedMonth, $selectedYear);
|
||||
$filename = sprintf('backoffice-statistik-uebersicht-%02d-%d.csv', $selectedMonth, $selectedYear);
|
||||
$selectedTree = $this->selectedTree($request);
|
||||
$statistics = $this->dashboardService->overview($request->user(), $selectedMonth, $selectedYear, $selectedTree);
|
||||
$filename = sprintf('backoffice-statistik-uebersicht-%s-%02d-%d.csv', $selectedTree, $selectedMonth, $selectedYear);
|
||||
|
||||
return response()->streamDownload(function () use ($statistics): void {
|
||||
$output = fopen('php://output', 'w');
|
||||
|
|
@ -172,6 +181,22 @@ class BackofficeStatisticsController extends Controller
|
|||
return [$selectedMonth, $selectedYear];
|
||||
}
|
||||
|
||||
/**
|
||||
* Baum-Definition (Provisionsbaum / gesamte Downline) — wie Monat und Jahr in
|
||||
* der Session gemerkt, damit Detaillisten und Exporte dieselbe Sicht nutzen wie
|
||||
* die Uebersicht, aus der sie aufgerufen wurden.
|
||||
*/
|
||||
private function selectedTree(Request $request): string
|
||||
{
|
||||
$tree = BackofficeDashboardService::normalizeTree(
|
||||
(string) $request->get('tree', session(self::SESSION_TREE_KEY, BackofficeDashboardService::TREE_COMMISSION))
|
||||
);
|
||||
|
||||
session([self::SESSION_TREE_KEY => $tree]);
|
||||
|
||||
return $tree;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue