loadRoleOptions(); $this->codePrefix = $this->roleOptions[$this->role]['prefix']; $this->expiresAt = now()->addDays(7)->format('Y-m-d'); if ($this->role === 'customer') { $this->regenerateCustomerRange(); } else { $this->regenerateNumber(); } } private function loadRoleOptions(): void { $roles = Role::whereNotNull('reg_prefix')->orderBy('id', 'asc')->get(); foreach ($roles as $role) { // Konvertiere Role name zu lowercase für Konsistenz mit registration_codes.role $key = strtolower(str_replace('-', '', $role->name)); // "Broker" → "broker" // Für Broker spezielle Behandlung $this->roleOptions[$key] = [ 'label' => $role->display_name ?? $role->name, 'prefix' => $role->reg_prefix, 'startNumber' => $role->reg_start_number ?? 10000000, 'description' => $role->reg_description, 'color' => $role->color ?? 'zinc', 'icon' => $role->icon ?? 'key', ]; } } public function updatedRole(): void { $this->codePrefix = $this->roleOptions[$this->role]['prefix']; $this->name = null; $this->brokerPartnerId = null; $this->customerBrokerType = 'broker'; $this->rangeFrom = ''; $this->rangeTo = ''; $this->rangeFromPart1 = ''; $this->rangeFromPart2 = ''; $this->rangeFromPart3 = ''; $this->rangeFromPart4 = ''; $this->rangeToPart1 = ''; $this->rangeToPart2 = ''; $this->rangeToPart3 = ''; $this->rangeToPart4 = ''; if ($this->role === 'customer') { $this->regenerateCustomerRange(); } else { $this->regenerateNumber(); } } public function updatedRangeFromPart1(): void { $this->updateRangeFrom(); } public function updatedRangeFromPart2(): void { $this->updateRangeFrom(); } public function updatedRangeFromPart3(): void { $this->updateRangeFrom(); } public function updatedRangeFromPart4(): void { $this->updateRangeFrom(); } public function updatedRangeToPart1(): void { $this->updateRangeTo(); } public function updatedRangeToPart2(): void { $this->updateRangeTo(); } public function updatedRangeToPart3(): void { $this->updateRangeTo(); } public function updatedRangeToPart4(): void { $this->updateRangeTo(); } protected function updateRangeFrom(): void { $this->rangeFrom = trim($this->rangeFromPart1 . ' ' . $this->rangeFromPart2 . ' ' . $this->rangeFromPart3 . ' ' . $this->rangeFromPart4); } protected function updateRangeTo(): void { $this->rangeTo = trim($this->rangeToPart1 . ' ' . $this->rangeToPart2 . ' ' . $this->rangeToPart3 . ' ' . $this->rangeToPart4); } public function updatedCustomerBrokerType(): void { $this->brokerPartnerId = null; } public function regenerateNumber(): void { $number = $this->getNextAvailableNumber(); $this->codePart1 = substr($number, 0, 2); $this->codePart2 = substr($number, 2, 2); $this->codePart3 = substr($number, 4, 2); $this->codePart4 = substr($number, 6, 2); } public function regenerateCustomerRange(): void { $fromNumber = $this->getNextAvailableNumber(); // Setze "Code von" Parts $this->rangeFromPart1 = substr($fromNumber, 0, 2); $this->rangeFromPart2 = substr($fromNumber, 2, 2); $this->rangeFromPart3 = substr($fromNumber, 4, 2); $this->rangeFromPart4 = substr($fromNumber, 6, 2); // Berechne "Code bis" (+10) $fromNumberInt = (int) $fromNumber; $toNumberInt = $fromNumberInt + 10; $toNumber = str_pad((string) $toNumberInt, 8, '0', STR_PAD_LEFT); // Setze "Code bis" Parts $this->rangeToPart1 = substr($toNumber, 0, 2); $this->rangeToPart2 = substr($toNumber, 2, 2); $this->rangeToPart3 = substr($toNumber, 4, 2); $this->rangeToPart4 = substr($toNumber, 6, 2); // Aktualisiere rangeFrom und rangeTo $this->updateRangeFrom(); $this->updateRangeTo(); } public function updatedCodePart1(): void { $this->validateNumberUniqueness(); } public function updatedCodePart2(): void { $this->validateNumberUniqueness(); } public function updatedCodePart3(): void { $this->validateNumberUniqueness(); } public function updatedCodePart4(): void { $this->validateNumberUniqueness(); } protected function validateNumberUniqueness(): void { // Prüfe nur wenn alle Teile ausgefüllt sind if (strlen($this->codePart1) < 2 || strlen($this->codePart2) < 2 || strlen($this->codePart3) < 2 || strlen($this->codePart4) < 2) { $this->resetErrorBag(['codePart1', 'codePart2', 'codePart3', 'codePart4']); return; } $number = $this->normalizeNumber($this->codePart1 . $this->codePart2 . $this->codePart3 . $this->codePart4); // Prüfe ob diese Nummer bereits verwendet wird (unabhängig von Prefix/Rolle) $exists = RegistrationCode::whereRaw('SUBSTRING(code, 2) = ?', [$number])->exists(); if ($exists) { $this->addError('codePart1', __('Diese Nummer wird bereits verwendet. Jede Nummer ist einzigartig über alle Rollen hinweg.')); } else { $this->resetErrorBag(['codePart1', 'codePart2', 'codePart3', 'codePart4']); } } public function createCode(): void { $prefix = $this->normalizedPrefix(); // Range-Modus für Kunden (immer) if ($this->role === 'customer') { $this->createCodeRange($prefix); return; } // Einzelner Code $number = $this->normalizeNumber($this->codePart1 . $this->codePart2 . $this->codePart3 . $this->codePart4); $fullCode = $prefix . $number; $this->validate($this->rules($prefix), $this->messages()); // Prüfe auf doppelten Code (Nummer unabhängig von Prefix/Rolle) $numberExists = RegistrationCode::whereRaw('SUBSTRING(code, 2) = ?', [$number])->exists(); if ($numberExists) { $this->addError('codePart1', __('Diese Nummer wird bereits verwendet. Jede Nummer ist einzigartig über alle Rollen hinweg.')); return; } // Aktualisiere die Teile für die Anzeige $this->codePart1 = substr($number, 0, 2); $this->codePart2 = substr($number, 2, 2); $this->codePart3 = substr($number, 4, 2); $this->codePart4 = substr($number, 6, 2); $metadata = []; if ($this->note) { $metadata['note'] = $this->note; } RegistrationCode::create([ 'code' => $fullCode, 'role' => $this->role, 'name' => in_array($this->role, ['broker', 'retailer', 'manufacturer'], true) ? $this->name : null, 'status' => RegistrationCode::STATUS_AVAILABLE, 'broker_partner_id' => null, 'partner_id' => null, 'assigned_to_code_id' => $this->role === 'customer' ? $this->brokerPartnerId : null, 'expires_at' => $this->expiresAt ? Carbon::parse($this->expiresAt)->endOfDay() : null, 'metadata' => !empty($metadata) ? $metadata : null, ]); Flux::toast( heading: 'Success!', text: 'Registrierungscode wurde angelegt.', variant: 'success', position: "top end", duration: 3000 ); $this->reset(['name', 'brokerPartnerId', 'expiresAt', 'note', 'rangeFrom', 'rangeTo', 'rangeFromPart1', 'rangeFromPart2', 'rangeFromPart3', 'rangeFromPart4', 'rangeToPart1', 'rangeToPart2', 'rangeToPart3', 'rangeToPart4']); $this->codePrefix = $this->roleOptions[$this->role]['prefix']; $this->expiresAt = now()->addDays(7)->format('Y-m-d'); $this->regenerateNumber(); } protected function createCodeRange(string $prefix): void { // Aktualisiere rangeFrom und rangeTo aus den Parts $this->updateRangeFrom(); $this->updateRangeTo(); $this->validate([ 'rangeFromPart1' => ['required', 'digits:2'], 'rangeFromPart2' => ['required', 'digits:2'], 'rangeFromPart3' => ['required', 'digits:2'], 'rangeFromPart4' => ['required', 'digits:2'], 'rangeToPart1' => ['required', 'digits:2'], 'rangeToPart2' => ['required', 'digits:2'], 'rangeToPart3' => ['required', 'digits:2'], 'rangeToPart4' => ['required', 'digits:2'], 'brokerPartnerId' => ['required', 'exists:registration_codes,id'], ], [ 'rangeFromPart1.required' => __('Bitte geben Sie den Startwert der Range ein.'), 'rangeFromPart1.digits' => __('Bitte genau 2 Ziffern eingeben.'), 'rangeFromPart2.required' => __('Bitte geben Sie den Startwert der Range ein.'), 'rangeFromPart2.digits' => __('Bitte genau 2 Ziffern eingeben.'), 'rangeFromPart3.required' => __('Bitte geben Sie den Startwert der Range ein.'), 'rangeFromPart3.digits' => __('Bitte genau 2 Ziffern eingeben.'), 'rangeFromPart4.required' => __('Bitte geben Sie den Startwert der Range ein.'), 'rangeFromPart4.digits' => __('Bitte genau 2 Ziffern eingeben.'), 'rangeToPart1.required' => __('Bitte geben Sie den Endwert der Range ein.'), 'rangeToPart1.digits' => __('Bitte genau 2 Ziffern eingeben.'), 'rangeToPart2.required' => __('Bitte geben Sie den Endwert der Range ein.'), 'rangeToPart2.digits' => __('Bitte genau 2 Ziffern eingeben.'), 'rangeToPart3.required' => __('Bitte geben Sie den Endwert der Range ein.'), 'rangeToPart3.digits' => __('Bitte genau 2 Ziffern eingeben.'), 'rangeToPart4.required' => __('Bitte geben Sie den Endwert der Range ein.'), 'rangeToPart4.digits' => __('Bitte genau 2 Ziffern eingeben.'), 'brokerPartnerId.required' => __('Bitte wählen Sie einen Makler oder Händler aus.'), ]); // Normalisiere die Eingabe (zusammenfügen der Parts) $fromNumberStr = $this->normalizeNumber($this->rangeFromPart1 . $this->rangeFromPart2 . $this->rangeFromPart3 . $this->rangeFromPart4); $toNumberStr = $this->normalizeNumber($this->rangeToPart1 . $this->rangeToPart2 . $this->rangeToPart3 . $this->rangeToPart4); // Validiere Format (8 Ziffern) if (!preg_match('/^\d{8}$/', $fromNumberStr)) { $this->addError('rangeFrom', __('Format: 40 00 00 01 (8 Ziffern)')); return; } if (!preg_match('/^\d{8}$/', $toNumberStr)) { $this->addError('rangeTo', __('Format: 40 00 00 50 (8 Ziffern)')); return; } $fromNumber = (int) $fromNumberStr; $toNumber = (int) $toNumberStr; if ($fromNumber >= $toNumber) { $this->addError('rangeFrom', __('Der Startwert muss kleiner als der Endwert sein.')); return; } if (($toNumber - $fromNumber) > 1000) { $this->addError('rangeTo', __('Die Range darf maximal 1000 Codes umfassen.')); return; } $created = 0; $skipped = 0; for ($num = $fromNumber; $num <= $toNumber; $num++) { $numberStr = str_pad((string) $num, 8, '0', STR_PAD_LEFT); $fullCode = $prefix . $numberStr; // Prüfe ob bereits vorhanden if (RegistrationCode::whereRaw('SUBSTRING(code, 2) = ?', [$numberStr])->exists()) { $skipped++; continue; } $metadata = []; if ($this->note) { $metadata['note'] = $this->note; } RegistrationCode::create([ 'code' => $fullCode, 'role' => $this->role, 'name' => null, 'status' => RegistrationCode::STATUS_AVAILABLE, 'broker_partner_id' => null, 'partner_id' => null, 'assigned_to_code_id' => $this->brokerPartnerId, 'expires_at' => $this->expiresAt ? Carbon::parse($this->expiresAt)->endOfDay() : null, 'metadata' => !empty($metadata) ? $metadata : null, ]); $created++; } Flux::toast( heading: 'Success!', text: __(':created Codes wurden angelegt. :skipped wurden übersprungen (bereits vorhanden).', ['created' => $created, 'skipped' => $skipped]), variant: 'success', position: "top end", duration: 3000 ); $this->reset(['brokerPartnerId', 'expiresAt', 'note', 'rangeFrom', 'rangeTo', 'rangeFromPart1', 'rangeFromPart2', 'rangeFromPart3', 'rangeFromPart4', 'rangeToPart1', 'rangeToPart2', 'rangeToPart3', 'rangeToPart4']); $this->expiresAt = now()->addDays(7)->format('Y-m-d'); if ($this->role === 'customer') { $this->regenerateCustomerRange(); } else { $this->regenerateNumber(); } } public function expire(int $codeId): void { /** @var RegistrationCode|null $code */ $code = RegistrationCode::find($codeId); if (!$code) { return; } if ($code->status === RegistrationCode::STATUS_USED) { $this->addError('code', __('Dieser Code wurde bereits genutzt und kann nicht deaktiviert werden.')); return; } $code->update([ 'status' => RegistrationCode::STATUS_EXPIRED, 'expires_at' => $code->expires_at ?? now(), ]); session()->flash('message', __('Code wurde deaktiviert.')); } protected function rules(string $prefix): array { $rules = [ 'role' => ['required', Rule::in(array_keys($this->roleOptions))], 'codePrefix' => ['required', 'alpha', 'size:1'], 'name' => [ Rule::requiredIf(in_array($this->role, ['broker', 'retailer', 'manufacturer'], true)), 'nullable', 'string', 'max:255', ], 'expiresAt' => ['nullable', 'date'], 'note' => ['nullable', 'string', 'max:255'], ]; // Für Kunden gelten Range-Regeln if ($this->role === 'customer') { $rules['rangeFromPart1'] = ['required', 'digits:2']; $rules['rangeFromPart2'] = ['required', 'digits:2']; $rules['rangeFromPart3'] = ['required', 'digits:2']; $rules['rangeFromPart4'] = ['required', 'digits:2']; $rules['rangeToPart1'] = ['required', 'digits:2']; $rules['rangeToPart2'] = ['required', 'digits:2']; $rules['rangeToPart3'] = ['required', 'digits:2']; $rules['rangeToPart4'] = ['required', 'digits:2']; $rules['brokerPartnerId'] = ['required', 'exists:registration_codes,id']; } else { // Normale Code-Felder für andere Rollen $rules['codePart1'] = ['required', 'digits:2']; $rules['codePart2'] = ['required', 'digits:2']; $rules['codePart3'] = ['required', 'digits:2']; $rules['codePart4'] = ['required', 'digits:2']; } return $rules; } protected function messages(): array { return [ 'role.required' => __('Bitte Rolle wählen.'), 'codePrefix.required' => __('Prefix ist erforderlich.'), 'codePrefix.alpha' => __('Prefix darf nur Buchstaben enthalten.'), 'codePrefix.size' => __('Prefix muss genau 1 Zeichen lang sein.'), 'codePart1.required' => __('Erster Block ist erforderlich.'), 'codePart1.digits' => __('Bitte genau 2 Ziffern eingeben.'), 'codePart2.required' => __('Zweiter Block ist erforderlich.'), 'codePart2.digits' => __('Bitte genau 2 Ziffern eingeben.'), 'codePart3.required' => __('Dritter Block ist erforderlich.'), 'codePart3.digits' => __('Bitte genau 2 Ziffern eingeben.'), 'codePart4.required' => __('Vierter Block ist erforderlich.'), 'codePart4.digits' => __('Bitte genau 2 Ziffern eingeben.'), 'name.required' => __('Für Makler-, Händler- und Herstellercodes ist ein Name erforderlich.'), 'name.max' => __('Der Name darf maximal 255 Zeichen lang sein.'), 'brokerPartnerId.required' => __('Für Kundencodes muss ein Makler oder Händler gewählt werden.'), 'brokerPartnerId.exists' => __('Bitte einen gültigen Makler- oder Händlercode auswählen.'), 'expiresAt.date' => __('Bitte ein gültiges Datum wählen.'), 'note.max' => __('Notiz darf max. 255 Zeichen lang sein.'), ]; } protected function normalizedPrefix(): string { $prefix = strtoupper(trim($this->codePrefix)); if ($prefix === '') { $prefix = $this->roleOptions[$this->role]['prefix'] ?? 'X'; } return substr($prefix, 0, 1); } protected function normalizeNumber(string $number): string { $digits = preg_replace('/\D+/', '', $number); $digits = str_pad(substr($digits, 0, 8), 8, '0', STR_PAD_LEFT); return $digits; } protected function getNextAvailableNumber(): string { $startNumber = $this->roleOptions[$this->role]['startNumber'] ?? '10000001'; $currentNumber = (int) $startNumber; // Finde die nächste verfügbare Nummer im Bereich dieser Rolle $maxAttempts = 10000; // Sicherheitslimit $attempts = 0; while ($attempts < $maxAttempts) { $numberStr = str_pad((string) $currentNumber, 8, '0', STR_PAD_LEFT); // Prüfe ob diese Nummer bereits verwendet wird (unabhängig von Prefix/Rolle) $exists = RegistrationCode::whereRaw('SUBSTRING(code, 2) = ?', [$numberStr])->exists(); if (!$exists) { return $numberStr; } $currentNumber++; $attempts++; } // Fallback: zufällige Nummer wenn Bereich voll ist return $this->generateRandomUniqueNumber(); } protected function generateRandomUniqueNumber(): string { $attempts = 0; do { $attempts++; $number = str_pad((string) random_int(10000000, 99999999), 8, '0', STR_PAD_LEFT); $exists = RegistrationCode::whereRaw('SUBSTRING(code, 2) = ?', [$number])->exists(); } while ($exists && $attempts < 100); return $number; } public function getNextAvailableNumberForDisplay(): string { $number = $this->getNextAvailableNumber(); return substr($number, 0, 2) . ' ' . substr($number, 2, 2) . ' ' . substr($number, 4, 2) . ' ' . substr($number, 6, 2); } public function sortBy(string $field): void { if ($this->sortField === $field) { $this->sortDirection = $this->sortDirection === 'asc' ? 'desc' : 'asc'; } else { $this->sortField = $field; $this->sortDirection = 'asc'; } } public function updatingSearch(): void { $this->resetPage(); } public function updatingTableRoleFilter(): void { $this->resetPage(); } public function updatingTableStatusFilter(): void { $this->resetPage(); } public function updatingTableAssignmentFilter(): void { $this->resetPage(); } public function updatedTableRoleFilter(): void { // Reset assignment filter wenn Rolle geändert wird $this->tableAssignmentFilter = ''; $this->resetPage(); } public function with(): array { $stats = [ 'available' => RegistrationCode::where('status', RegistrationCode::STATUS_AVAILABLE)->count(), 'used' => RegistrationCode::where('status', RegistrationCode::STATUS_USED)->count(), 'expired' => RegistrationCode::where('status', RegistrationCode::STATUS_EXPIRED)->count(), ]; $recentCodes = RegistrationCode::with(['usedBy']) ->latest() ->take(25) ->get(); // Für Kunden: Filtere Codes basierend auf customerBrokerType $brokerAndRetailerCodes = RegistrationCode::whereIn('role', $this->role === 'customer' ? [$this->customerBrokerType] : ['broker', 'retailer']) ->where('status', RegistrationCode::STATUS_AVAILABLE) ->orderBy('code') ->get(); // Query für Tabelle mit Filtern und Sortierung $tableQuery = RegistrationCode::with(['usedBy', 'assignedToCode']) ->when($this->tableRoleFilter, fn($q) => $q->where('role', $this->tableRoleFilter)) ->when($this->tableStatusFilter, fn($q) => $q->where('status', $this->tableStatusFilter)) ->when($this->tableAssignmentFilter && $this->tableRoleFilter === 'customer', fn($q) => $q->where('assigned_to_code_id', $this->tableAssignmentFilter) ) ->when($this->search, fn($q) => $q->where(function($query) { $searchTerm = '%' . $this->search . '%'; $query->where('code', 'like', $searchTerm) ->orWhere('name', 'like', $searchTerm) ->orWhereHas('usedBy', fn($userQuery) => $userQuery->where('name', 'like', $searchTerm) ->orWhere('email', 'like', $searchTerm) ); }) ); $codes = $tableQuery->orderBy($this->sortField, $this->sortDirection)->paginate(25); // Finde alle Makler/Händler, die Kunden zugeordnet haben (mit neuer Spalte) $assignmentIds = RegistrationCode::where('role', 'customer') ->whereNotNull('assigned_to_code_id') ->distinct() ->pluck('assigned_to_code_id'); $availableAssignments = RegistrationCode::whereIn('id', $assignmentIds) ->whereIn('role', ['broker', 'retailer']) ->orderBy('code') ->get(); return [ 'stats' => $stats, 'recentCodes' => $recentCodes, 'roleOptions' => $this->roleOptions, 'nextAvailableNumber' => $this->getNextAvailableNumberForDisplay(), 'brokerAndRetailerCodes' => $brokerAndRetailerCodes, 'codes' => $codes, 'availableAssignments' => $availableAssignments ?? collect(), ]; } }; ?>
{{-- Header --}}
{{ __('Registrierungscodes') }} {{ __('Codes erzeugen, zuordnen und deaktivieren') }}
{{-- Statistik --}}
{{ __('Verfügbar') }} {{ $stats['available'] }}
{{ __('Verbraucht') }} {{ $stats['used'] }}
{{ __('Deaktiviert/abgelaufen') }} {{ $stats['expired'] }}
{{-- Formular --}}
{{ __('Neuen Code anlegen') }} {{ __('Rolle wählen, Nummer generieren, optional zuordnen') }}
{{ __('Rolle') }} @foreach($roleOptions as $key => $meta) {{ $meta['label'] }} — {{ $meta['description'] }} @endforeach @error('role') {{ $message }} @enderror @if($role === 'customer') {{-- Code von --}} {{ __('Code von') }}
|
@error('rangeFrom') {{ $message }} @enderror

{{ __('Format: Prefix + 4×2 Ziffern') }}

{{-- Code bis --}} {{ __('Code bis') }}
|
@error('rangeTo') {{ $message }} @enderror

{{ __('Format: Prefix + 4×2 Ziffern') }}

@else {{-- Normale Code-Eingabe für andere Rollen --}} {{ __('Code') }}
|
@error('codePrefix') {{ $message }} @enderror @error('codePart1') {{ $message }} @enderror @error('codePart2') {{ $message }} @enderror @error('codePart3') {{ $message }} @enderror @error('codePart4') {{ $message }} @enderror

{{ __('Format: Prefix + 4×2 Ziffern') }}

{{ __('Nächste:') }} {{ $nextAvailableNumber }}

@endif @if(in_array($role, ['broker', 'retailer', 'manufacturer'], true)) {{ __('Name') }} * @if($role === 'manufacturer') {{ __('Name des Herstellers') }} @else {{ __('Name für die Zuordnung von Kunden') }} @endif @error('name') {{ $message }} @enderror @endif @if($role === 'customer') {{ __('Makler oder Händler (Pflicht für Kundencodes)') }} {{ __('Wählen Sie zwischen Makler oder Händler und ordnen Sie dann einen Code zu') }} {{-- Tabs für Makler/Händler-Auswahl --}}
{{-- Zuordnung --}} {{ __('Zuordnen zu') }} {{ __('Bitte wählen') }} @foreach($brokerAndRetailerCodes as $code) @php $displayName = $code->name ?? $code->code; $roleLabel = $roleOptions[$code->role]['label'] ?? ucfirst($code->role); @endphp {{ $displayName }} ({{ $code->code }}) @endforeach @error('brokerPartnerId') {{ $message }} @enderror
@endif
{{ __('Ablaufdatum') }} @error('expiresAt') {{ $message }} @enderror {{ __('Notiz (optional)') }} @error('note') {{ $message }} @enderror
{{ __('Code speichern') }} {{ __('Speichern...') }}
{{-- Liste --}}
{{ __('Letzte Codes') }} {{ __('Zuletzt angelegte oder verbrauchte Codes') }}
@forelse($recentCodes as $code) @php $statusColor = match($code->status) { 'available' => 'green', 'used' => 'zinc', 'expired' => 'orange', default => 'zinc', }; $roleLabel = $roleOptions[$code->role]['label'] ?? ucfirst($code->role); @endphp
{{ $code->code }}
@if($code->name)
{{ __('Name:') }} {{ $code->name }}
@endif @if($code->role === 'customer' && $code->assignedToCode) @php $brokerName = $code->assignedToCode->name ?? $code->assignedToCode->code; $brokerRoleLabel = $roleOptions[$code->assignedToCode->role]['label'] ?? ucfirst($code->assignedToCode->role); @endphp
{{ __('Zugeordnet zu:') }} {{ $brokerRoleLabel }} {{ $brokerName }} ({{ $code->assignedToCode->code }})
@endif
@if($code->status === 'available') {{ __('Verfügbar') }} @elseif($code->status === 'used') {{ __('Verbraucht') }} @else {{ __('Abgelaufen') }} @endif {{ $roleLabel }}
@if($code->usedBy)
{{ __('Verbraucht von:') }} {{ $code->usedBy->name ?? $code->usedBy->email }} @if($code->used_at) ({{ $code->used_at->format('d.m.Y H:i') }}) @endif
@endif @if($code->metadata && isset($code->metadata['note']))
{{ $code->metadata['note'] }}
@endif
{{ __('Angelegt:') }} {{ $code->created_at->format('d.m.Y H:i') }} @if($code->expires_at)
{{ __('Gültig bis:') }} {{ $code->expires_at->format('d.m.Y H:i') }} @endif
@if($code->status === RegistrationCode::STATUS_AVAILABLE) {{ __('Deaktivieren') }} @endif
@empty
{{ __('Noch keine Codes angelegt') }}
@endforelse
{{-- Codes Tabelle --}}
{{ __('Alle Registrierungscodes') }} {{ __('Übersicht aller Codes mit Filtern und Sortierung') }}
{{-- Filter --}}
{{ __('Alle Rollen') }} @foreach($roleOptions as $key => $meta) {{ $meta['label'] }} @endforeach @if($tableRoleFilter === 'customer') {{ __('Alle Zuordnungen') }} @foreach($availableAssignments as $assignment) @php $assignmentName = $assignment->name ?? $assignment->code; $assignmentRoleLabel = $roleOptions[$assignment->role]['label'] ?? ucfirst($assignment->role); @endphp {{ $assignmentRoleLabel }}: {{ $assignmentName }} ({{ $assignment->code }}) @endforeach @endif {{ __('Alle Status') }} {{ __('Verfügbar') }} {{ __('Verbraucht') }} {{ __('Abgelaufen') }} @if($search || $tableRoleFilter || $tableStatusFilter || $tableAssignmentFilter) {{ __('Filter zurücksetzen') }} @endif
{{ __('Code') }} @if($sortField === 'code') @endif
{{ __('Rolle') }} @if($sortField === 'role') @endif
{{ __('Name') }}
{{ __('Status') }} @if($sortField === 'status') @endif
{{ __('Zuordnung') }}
{{ __('Angelegt') }} @if($sortField === 'created_at') @endif
{{ __('Aktionen') }}
@forelse($codes as $code) @php $statusColor = match($code->status) { 'available' => 'green', 'used' => 'zinc', 'expired' => 'orange', default => 'zinc', }; $roleLabel = $roleOptions[$code->role]['label'] ?? ucfirst($code->role); $name = $code->name; @endphp {{ $code->code }} {{ $roleLabel }} @if($name) {{ $name }} @else @endif @if($code->status === 'available') {{ __('Verfügbar') }} @elseif($code->status === 'used') {{ __('Verbraucht') }} @else {{ __('Abgelaufen') }} @endif @if($code->role === 'customer' && $code->assignedToCode) @php $brokerName = $code->assignedToCode->name ?? $code->assignedToCode->code; $brokerRoleLabel = $roleOptions[$code->assignedToCode->role]['label'] ?? ucfirst($code->assignedToCode->role); @endphp
{{ $brokerRoleLabel }}: {{ $brokerName }}
@elseif($code->usedBy)
{{ __('Verbraucht von:') }} {{ $code->usedBy->name ?? $code->usedBy->email }}
@else @endif
{{ $code->created_at->format('d.m.Y H:i') }}
@if($code->status === RegistrationCode::STATUS_AVAILABLE) {{ __('Deaktivieren') }} @endif
@empty
{{ __('Keine Codes gefunden') }} @if($search || $tableRoleFilter || $tableStatusFilter) {{ __('Versuchen Sie, Ihre Filter anzupassen.') }} @else {{ __('Erstellen Sie einen neuen Code, um zu beginnen.') }} @endif
@endforelse
{{-- Pagination --}}
{{ $codes->links() }}