68 lines
2.4 KiB
PHP
68 lines
2.4 KiB
PHP
<?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(),
|
||
);
|
||
}
|
||
}
|