Abos: taegliche Warnung fuer ueberfaellige Abos, ohne Nachbuchung
user:make_abo_order nimmt nur Abos mit next_date = heute; faellt ein Lauf aus, bleibt ein Abo stillschweigend liegen (Abo 39: Termin 25.03.2026). abo:check-overdue meldet taeglich um 05:30 alle aktiven Abos mit Status okay und verstrichenem Termin per Mail an mivita (Link ins Admin-Abo) und ins abo_order-Log. Es wird bewusst nichts nachgebucht; --no-mail nur fuer die Ausgabe. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
0b8f8abeeb
commit
452d1ac17f
5 changed files with 288 additions and 0 deletions
76
tests/Feature/AboCheckOverdueTest.php
Normal file
76
tests/Feature/AboCheckOverdueTest.php
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
<?php
|
||||
|
||||
use App\Mail\AboOverdueAlertMail;
|
||||
use App\Models\UserAbo;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use Tests\TestCase;
|
||||
|
||||
uses(TestCase::class, RefreshDatabase::class);
|
||||
|
||||
beforeEach(function () {
|
||||
Carbon::setTestNow(Carbon::parse('2026-09-23 05:30:00'));
|
||||
Mail::fake();
|
||||
});
|
||||
|
||||
afterEach(fn () => Carbon::setTestNow());
|
||||
|
||||
function overdueAbo(string $nextDate, int $status = 2, bool $active = true): UserAbo
|
||||
{
|
||||
return UserAbo::create([
|
||||
'user_id' => null,
|
||||
'member_id' => 1,
|
||||
'shopping_user_id' => 0,
|
||||
'is_for' => 'ot',
|
||||
'email' => 'abo-'.uniqid('', true).'@example.com',
|
||||
'payone_userid' => 1,
|
||||
'clearingtype' => 'cc',
|
||||
'active' => $active,
|
||||
'status' => $status,
|
||||
'abo_interval' => (int) Carbon::parse($nextDate)->day,
|
||||
'start_date' => '2026-01-01',
|
||||
'next_date' => $nextDate,
|
||||
]);
|
||||
}
|
||||
|
||||
it('meldet laufende Abos mit verstrichenem Termin und bucht nichts nach', function () {
|
||||
$stuck = overdueAbo('2026-03-25');
|
||||
overdueAbo('2026-09-23'); // heute faellig: laeuft regulaer
|
||||
overdueAbo('2026-10-05'); // Zukunft
|
||||
overdueAbo('2026-08-10', status: 3); // Zahlung fehlgeschlagen: eigener Zustand
|
||||
overdueAbo('2026-08-10', active: false); // inaktiv
|
||||
|
||||
$this->artisan('abo:check-overdue')
|
||||
->expectsOutputToContain('Überfällige Abos: 1')
|
||||
->assertSuccessful();
|
||||
|
||||
Mail::assertSent(AboOverdueAlertMail::class, function (AboOverdueAlertMail $mail) use ($stuck) {
|
||||
$html = $mail->render();
|
||||
|
||||
return $mail->hasTo(config('app.default_mail'))
|
||||
&& count($mail->overdueAbos) === 1
|
||||
&& str_contains($html, '#'.$stuck->id)
|
||||
&& str_contains($html, '25.03.2026')
|
||||
&& str_contains($html, '/admin/abos/detail/'.$stuck->id);
|
||||
});
|
||||
|
||||
expect(Carbon::parse($stuck->fresh()->getRawOriginal('next_date'))->toDateString())->toBe('2026-03-25')
|
||||
->and($stuck->user_abo_orders()->count())->toBe(0);
|
||||
});
|
||||
|
||||
it('schickt ohne ueberfaellige Abos keine Mail', function () {
|
||||
overdueAbo('2026-10-05');
|
||||
|
||||
$this->artisan('abo:check-overdue')->expectsOutputToContain('Keine überfälligen Abos.')->assertSuccessful();
|
||||
|
||||
Mail::assertNothingSent();
|
||||
});
|
||||
|
||||
it('schickt mit --no-mail nur die Ausgabe', function () {
|
||||
overdueAbo('2026-09-01');
|
||||
|
||||
$this->artisan('abo:check-overdue', ['--no-mail' => true])->assertSuccessful();
|
||||
|
||||
Mail::assertNothingSent();
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue