Backoffice-Statistik vereinfacht & Dashboard-Monatsstatistik konsolidiert
- Statistik-Uebersicht: Tabelle auf Linie/Berater/Umsatz(Punkte)/Teamabos/ Teamkundenabos reduziert; Neupartner als grünes "+N"-Badge in der Berater-Spalte; 1000-Punkte-Shop & Neupartner als klickbare KPI-Cards (Augen-Icon/Liste anzeigen) - Teamkundenabos-Drilldown pro Teampartner gruppiert (Anzahl + Volumenpunkte gesamt, aufklappbar je Abo), CSV-Export angepasst - Home: fehlerhafte Monatsstatistik-Card (inkonsistente aktiv-Definition, kein Monatsbezug, schwere Live-Logik im Blade) mit der Abo-KPI-Card zusammengefuehrt; Logik nach HomeController::buildMonthlyStats() ausgelagert, konsistent ueber TeamAboOverviewService/BackofficeDashboardService - Team-Payline fuer laufenden Monat live berechnet und 6h gecacht (Snapshot) - Kacheln in Cluster (Umsatz/Neupartner/Abos) gruppiert - Services: teamKpis() um *_new ergaenzt, personalAboKpis() & newPartnersCount() neu - i18n (de/en/es/fr), Tests ergaenzt/aktualisiert Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
0d67b02021
commit
27b4ad3eb5
20 changed files with 631 additions and 323 deletions
|
|
@ -47,12 +47,13 @@ class BackofficeDrilldownService
|
|||
|
||||
/**
|
||||
* @param array<int, array<string, mixed>> $rows
|
||||
* @return array{count: int, points: float, own_points: float, external_points: float, customer_abo_points: float, customer_single_order_points: float, customer_other_points: float, total_points: float, deliveries: int}
|
||||
* @return array{count: int, abo_count: int, points: float, own_points: float, external_points: float, customer_abo_points: float, customer_single_order_points: float, customer_other_points: float, total_points: float, deliveries: int}
|
||||
*/
|
||||
private function summary(array $rows): array
|
||||
{
|
||||
return [
|
||||
'count' => count($rows),
|
||||
'abo_count' => (int) collect($rows)->sum('abo_count'),
|
||||
'points' => (float) collect($rows)->sum('points'),
|
||||
'own_points' => (float) collect($rows)->sum('own_points'),
|
||||
'external_points' => (float) collect($rows)->sum('external_points'),
|
||||
|
|
@ -157,37 +158,47 @@ class BackofficeDrilldownService
|
|||
}
|
||||
|
||||
/**
|
||||
* Teamkundenabos pro Teampartner (member_id) gruppiert: je Teampartner die
|
||||
* Anzahl der Kundenabos, die Gesamt-Volumenpunkte sowie die einzelnen Abos
|
||||
* mit Punkten je Abo. Kundennamen bleiben aus Datenschutzgründen außen vor.
|
||||
*
|
||||
* @param int[] $userIds
|
||||
* @return array<int, array<string, mixed>>
|
||||
*/
|
||||
private function customerAboRows(array $userIds, int $month, int $year): array
|
||||
{
|
||||
return $this->activeAboQuery()
|
||||
->with(['member.account', 'member.user_level', 'user.account', 'user_abo_items.product', 'user_abo_orders.shopping_order.shopping_payments.payment_transactions'])
|
||||
->with(['member.account', 'member.user_level', 'user_abo_items.product'])
|
||||
->whereIn('member_id', $userIds)
|
||||
->where('is_for', 'ot')
|
||||
->orderBy('member_id')
|
||||
->orderBy('next_date')
|
||||
->get()
|
||||
->map(fn (UserAbo $abo) => [
|
||||
'type' => 'customer_abo',
|
||||
'abo_id' => $abo->id,
|
||||
'user_id' => $abo->user_id,
|
||||
'member_id' => $abo->member_id,
|
||||
'name' => $abo->user ? $this->userName($abo->user) : ($abo->email ?: '#'.$abo->user_id),
|
||||
'email' => $abo->email ?: $abo->user?->email,
|
||||
'consultant_name' => $abo->member ? $this->userName($abo->member) : '#'.$abo->member_id,
|
||||
'career_level' => $abo->member ? $this->careerLevel($abo->member) : '-',
|
||||
'points' => $abo->getTotalPoints(),
|
||||
'start_date' => $this->formatDate($abo->getRawOriginal('start_date')),
|
||||
'is_new_this_month' => $this->isAboNewInMonth($abo, $month, $year),
|
||||
'next_date' => $this->formatDate($abo->next_date),
|
||||
'deliveries' => $abo->getCountOrders(),
|
||||
'status' => $abo->status,
|
||||
'status_label' => $abo->getStatusType(),
|
||||
'status_badge' => $abo->getStatusFormated(),
|
||||
'status_reason' => $this->aboStatusReason($abo),
|
||||
])
|
||||
->groupBy(fn (UserAbo $abo) => (int) $abo->member_id)
|
||||
->map(function ($abos) use ($month, $year) {
|
||||
$consultant = $abos->first()->member;
|
||||
$memberId = (int) $abos->first()->member_id;
|
||||
|
||||
$aboItems = $abos->map(fn (UserAbo $abo) => [
|
||||
'abo_id' => $abo->id,
|
||||
'points' => (float) $abo->getTotalPoints(),
|
||||
'start_date' => $this->formatDate($abo->getRawOriginal('start_date')),
|
||||
'next_date' => $this->formatDate($abo->next_date),
|
||||
'is_new_this_month' => $this->isAboNewInMonth($abo, $month, $year),
|
||||
])->values()->all();
|
||||
|
||||
return [
|
||||
'type' => 'customer_abo_group',
|
||||
'consultant_id' => $memberId,
|
||||
'name' => $consultant ? $this->userName($consultant) : '#'.$memberId,
|
||||
'email' => $consultant?->email,
|
||||
'career_level' => $consultant ? $this->careerLevel($consultant) : '-',
|
||||
'abo_count' => $abos->count(),
|
||||
'points' => (float) $abos->sum(fn (UserAbo $abo) => $abo->getTotalPoints()),
|
||||
'abos' => $aboItems,
|
||||
];
|
||||
})
|
||||
->sortByDesc('points')
|
||||
->values()
|
||||
->all();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue