Punkte: Dezimalpunkte in Einmalprodukten, Homeparty und Shop-API nicht mehr abschneiden
Produkte mit 7,5 Punkten wurden an drei Stellen zu ganzen Zahlen: user_abo_one_time_items (PHP-Cast int, 7,5 -> 7), homeparty_user_order_items (MySQL rundete auf 8) und shopping_collect_orders (Summe der Shop-API). Die Migration zieht die drei Spalten auf DECIMAL(10,2) nach (Nachtrag zu 2026_01_22), Cast und Abo-Snapshot rechnen mit float. points:report-decimal-diff wertet die Differenzen je Berater und Monat aus (nur lesend), points:repair-decimal korrigiert den laufenden Monat und zieht die Monatssummen nach. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
e009b11259
commit
a21bebc932
15 changed files with 1539 additions and 9 deletions
84
tests/Feature/AboOneTimeDecimalPointsTest.php
Normal file
84
tests/Feature/AboOneTimeDecimalPointsTest.php
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Dezimal-Punkte bei Abo-Einmalartikeln.
|
||||
*
|
||||
* Produkte können halbe Punkte haben (z.B. 7,5). Der Snapshot in
|
||||
* {@see AboOrderCart::buildOneTimeSnapshot()} hat diese früher per (int)-Cast
|
||||
* abgeschnitten (7,5 -> 7); zusätzlich war user_abo_one_time_items.points noch
|
||||
* eine INT-Spalte. Die Punkte fließen über shopping_orders.points in
|
||||
* user_sales_volumes und damit in die Provisionsberechnung ein, der Verlust war
|
||||
* also nicht nur ein Anzeigefehler auf der Rechnung.
|
||||
*/
|
||||
|
||||
use App\Models\Product;
|
||||
use App\Models\UserAboOneTimeItem;
|
||||
use App\Services\AboOneTimeService;
|
||||
use App\Services\AboOrderCart;
|
||||
use App\Services\Facade\Yard;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Tests\TestCase;
|
||||
|
||||
uses(TestCase::class, RefreshDatabase::class);
|
||||
|
||||
/** Setzt die Punkte am Produkt an der Datenbank vorbei am Mutator-freien Weg. */
|
||||
function makeProductWithPoints(array $showOn, float $points): Product
|
||||
{
|
||||
$product = makeProduct($showOn);
|
||||
DB::table('products')->where('id', $product->id)->update(['points' => $points]);
|
||||
|
||||
return Product::findOrFail($product->id);
|
||||
}
|
||||
|
||||
describe('Abo-Einmalartikel mit Dezimal-Punkten', function () {
|
||||
beforeEach(function () {
|
||||
makeShopEnv();
|
||||
$this->service = new AboOneTimeService;
|
||||
});
|
||||
|
||||
it('behält halbe Punkte im Preis-Snapshot', function () {
|
||||
$abo = makeMeAbo();
|
||||
$product = makeProductWithPoints(['2'], 7.5);
|
||||
|
||||
$snapshot = AboOrderCart::buildOneTimeSnapshot($product, $abo);
|
||||
|
||||
expect($snapshot['points'])->toBe(7.5);
|
||||
});
|
||||
|
||||
it('persistiert halbe Punkte am Einmal-Artikel', function () {
|
||||
$abo = makeMeAbo();
|
||||
$product = makeProductWithPoints(['2'], 7.5);
|
||||
|
||||
$message = $this->service->handleAction($abo, ['action' => 'add', 'product_id' => $product->id]);
|
||||
|
||||
expect($message)->toBeNull();
|
||||
|
||||
$item = UserAboOneTimeItem::where('user_abo_id', $abo->id)->firstOrFail();
|
||||
expect((float) $item->points)->toBe(7.5)
|
||||
->and((float) DB::table('user_abo_one_time_items')->where('id', $item->id)->value('points'))->toBe(7.5);
|
||||
});
|
||||
|
||||
it('übernimmt halbe Punkte in den Abo-Yard', function () {
|
||||
$abo = makeMeAbo();
|
||||
$product = makeProductWithPoints(['2'], 7.5);
|
||||
|
||||
$this->service->handleAction($abo, ['action' => 'add', 'product_id' => $product->id]);
|
||||
|
||||
$item = UserAboOneTimeItem::where('user_abo_id', $abo->id)->firstOrFail();
|
||||
$item->update(['qty' => 2, 'confirmed_qty' => 2, 'confirmed_at' => now()]);
|
||||
|
||||
AboOrderCart::addOneTimeItemsToYard($abo->fresh());
|
||||
|
||||
expect(Yard::instance(AboOrderCart::INSTANCE)->points())->toBe(15.0);
|
||||
});
|
||||
|
||||
it('lässt ganzzahlige Punkte unverändert', function () {
|
||||
$abo = makeMeAbo();
|
||||
$product = makeProductWithPoints(['2'], 14.0);
|
||||
|
||||
$snapshot = AboOrderCart::buildOneTimeSnapshot($product, $abo);
|
||||
|
||||
expect($snapshot['points'])->toBe(14.0);
|
||||
});
|
||||
})->group('abo');
|
||||
Loading…
Add table
Add a link
Reference in a new issue