- 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>
88 lines
3.3 KiB
PHP
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);
|
|
});
|