Warenwirtschaft: Review-Fix — Stichtags-Schutz als unveränderliches Flag (sale_stock_exempt)

Der Schutz historischer Bestellungen hing an shipped_at, das der
OrderStatusService beim Status-Toggle nullt und neu stempelt — Storno +
erneutes Versenden einer Alt-Bestellung hätte rückwirkend vom heutigen
Bestand abgezogen. Migration mit einmaligem Backfill (shipped_at vor
16.07.2026), Guard prüft nur noch das Flag.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Kevin Adametz 2026-07-20 09:41:01 +00:00
parent e6af987237
commit 3eb14762e7
6 changed files with 70 additions and 11 deletions

View file

@ -249,9 +249,11 @@ test('service-abgleich ist auch direkt idempotent (cron-storno)', function () {
test('historische bestellung (vor stichtag versendet) bucht bei erneutem speichern nichts', function () {
$creme = ap13MakeProduct('AP13 Historisch');
// sale_stock_exempt entspricht dem Migrations-Backfill (shipped_at vor dem Stichtag)
$order = ap13MakeOrder([['product' => $creme, 'qty' => 5]], [
'shipped' => 3,
'shipped_at' => '2025-12-12 14:05:26',
'sale_stock_exempt' => true,
]);
// Admin bestätigt den Status einer Alt-Bestellung erneut — darf nicht rückwirkend abziehen
@ -261,6 +263,24 @@ test('historische bestellung (vor stichtag versendet) bucht bei erneutem speiche
->and($order->fresh()->shipped_at?->format('Y-m-d'))->toBe('2025-12-12');
});
test('stichtags-schutz ueberlebt storno und erneutes versenden (status-toggle)', function () {
$creme = ap13MakeProduct('AP13 Historisch-Toggle');
$order = ap13MakeOrder([['product' => $creme, 'qty' => 5]], [
'shipped' => 3,
'shipped_at' => '2025-12-12 14:05:26',
'sale_stock_exempt' => true,
]);
// Storno nullt shipped_at, erneutes Versenden stempelt es neu (nach Stichtag) —
// das unveränderliche Flag muss den rückwirkenden Abzug trotzdem verhindern
$admin = ap13MakeAdmin();
ap13SetShipped($order, 10, $admin);
ap13SetShipped($order, 2, $admin);
expect(ProductStockMovement::query()->where('product_id', $creme->id)->count())->toBe(0)
->and($order->fresh()->sale_stock_exempt)->toBeTrue();
});
test('verkaufs-abgaenge zaehlen im monatsverbrauch', function () {
$service = app(ProductStockService::class);
$creme = ap13MakeProduct('AP13 Verbrauch');