Kundenabo-Vorschau: bereits abgerechnete Punkte fehlten in der Basis
Die Kachelreihe "Punkte aus meinen Kundenabos zum 5./10./20./25." startete bei einer Basis von 0 und addierte nur die noch offenen Ausfuehrungen. Damit standen die bereits vergangenen Termine auf null, obwohl im Monat laengst Lieferungen gebucht waren, und die spaeteren Termine zeigten nur den Rest statt des Monatsstands. Berater 454 im September: vorher 0 / 0 / 131 / 319, jetzt 457 / 457 / 588 / 776. Betrifft im September 86 Berater mit zusammen 15.936 Punkten — reine Anzeige, gebucht und abgerechnet wurde korrekt. Die Basis ist jetzt die im Monat aus den eigenen Kundenabos abgerechnete Punktzahl, ueber dieselbe Abgrenzung wie die Backoffice-Statistik (SalesVolumePoints::customerAboPoints(), Stornos vorzeichengetreu). Damit liest sich die Kachel wie die Prognose-Kachel auf dem Dashboard: Stand heute plus das, was bis zum Termin noch hereinkommt. Hinweistext in allen vier Sprachen nachgezogen. Nicht aus dem Audit-Paket: Die Null-Basis stammt aus der K9-Umsetzung vom 07.09., nicht aus der A13-Korrektur. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
ff0860fb81
commit
cb5664a483
7 changed files with 132 additions and 10 deletions
|
|
@ -491,6 +491,57 @@ it('prognostiziert die Liefertage ausschliesslich aus den eigenen Kundenabos', f
|
|||
->and($forecast['days'][3])->toMatchArray(['day' => 25, 'upcoming' => 75.0, 'total' => 75.0]);
|
||||
});
|
||||
|
||||
it('rechnet die bereits abgerechneten Kundenabo-Punkte in die persoenliche Vorschau ein', function (): void {
|
||||
// Die Kacheln beantworten "wieviel Volumenpunkte habe ich am 5./10./20./25.".
|
||||
// Ohne die bereits gebuchten Lieferungen stehen die vergangenen Termine auf
|
||||
// null, obwohl die Punkte laengst im Ist stecken.
|
||||
Carbon::setTestNow(Carbon::parse('2026-07-11'));
|
||||
|
||||
$berater = pflMakeUser();
|
||||
|
||||
$aboOrder = ShoppingOrder::forceCreate([
|
||||
'shopping_user_id' => 0, 'auth_user_id' => $berater->id, 'country_id' => 0,
|
||||
'user_shop_id' => 0, 'is_abo' => true, 'paid' => true,
|
||||
]);
|
||||
$shopOrder = ShoppingOrder::forceCreate([
|
||||
'shopping_user_id' => 0, 'auth_user_id' => $berater->id, 'country_id' => 0,
|
||||
'user_shop_id' => 0, 'is_abo' => false, 'paid' => true,
|
||||
]);
|
||||
|
||||
// Am 5. und 10. geliefert und gebucht.
|
||||
UserSalesVolume::forceCreate(['user_id' => $berater->id, 'shopping_order_id' => $aboOrder->id, 'month' => 7, 'year' => 2026, 'points' => 40, 'status' => 2]);
|
||||
UserSalesVolume::forceCreate(['user_id' => $berater->id, 'shopping_order_id' => $aboOrder->id, 'month' => 7, 'year' => 2026, 'points' => 60, 'status' => 2]);
|
||||
// Einzelbestellung eines Kunden: kein Abo, gehoert nicht in diese Kachel.
|
||||
UserSalesVolume::forceCreate(['user_id' => $berater->id, 'shopping_order_id' => $shopOrder->id, 'month' => 7, 'year' => 2026, 'points' => 500, 'status' => 2]);
|
||||
// Anderer Monat.
|
||||
UserSalesVolume::forceCreate(['user_id' => $berater->id, 'shopping_order_id' => $aboOrder->id, 'month' => 6, 'year' => 2026, 'points' => 900, 'status' => 2]);
|
||||
|
||||
// Noch offen zum 20.
|
||||
pflMakeAbo($berater->id, 'ot', '2026-07-20', 30);
|
||||
|
||||
$forecast = app(PaylineForecastService::class)->personalCustomerAboForecast($berater);
|
||||
|
||||
expect($forecast['base'])->toBe(100.0)
|
||||
->and($forecast['days'][0])->toMatchArray(['day' => 5, 'upcoming' => 0.0, 'total' => 100.0])
|
||||
->and($forecast['days'][2])->toMatchArray(['day' => 20, 'upcoming' => 30.0, 'total' => 130.0])
|
||||
->and($forecast['days'][3])->toMatchArray(['day' => 25, 'upcoming' => 30.0, 'total' => 130.0]);
|
||||
});
|
||||
|
||||
it('zieht ein Storno von der Basis der persoenlichen Vorschau ab', function (): void {
|
||||
Carbon::setTestNow(Carbon::parse('2026-07-11'));
|
||||
|
||||
$berater = pflMakeUser();
|
||||
$aboOrder = ShoppingOrder::forceCreate([
|
||||
'shopping_user_id' => 0, 'auth_user_id' => $berater->id, 'country_id' => 0,
|
||||
'user_shop_id' => 0, 'is_abo' => true, 'paid' => true,
|
||||
]);
|
||||
|
||||
UserSalesVolume::forceCreate(['user_id' => $berater->id, 'shopping_order_id' => $aboOrder->id, 'month' => 7, 'year' => 2026, 'points' => 100, 'status' => 2]);
|
||||
UserSalesVolume::forceCreate(['user_id' => $berater->id, 'shopping_order_id' => $aboOrder->id, 'month' => 7, 'year' => 2026, 'points' => -40, 'status' => 6, 'storno_origin_status' => 2]);
|
||||
|
||||
expect(app(PaylineForecastService::class)->personalCustomerAboForecast($berater)['base'])->toBe(60.0);
|
||||
});
|
||||
|
||||
it('prognostiziert auch ohne bereits erreichte Qualifikationsstufe', function (): void {
|
||||
// A08: Wer im Monat noch keine Stufe qualifiziert hat, kann die erste durch
|
||||
// kommende eigene Kundenabo-Punkte trotzdem erreichen. Vorher lieferte die
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue