Backoffice-Statistik: Punkte-Fix (kumulative Snapshots) & Meine Statistik
Punkte/Umsatz korrekt aus per-Zeile points/total_net je status berechnen statt SUM der kumulativen month_*-Snapshots (zaehlte massiv mehrfach). Zentralisiert in SalesVolumePoints, genutzt von Dashboard- & Drilldown-Service. Detail-Tabelle neu gegliedert: Eigenpunkte | Shop | Abo | Sonstige | Kundenpunkte (=Summe) | Gesamt, mit gruener Hervorhebung der Basis-/Summenspalten. Neue VIP-Seite "Meine Statistik" (Untermenue neben Team-Statistik): KPI-Karten + nachvollziehbare Detailtabellen, gruppiert nach eigenen Bestellungen, Shop-Bestellungen und Abos (PersonalStatisticsService). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
9565814221
commit
7a620d66ae
14 changed files with 666 additions and 70 deletions
122
tests/Unit/Services/PersonalStatisticsServiceTest.php
Normal file
122
tests/Unit/Services/PersonalStatisticsServiceTest.php
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
<?php
|
||||
|
||||
use App\Models\UserSalesVolume;
|
||||
use App\Services\Backoffice\PersonalStatisticsService;
|
||||
use App\User;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Tests\TestCase;
|
||||
|
||||
uses(TestCase::class);
|
||||
|
||||
beforeEach(function () {
|
||||
Schema::dropIfExists('user_sales_volumes');
|
||||
Schema::dropIfExists('shopping_orders');
|
||||
Schema::dropIfExists('shopping_users');
|
||||
Schema::dropIfExists('users');
|
||||
|
||||
Schema::create('users', function ($table) {
|
||||
$table->increments('id');
|
||||
$table->string('email')->unique();
|
||||
$table->string('password');
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
});
|
||||
|
||||
Schema::create('shopping_users', function ($table) {
|
||||
$table->increments('id');
|
||||
$table->string('billing_firstname')->nullable();
|
||||
$table->string('billing_lastname')->nullable();
|
||||
$table->string('billing_email')->nullable();
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
});
|
||||
|
||||
Schema::create('shopping_orders', function ($table) {
|
||||
$table->increments('id');
|
||||
$table->unsignedInteger('shopping_user_id')->nullable();
|
||||
$table->boolean('is_abo')->default(false);
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
});
|
||||
|
||||
Schema::create('user_sales_volumes', function ($table) {
|
||||
$table->increments('id');
|
||||
$table->unsignedInteger('user_id');
|
||||
$table->unsignedInteger('shopping_order_id')->nullable();
|
||||
$table->unsignedTinyInteger('month')->nullable();
|
||||
$table->unsignedSmallInteger('year')->nullable();
|
||||
$table->decimal('points', 13, 2)->nullable();
|
||||
$table->decimal('total_net', 13, 2)->nullable();
|
||||
$table->unsignedTinyInteger('status')->nullable();
|
||||
$table->unsignedTinyInteger('status_turnover')->nullable();
|
||||
$table->string('date')->nullable();
|
||||
$table->string('info')->nullable();
|
||||
$table->string('message')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
});
|
||||
|
||||
it('gruppiert die Monatspunkte nach Eigen, Shop, Abo und Sonstige', function () {
|
||||
$user = User::forceCreate(['email' => 'me@test.test', 'password' => 'secret']);
|
||||
|
||||
$customer = DB::table('shopping_users')->insertGetId([
|
||||
'billing_firstname' => 'Erika', 'billing_lastname' => 'Musterfrau', 'billing_email' => 'erika@test.test',
|
||||
'created_at' => now(), 'updated_at' => now(),
|
||||
]);
|
||||
|
||||
$shopOrderId = DB::table('shopping_orders')->insertGetId([
|
||||
'shopping_user_id' => $customer, 'is_abo' => false, 'created_at' => now(), 'updated_at' => now(),
|
||||
]);
|
||||
$aboOrderId = DB::table('shopping_orders')->insertGetId([
|
||||
'shopping_user_id' => $customer, 'is_abo' => true, 'created_at' => now(), 'updated_at' => now(),
|
||||
]);
|
||||
$ownOrderId = DB::table('shopping_orders')->insertGetId([
|
||||
'is_abo' => false, 'created_at' => now(), 'updated_at' => now(),
|
||||
]);
|
||||
|
||||
$make = function (array $attributes) use ($user): void {
|
||||
UserSalesVolume::forceCreate(array_merge([
|
||||
'user_id' => $user->id, 'month' => 6, 'year' => 2026, 'date' => '01.06.2026',
|
||||
], $attributes));
|
||||
};
|
||||
|
||||
// Eigene Bestellungen (status 1): 150 + 250 = 400
|
||||
$make(['shopping_order_id' => $ownOrderId, 'status' => 1, 'points' => 150, 'total_net' => 40]);
|
||||
$make(['shopping_order_id' => $ownOrderId, 'status' => 1, 'points' => 250, 'total_net' => 60]);
|
||||
// Shop-Bestellung (status 2, keine Abo-Order): 300
|
||||
$make(['shopping_order_id' => $shopOrderId, 'status' => 2, 'points' => 300, 'total_net' => 120]);
|
||||
// Abo (status 2, Abo-Order): 500
|
||||
$make(['shopping_order_id' => $aboOrderId, 'status' => 2, 'points' => 500, 'total_net' => 200]);
|
||||
// Sonstige (status 5, ohne Order): 50
|
||||
$make(['shopping_order_id' => null, 'status' => 5, 'points' => 50, 'total_net' => 10]);
|
||||
|
||||
$result = (new PersonalStatisticsService)->monthly($user, 6, 2026);
|
||||
|
||||
expect($result['totals']['own_points'])->toBe(400.0);
|
||||
expect($result['totals']['shop_points'])->toBe(300.0);
|
||||
expect($result['totals']['abo_points'])->toBe(500.0);
|
||||
expect($result['totals']['other_points'])->toBe(50.0);
|
||||
expect($result['totals']['total_points'])->toBe(1250.0);
|
||||
expect($result['totals']['turnover_net'])->toBe(430.0);
|
||||
|
||||
expect($result['groups']['own']['rows'])->toHaveCount(2);
|
||||
expect($result['groups']['shop']['rows'])->toHaveCount(1);
|
||||
expect($result['groups']['abo']['rows'])->toHaveCount(1);
|
||||
expect($result['groups']['other']['rows'])->toHaveCount(1);
|
||||
|
||||
expect($result['groups']['own']['rows'][0]['order_type'])->toBe('own');
|
||||
expect($result['groups']['shop']['rows'][0]['order_type'])->toBe('shop');
|
||||
expect($result['groups']['shop']['rows'][0]['customer_name'])->toBe('Erika Musterfrau');
|
||||
expect($result['groups']['abo']['rows'][0]['customer_email'])->toBe('erika@test.test');
|
||||
});
|
||||
|
||||
it('liefert leere Gruppen ohne Umsaetze', function () {
|
||||
$user = User::forceCreate(['email' => 'empty@test.test', 'password' => 'secret']);
|
||||
|
||||
$result = (new PersonalStatisticsService)->monthly($user, 6, 2026);
|
||||
|
||||
expect($result['totals']['total_points'])->toBe(0.0);
|
||||
expect($result['groups']['own']['rows'])->toBe([]);
|
||||
expect($result['groups']['shop']['rows'])->toBe([]);
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue