mivita/tests/Feature/AboMoveOrdersTest.php
Kevin f6faad9ae7 Abo: extern-erledigt für gelöschte Abos + Lieferhistorie-Umzug (Ticket Kunz Mai-Punkte)
- AboExternalCompletionService: Bestellungen gelöschter/ersetzter Abos können
  nachträglich extern erledigt werden (Punkte + Status 8 + Versandstatus);
  das gelöschte Abo wird dabei nicht reaktiviert
- IncentiveTracker::trackSalesVolume: Abo-Zuordnung inkl. gelöschter Abos
  (withTrashed) - nachgebuchte Umsätze bereits getrackter Abos zählen weiter
- Neue Wartungs-Commands: abo:extern-done {shopping_order_id} und
  abo:move-orders {from_abo} {to_abo} (--dry-run, Guards: gleicher Kunde)
- Latent datumsabhängigen Alt-Test in AboExternalCompletionTest repariert
  (Buchung nutzt date(), nicht Carbon::setTestNow)

Fall Kunz (dev/2026-08-12-intensiv-tickets): Dannenhauers gelieferte, aber am
17.06. beim Nachtragen vergessene Mai-Order 53274 → abo:extern-done (+54 P);
Bockhackers Lieferhistorie von gelöschtem Abo 197 → 496 umgehängt (Zähler 4).
Bockhackers 24 P existieren bereits (Juni-Buchung der Mai-Lieferung).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-21 12:06:29 +00:00

88 lines
3.3 KiB
PHP

<?php
use App\Models\Country;
use App\Models\ShoppingUser;
use App\Models\UserAbo;
use App\Models\UserAboOrder;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
uses(TestCase::class, RefreshDatabase::class);
function moveOrdersSeedAbo(string $email, int $memberId, bool $deleted = false): UserAbo
{
$country = Country::firstOrCreate(['code' => 'DE'], [
'phone' => '49', 'en' => 'Germany', 'de' => 'Deutschland', 'es' => 'Alemania',
'fr' => 'Allemagne', 'it' => 'Germania', 'ru' => 'Германия',
]);
$shoppingUser = ShoppingUser::create([
'auth_user_id' => $memberId,
'member_id' => $memberId,
'billing_email' => $email,
'billing_country_id' => $country->id,
'shipping_country_id' => $country->id,
'is_for' => 'ot',
]);
$abo = UserAbo::create([
'shopping_user_id' => $shoppingUser->id,
'member_id' => $memberId,
'is_for' => 'ot',
'email' => $email,
'payone_userid' => 1,
'clearingtype' => 'cc',
'active' => ! $deleted,
'status' => 2,
'abo_interval' => 5,
]);
if ($deleted) {
$abo->delete();
}
return $abo;
}
it('haengt die Lieferhistorie eines geloeschten Abos auf das Nachfolge-Abo um', function () {
$old = moveOrdersSeedAbo('kundin@example.com', 42, deleted: true);
$new = moveOrdersSeedAbo('kundin@example.com', 42);
UserAboOrder::create(['user_abo_id' => $old->id, 'shopping_order_id' => 1001, 'status' => 2, 'paid' => true]);
UserAboOrder::create(['user_abo_id' => $old->id, 'shopping_order_id' => 1002, 'status' => 8, 'paid' => false]);
UserAboOrder::create(['user_abo_id' => $new->id, 'shopping_order_id' => 1003, 'status' => 2, 'paid' => true]);
$this->artisan('abo:move-orders', ['from_abo' => $old->id, 'to_abo' => $new->id])
->assertSuccessful();
expect(UserAboOrder::where('user_abo_id', $old->id)->count())->toBe(0)
->and(UserAboOrder::where('user_abo_id', $new->id)->count())->toBe(3);
// bezahlte + extern erledigte (Status 8) Lieferungen zaehlen fuer die Mindestlaufzeit
expect(UserAbo::find($new->id)->getCountPaidOrders())->toBe(3);
});
it('verweigert das Umhaengen zwischen Abos verschiedener Kunden', function () {
$old = moveOrdersSeedAbo('kundin-a@example.com', 42, deleted: true);
$new = moveOrdersSeedAbo('kundin-b@example.com', 42);
UserAboOrder::create(['user_abo_id' => $old->id, 'shopping_order_id' => 1001, 'status' => 2, 'paid' => true]);
$this->artisan('abo:move-orders', ['from_abo' => $old->id, 'to_abo' => $new->id])
->assertFailed();
expect(UserAboOrder::where('user_abo_id', $old->id)->count())->toBe(1);
});
it('aendert im dry-run nichts', function () {
$old = moveOrdersSeedAbo('kundin@example.com', 42, deleted: true);
$new = moveOrdersSeedAbo('kundin@example.com', 42);
UserAboOrder::create(['user_abo_id' => $old->id, 'shopping_order_id' => 1001, 'status' => 2, 'paid' => true]);
$this->artisan('abo:move-orders', ['from_abo' => $old->id, 'to_abo' => $new->id, '--dry-run' => true])
->assertSuccessful();
expect(UserAboOrder::where('user_abo_id', $old->id)->count())->toBe(1)
->and(UserAboOrder::where('user_abo_id', $new->id)->count())->toBe(0);
});