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
+36
View File
@@ -4,6 +4,7 @@ namespace App\Models;
use App\Casts\AmountCast;
use App\Enumerations\RefundReason;
use App\Enumerations\RetentionReason;
use App\Scopes\InstancedModel;
use App\ValueObjects\Amount;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
@@ -20,6 +21,9 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
* @property Amount|null $amount
* @property string|null $reason
* @property string|null $reason_note
* @property string|null $retention_reason
* @property string|null $retention_reason_note
* @property Amount|null $retained_amount
* @property string|null $account_owner
* @property string|null $account_iban
* @property int|null $captured_by
@@ -51,6 +55,9 @@ class ParticipantRefund extends InstancedModel
'amount',
'reason',
'reason_note',
'retention_reason',
'retention_reason_note',
'retained_amount',
'account_owner',
'account_iban',
'captured_by',
@@ -63,6 +70,7 @@ class ParticipantRefund extends InstancedModel
protected $casts = [
'amount' => AmountCast::class,
'retained_amount' => AmountCast::class,
'released_at' => 'datetime',
'accepted_at' => 'datetime',
'cancelled_at' => 'datetime',
@@ -129,4 +137,32 @@ class ParticipantRefund extends InstancedModel
{
return (string) ($this->reasonRelation()->first()?->name ?? '');
}
/** Der Einbehaltungsgrund als Stammdatensatz -- leer, wenn voll erstattet wurde. */
public function retentionReasonRelation(): BelongsTo
{
return $this->belongsTo(RetentionReason::class, 'retention_reason', 'slug');
}
public function retentionReasonLabel(): string
{
return (string) ($this->retentionReasonRelation()->first()?->name ?? '');
}
/** Der auf dem Beleg auszuweisende Text zur Einbehaltung. */
public function retentionReasonText(): string
{
return $this->retentionReasonRelation()->first()?->documentText($this->retention_reason_note) ?? '';
}
/**
* Ob etwas beim Verband bleibt -- die halbe Cent-Toleranz fängt die Float-Rundung ab.
*
* Der Betrag steht in `retained_amount` und wird beim Einreichen festgeschrieben. Ihn zur Laufzeit
* aus `amount_paid` zu rechnen ginge schief: Danach führt das Feld bereits den Rest.
*/
public function hasRetention(): bool
{
return ($this->retained_amount?->getAmount() ?? 0.0) > 0.005;
}
}