Files
mareike/app/Enumerations/TaxExemptionReason.php
2026-08-06 11:49:58 +02:00

68 lines
2.4 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
namespace App\Enumerations;
/**
* Gründe für eine Umsatzsteuerbefreiung. Jeder Fall kapselt sein UI-Label und den auf der Rechnung
* verpflichtenden Hinweis nach § 14 Abs. 4 Nr. 8 UStG, damit Label und Text nur an einer Stelle
* gepflegt werden. Gemeinnützigkeit allein befreit nicht die Befreiung braucht immer einen konkreten
* Rechtsgrund; die Vereins-Fälle sind über § 4 Nr. 22a / Nr. 25 abgedeckt.
*/
enum TaxExemptionReason: string
{
case SmallBusiness = 'small_business';
case Education = 'education';
case YouthWelfare = 'youth_welfare';
case Custom = 'custom';
public function label(): string
{
return match ($this) {
self::SmallBusiness => 'Kleinunternehmer (§ 19 UStG)',
self::Education => 'Bildungs-/Kursleistung (§ 4 Nr. 22a UStG)',
self::YouthWelfare => 'Kinder- und Jugendhilfe (§ 4 Nr. 25 UStG)',
self::Custom => 'Sonstiger Grund (Freitext)',
};
}
/**
* Pflichthinweis für die Rechnung. Bei einem individuellen Grund (Custom) wird der hinterlegte
* Freitext des Tenants verwendet.
*/
public function invoiceText(?string $customNote = null): string
{
return match ($this) {
self::SmallBusiness => 'Gemäß § 19 UStG wird keine Umsatzsteuer berechnet.',
self::Education => 'Die Leistung ist gemäß § 4 Nr. 22 Buchst. a UStG von der Umsatzsteuer befreit.',
self::YouthWelfare => 'Die Leistung ist gemäß § 4 Nr. 25 UStG von der Umsatzsteuer befreit.',
self::Custom => trim((string)$customNote),
};
}
/**
* Ob dieser Grund einen zusätzlichen Freitext des Tenants erfordert.
*/
public function requiresNote(): bool
{
return $this === self::Custom;
}
/**
* Optionen für das Frontend inkl. Vorschau-Text. Bei Custom ist `text` leer, da der Text erst aus
* dem Freitext des Tenants entsteht.
*
* @return array<int, array{value: string, label: string, text: string}>
*/
public static function options(): array
{
return array_map(
static fn(self $reason): array => [
'value' => $reason->value,
'label' => $reason->label(),
'text' => $reason->requiresNote() ? '' : $reason->invoiceText(),
],
self::cases(),
);
}
}