Overview for refunds

This commit is contained in:
2026-09-07 10:45:33 +02:00
parent b9795f08f0
commit d07980dd1f
7 changed files with 272 additions and 2 deletions
+117
View File
@@ -9,6 +9,8 @@ use App\Domains\ParticipantRefund\Actions\CancelRefund\CancelRefundRequest;
use App\Domains\ParticipantRefund\Actions\CreateRefundDocument\CreateRefundDocumentCommand;
use App\Domains\ParticipantRefund\Actions\ReleaseRefund\ReleaseRefundCommand;
use App\Domains\ParticipantRefund\Actions\ReleaseRefund\ReleaseRefundRequest;
use App\Domains\ParticipantRefund\Actions\ResendRefundMail\ResendRefundMailCommand;
use App\Domains\ParticipantRefund\Actions\ResendRefundMail\ResendRefundMailRequest;
use App\Enumerations\EfzStatus;
use App\Enumerations\CostUnitType;
use App\Enumerations\InvoiceStatus;
@@ -243,6 +245,11 @@ class ParticipantRefundTest extends TestCase
))->execute();
}
private function resend(?ParticipantRefund $refund)
{
return new ResendRefundMailCommand(new ResendRefundMailRequest($refund))->execute();
}
/** Der zweite Weg: Der Teili verzichtet auf die Auszahlung und spendet -- ohne Bankverbindung. */
private function acceptAsDonation(?ParticipantRefund $refund, bool $declarationAccepted = true)
{
@@ -684,6 +691,69 @@ class ParticipantRefundTest extends TestCase
$this->assertSame(ParticipantRefund::STATUS_ACCEPTED, $refund->fresh()->status);
}
/*
|--------------------------------------------------------------------------
| Die Mail noch einmal schicken
|--------------------------------------------------------------------------
*/
public function test_resend_sends_the_release_mail_again_without_touching_the_refund(): void
{
$participant = $this->makeParticipant($this->makeEvent(), ['email_2' => 'eltern@example.com']);
$refund = $this->release($participant)->refund;
// Erst ab hier zählen: die Mails der Freigabe sind nicht gemeint.
Mail::fake();
$response = $this->resend($refund);
$this->assertTrue($response->success);
Mail::assertSent(RefundReleasedMail::class, 2);
Mail::assertSent(RefundReleasedMail::class, fn ($mail) => $mail->hasTo('mika@example.com'));
Mail::assertSent(RefundReleasedMail::class, fn ($mail) => $mail->hasTo('eltern@example.com'));
// Der Vorgang bleibt, wie er war -- vorgemerkt wurde er beim ersten Mal.
$fresh = $refund->fresh();
$this->assertSame(ParticipantRefund::STATUS_PENDING, $fresh->status);
$this->assertSame($refund->token, $fresh->token);
$this->assertEquals($refund->released_at, $fresh->released_at);
}
public function test_resend_sends_only_one_mail_without_contact_person(): void
{
$refund = $this->release($this->makeParticipant($this->makeEvent()))->refund;
Mail::fake();
$this->resend($refund);
Mail::assertSent(RefundReleasedMail::class, 1);
}
public function test_resend_is_rejected_after_acceptance(): void
{
$refund = $this->release($this->makeParticipant($this->makeEvent()))->refund;
$this->accept($refund);
Mail::fake();
$response = $this->resend($refund->fresh());
$this->assertFalse($response->success);
$this->assertStringContainsString('bereits bestätigt', $response->message);
Mail::assertNothingSent();
}
public function test_resend_is_rejected_after_a_cancellation(): void
{
$refund = $this->release($this->makeParticipant($this->makeEvent()))->refund;
new CancelRefundCommand(new CancelRefundRequest($refund))->execute();
Mail::fake();
$response = $this->resend($refund->fresh());
$this->assertFalse($response->success);
$this->assertStringContainsString('abgebrochen', $response->message);
Mail::assertNothingSent();
}
/*
|--------------------------------------------------------------------------
| Der gezahlte Beitrag bleibt unangetastet
@@ -897,6 +967,53 @@ class ParticipantRefundTest extends TestCase
$this->assertSame(ParticipantRefund::STATUS_PENDING, $refund->fresh()->status);
}
public function test_resend_over_http_sends_the_mail_again(): void
{
$refund = $this->release($this->makeParticipant($this->makeEvent()))->refund;
$this->actingAs($this->makeAdmin());
Mail::fake();
$this->postJson('/api/v1/participant-refund/' . $refund->token . '/resend-mail')
->assertOk()
->assertJsonPath('status', 'success');
Mail::assertSent(RefundReleasedMail::class, 1);
}
public function test_resend_requires_a_login(): void
{
$refund = $this->release($this->makeParticipant($this->makeEvent()))->refund;
Mail::fake();
$this->post('/api/v1/participant-refund/' . $refund->token . '/resend-mail')
->assertRedirect('/login');
Mail::assertNothingSent();
}
/** Der Token allein reicht nicht: nachschicken darf nur, wer die Veranstaltung verwalten kann. */
public function test_resend_is_forbidden_without_access_to_the_event(): void
{
$refund = $this->release($this->makeParticipant($this->makeEvent()))->refund;
$this->actingAs($this->makeParticipantUser());
Mail::fake();
$this->postJson('/api/v1/participant-refund/' . $refund->token . '/resend-mail')
->assertForbidden();
Mail::assertNothingSent();
}
public function test_resend_on_an_unknown_token_is_forbidden(): void
{
$this->actingAs($this->makeAdmin());
$this->postJson('/api/v1/participant-refund/gibtesnicht/resend-mail')
->assertForbidden();
}
/*
|--------------------------------------------------------------------------
| Die Mails müssen sich auch wirklich rendern lassen