Calculation errors for refunded amounts

This commit is contained in:
2026-09-04 01:15:37 +02:00
parent 5beb2b1d97
commit c1c1a4f143
28 changed files with 1436 additions and 26 deletions
+27 -2
View File
@@ -10,6 +10,7 @@ use App\Enumerations\CostUnitType;
use App\Enumerations\EfzStatus;
use App\Enumerations\InvoiceStatus;
use App\Enumerations\RefundReason;
use App\Enumerations\RetentionReason;
use App\Enumerations\UserRole;
use App\Mail\ParticipantRefundMails\RefundAcceptedMail;
use App\Mail\ParticipantRefundMails\RefundReleasedMail;
@@ -204,12 +205,18 @@ class RefundDirectCaptureTest extends TestCase
], $attributes));
}
/** Freigabe mit bereits bekannter Bankverbindung. */
/**
* Freigabe mit bereits bekannter Bankverbindung.
*
* 220 von 300 gezahlten Euro: Es bleibt etwas beim Verband, deshalb gehört ein Einbehaltungsgrund
* dazu.
*/
private function releaseWithBankDetails(
?EventParticipant $participant = null,
string $owner = 'Mika Muster',
string $iban = 'DE02120300000000202051',
float $amount = 220.0,
?string $retentionReason = RetentionReason::CANCELLATION_FEE,
) {
return new ReleaseRefundCommand(new ReleaseRefundRequest(
participant: $participant ?? $this->makeParticipant(),
@@ -217,6 +224,7 @@ class RefundDirectCaptureTest extends TestCase
reason: RefundReason::SICKNESS,
accountOwner: $owner,
accountIban: $iban,
retentionReason: $retentionReason,
))->execute();
}
@@ -252,7 +260,7 @@ class RefundDirectCaptureTest extends TestCase
$this->assertTrue($refund->wasCapturedByManagement());
}
public function test_the_invoice_exists_and_the_paid_amount_is_cleared(): void
public function test_the_invoice_exists_and_the_paid_amount_is_settled(): void
{
$participant = $this->makeParticipant();
@@ -263,7 +271,19 @@ class RefundDirectCaptureTest extends TestCase
$this->assertEqualsWithDelta(220.0, $invoice->amount, 0.001);
$this->assertSame($invoice->id, ParticipantRefund::first()->invoice_id);
// 300 gezahlt, 220 erstattet -- die restlichen 80 bleiben beim Verband und werden dort geführt.
$this->assertEqualsWithDelta(80.0, $participant->fresh()->amount_paid->getAmount(), 0.001);
}
public function test_a_full_refund_leaves_nothing_behind(): void
{
$participant = $this->makeParticipant();
$this->releaseWithBankDetails($participant, amount: 300.0, retentionReason: null);
$this->assertEqualsWithDelta(0.0, $participant->fresh()->amount_paid->getAmount(), 0.001);
$this->assertEqualsWithDelta(0.0, ParticipantRefund::first()->retained_amount->getAmount(), 0.001);
$this->assertNull(ParticipantRefund::first()->retention_reason);
}
public function test_only_the_receipt_mail_goes_out(): void
@@ -299,6 +319,7 @@ class RefundDirectCaptureTest extends TestCase
participant: $this->makeParticipant(),
amount: new Amount(220.0, 'Euro'),
reason: RefundReason::SICKNESS,
retentionReason: RetentionReason::CANCELLATION_FEE,
))->execute()->refund;
$refund->update([
@@ -379,6 +400,8 @@ class RefundDirectCaptureTest extends TestCase
$this->postJson('/api/v1/participant-refund/' . $participant->identifier . '/release', [
'amount' => '220,00',
'reason' => RefundReason::SICKNESS,
// 220 von 300 -- der Rest bleibt beim Verband und braucht eine Begründung.
'retentionReason' => RetentionReason::CANCELLATION_FEE,
'accountOwner' => 'Mika Muster',
'accountIban' => 'DE02 1203 0000 0000 2020 51',
])
@@ -396,6 +419,8 @@ class RefundDirectCaptureTest extends TestCase
$this->postJson('/api/v1/participant-refund/' . $participant->identifier . '/release', [
'amount' => '220,00',
'reason' => RefundReason::SICKNESS,
// 220 von 300 -- der Rest bleibt beim Verband und braucht eine Begründung.
'retentionReason' => RetentionReason::CANCELLATION_FEE,
'accountOwner' => '',
'accountIban' => '',
])