function view_domains_index(array $app, array $domains): string { $canCreate = in_array($app['user']['role'] ?? '', ['admin', 'reseller', 'reseller_staff'], true); $showInternalPrice = in_array(($app['user']['role'] ?? ''), ['admin', 'reseller', 'reseller_staff'], true); $rows = ''; foreach ($domains as $domain) { $rows .= ' ' . app_h($domain['domain_name'] ?? '') . ' ' . app_h($domain['provider_status'] ?? '') . ' ' . app_h($domain['customer_name'] ?? '—') . ' ' . ((($app['user']['role'] ?? '') === 'admin') ? app_h($domain['reseller_name'] ?? '') : '—') . ' ' . app_h($domain['local_status'] ?? '') . ' ' . ($showInternalPrice ? '' . app_currency((float)($domain['reseller_price_net'] ?? 0)) . '' : '') . ' Öffnen '; } if ($rows === '') { $rows = '
Keine Domains gefunden.
'; } return app_layout($app, [ 'title' => 'Domains', 'content' => '

Domains

Alle zugeordneten Domains im Überblick.

' . ($canCreate ? 'Domain CheckDomain bestellen' : '') . '
' . ($showInternalPrice ? '' : '') . ' ' . $rows . '
Domain Kunde ' . (($app['user']['role'] ?? '') === 'admin' ? 'Reseller' : 'Zuordnung') . ' StatusPreis netto
', ]); } function view_domains_check(array $app, array $data = []): string { $error = $data['error'] ?? ''; $checkResult = $data['check_result'] ?? null; $suggestions = $data['suggestions'] ?? []; $domain = $data['domain'] ?? ''; $label = $data['label'] ?? ''; $resultHtml = ''; if (is_array($checkResult)) { if (!empty($checkResult['ok'])) { $available = !empty($checkResult['data']['available']); $resultHtml = '
Domain ' . app_h($domain) . ' ist ' . ($available ? 'verfügbar' : 'nicht verfügbar') . '.
'; } else { $resultHtml = '
' . app_h($checkResult['message'] ?? 'Fehler beim Domain-Check.') . '
'; } } $suggestRows = ''; foreach ($suggestions as $item) { $suggestRows .= ' ' . app_h((string)($item['domainName'] ?? $item['domain'] ?? '')) . ' ' . app_h((string)($item['status'] ?? '')) . ' '; } if ($suggestRows === '') { $suggestRows = '
Keine Vorschläge vorhanden.
'; } return app_layout($app, [ 'title' => 'Domain Check', 'content' => '

Domain Check

Domain prüfen und Alternativen anzeigen.

' . ($error ? '
' . app_h($error) . '
' : '') . ' ' . $resultHtml . '

Vorschläge

' . $suggestRows . '
Domain Status
', ]); } function view_domains_create(array $app, array $data = []): string { $error = $data['error'] ?? ''; $customers = $data['customers'] ?? []; $handles = $data['handles'] ?? []; $profiles = $data['nameserver_profiles'] ?? []; $customerOptions = ''; foreach ($customers as $customer) { $customerOptions .= ''; } $handleOptions = ''; foreach ($handles as $handle) { $label = trim(((string)($handle['organisation'] ?? '')) . ' ' . ((string)($handle['first_name'] ?? '')) . ' ' . ((string)($handle['last_name'] ?? ''))); $handleOptions .= ''; } $profileOptions = ''; foreach ($profiles as $profile) { $profileOptions .= ''; } return app_layout($app, [ 'title' => 'Domain bestellen', 'content' => '

Domain bestellen

Neue Domain für einen Kunden bestellen.

' . ($error ? '
' . app_h($error) . '
' : '') . '
', ]); } function view_domains_show(array $app, array $data): string { $domain = $data['domain']; $zone = $data['zone'] ?? null; $customers = $data['customers'] ?? []; $handles = $data['handles'] ?? []; $profiles = $data['nameserver_profiles'] ?? []; $customerOptions = ''; foreach ($customers as $customer) { $selected = ((int)($domain['customer_id'] ?? 0) === (int)$customer['id']) ? ' selected' : ''; $customerOptions .= ''; } $profileOptions = ''; foreach ($profiles as $profile) { $selected = ((int)($domain['nameserver_profile_id'] ?? 0) === (int)$profile['id']) ? ' selected' : ''; $profileOptions .= ''; } $recordRows = ''; foreach (($zone['records'] ?? []) as $record) { $recordRows .= ' ' . app_h($record['rr_name'] ?? '') . ' ' . app_h($record['rr_type'] ?? '') . ' ' . app_h($record['rr_content'] ?? '') . ' ' . app_h((string)($record['rr_ttl'] ?? '')) . '
'; } if ($recordRows === '') { $recordRows = '
Keine DNS Records vorhanden.
'; } return app_layout($app, [ 'title' => 'Domain', 'content' => '

' . app_h($domain['domain_name']) . '

' . app_h($domain['customer_name'] ?? 'Nicht zugeordnet') . '

' . dashboard_stat_card('Status', app_h((string)$domain['local_status']), 'Lokaler Status', icon_status()) . ' ' . dashboard_stat_card('Provider', app_h((string)($domain['provider_status'] ?? '')), 'Provider Status', icon_domain()) . ' ' . dashboard_stat_card('Preis netto', app_currency((float)($domain['reseller_price_net'] ?? 0)), 'Hinterlegter Preis', icon_price()) . '

Stammdaten

Domain
' . app_h($domain['domain_name']) . '
TLD
' . app_h($domain['tld'] ?? '') . '
Auto Renew
' . ((int)($domain['auto_renew'] ?? 0) === 1 ? 'Ja' : 'Nein') . '
Expire
' . app_h($domain['expires_at'] ?? '') . '
AuthInfo
' . app_h($domain['auth_code_masked'] ?? '') . '

Kundenzuordnung

Domain Update

DNS

DNS Ansicht öffnen
' . $recordRows . '
Name Typ Content TTL

DNS Record anlegen

', ]); } function view_handles_index(array $app, array $handles): string { $rows = ''; foreach ($handles as $handle) { $display = trim(((string)($handle['organisation'] ?? '')) . ' ' . ((string)($handle['first_name'] ?? '')) . ' ' . ((string)($handle['last_name'] ?? ''))); $rows .= ' ' . app_h($display !== '' ? $display : (string)$handle['external_handle_id']) . ' ' . app_h($handle['email'] ?? '') . ' ' . app_h($handle['handle_type'] ?? '') . ' ' . app_h($handle['customer_name'] ?? '—') . ' Öffnen '; } if ($rows === '') { $rows = '
Keine Handles gefunden.
'; } return app_layout($app, [ 'title' => 'Handles', 'content' => '

Handles

Kontakte und Inhaber-Handles verwalten.

' . $rows . '
Handle Typ Kunde
', ]); } function view_handles_create(array $app, array $data = []): string { $error = $data['error'] ?? ''; $customers = $data['customers'] ?? []; $customerOptions = ''; foreach ($customers as $customer) { $customerOptions .= ''; } return app_layout($app, [ 'title' => 'Handle anlegen', 'content' => '

Handle anlegen

Neues Handle im Resellerkonto anlegen.

' . ($error ? '
' . app_h($error) . '
' : '') . '
', ]); } function view_handles_show(array $app, array $data): string { $handle = $data['handle']; $customers = $data['customers'] ?? []; $customerOptions = ''; foreach ($customers as $customer) { $selected = ((int)($handle['customer_id'] ?? 0) === (int)$customer['id']) ? ' selected' : ''; $customerOptions .= ''; } return app_layout($app, [ 'title' => 'Handle', 'content' => '

' . app_h($handle['external_handle_id']) . '

Handle bearbeiten und Kundenzuordnung pflegen.

', ]); } function view_dns_show(array $app, array $data): string { $domain = $data['domain']; $zone = $data['zone'] ?? null; $rows = ''; foreach (($zone['records'] ?? []) as $record) { $rows .= ' ' . app_h($record['rr_name'] ?? '') . ' ' . app_h($record['rr_type'] ?? '') . ' ' . app_h($record['rr_content'] ?? '') . ' ' . app_h((string)($record['rr_ttl'] ?? '')) . ' '; } if ($rows === '') { $rows = '
Keine DNS Daten vorhanden.
'; } return app_layout($app, [ 'title' => 'DNS', 'content' => '

DNS · ' . app_h($domain['domain_name']) . '

Zone und Resource Records.

Zone

Origin
' . app_h($zone['soa_origin'] ?? $domain['domain_name']) . '
Provider Serial
' . app_h($zone['provider_serial'] ?? '') . '
Letzter Sync
' . app_h($zone['last_synced_at'] ?? '') . '

Records

' . $rows . '
Name Typ Content TTL
', ]); } function view_price_list_index(array $app, array $data): string { $prices = $data['prices'] ?? []; $resellerId = (int)($data['reseller_id'] ?? 0); $resellers = $data['resellers'] ?? []; $resellerOptions = ''; foreach ($resellers as $reseller) { $selected = $resellerId === (int)$reseller['id'] ? ' selected' : ''; $resellerOptions .= ''; } $rows = ''; foreach ($prices as $price) { $key = $price['tld'] . '|' . $price['action_code']; $rows .= ' ' . app_h($price['tld']) . ' ' . app_h($price['action_code']) . ' '; } if ($rows === '') { $rows = '
Keine Preise vorhanden.
'; } return app_layout($app, [ 'title' => 'Preisliste', 'content' => '

Preisliste

TLD Preise und Markups pflegen.

' . (($app['user']['role'] ?? '') === 'admin' ? '
' : '') . '
' . (($app['user']['role'] ?? '') === 'admin' ? '' : '') . '
' . (($app['user']['role'] ?? '') === 'admin' ? '' : '') . '
' . $rows . '
TLD Aktion Supplier netto Markup Typ Markup Wert Reseller netto
', ]); } function view_billing_index(array $app, array $data): string { $resellers = $data['resellers'] ?? []; $runs = $data['runs'] ?? []; $selectedResellerId = (int)($data['selected_reseller_id'] ?? 0); $selectedYear = (int)($data['selected_year'] ?? date('Y')); $selectedMonth = (int)($data['selected_month'] ?? date('n')); $resellerOptions = ''; foreach ($resellers as $reseller) { $selected = $selectedResellerId === (int)$reseller['id'] ? ' selected' : ''; $resellerOptions .= ''; } $runRows = ''; foreach ($runs as $run) { $runRows .= ' ' . app_h($run['reseller_name']) . ' ' . app_h((string)$run['billing_month']) . '/' . app_h((string)$run['billing_year']) . ' ' . app_currency((float)$run['total_net']) . ' ' . app_currency((float)$run['total_gross']) . ' ' . app_h($run['status']) . ' Öffnen '; } if ($runRows === '') { $runRows = '
Keine Abrechnungsläufe gefunden.
'; } return app_layout($app, [ 'title' => 'Buchhaltung', 'content' => '

Buchhaltung

Monatsläufe je Reseller.

Filtern

Abrechnungslauf erstellen

Abrechnungsläufe

' . $runRows . '
Reseller Monat Netto Brutto Status
', ]); } function view_billing_show(array $app, array $data): string { $run = $data['run']; $customers = $data['customers'] ?? []; $rows = ''; foreach ($customers as $customer) { $rows .= ' ' . app_h($customer['customer_name'] ?? '—') . ' ' . app_h((string)($customer['domain_count'] ?? 0)) . ' ' . app_currency((float)$customer['total_net']) . ' ' . app_currency((float)$customer['total_gross']) . ' Details '; } if ($rows === '') { $rows = '
Keine Kundenpositionen vorhanden.
'; } return app_layout($app, [ 'title' => 'Abrechnung', 'content' => '

' . app_h($run['reseller_name']) . '

Abrechnung ' . app_h((string)$run['billing_month']) . '/' . app_h((string)$run['billing_year']) . '

' . dashboard_stat_card('Netto', app_currency((float)$run['total_net']), 'Summe netto', icon_price()) . ' ' . dashboard_stat_card('MwSt', app_currency((float)$run['total_vat']), 'Steuer', icon_receipt()) . ' ' . dashboard_stat_card('Brutto', app_currency((float)$run['total_gross']), 'Summe brutto', icon_receipt()) . ' ' . dashboard_stat_card('Status', app_h($run['status']), 'Laufstatus', icon_status()) . '

Metadaten

Kundenpositionen

' . $rows . '
Kunde Domains Netto Brutto
', ]); } function view_billing_customer_show(array $app, array $data): string { $run = $data['run']; $positions = $data['positions'] ?? []; $customerName = $positions[0]['customer_name'] ?? 'Kunde'; $rows = ''; foreach ($positions as $position) { $rows .= ' ' . app_h($position['domain_name'] ?? '') . ' ' . app_h($position['line_type'] ?? '') . ' ' . app_h((string)($position['quantity'] ?? 0)) . ' ' . app_currency((float)($position['line_net'] ?? 0)) . ' ' . app_currency((float)($position['line_gross'] ?? 0)) . ' '; } if ($rows === '') { $rows = '
Keine Detailpositionen vorhanden.
'; } return app_layout($app, [ 'title' => 'Abrechnungsdetails', 'content' => '

' . app_h($customerName) . '

Details zur Abrechnung ' . app_h((string)$run['billing_month']) . '/' . app_h((string)$run['billing_year']) . '

Detailpositionen

' . $rows . '
Domain Typ Menge Netto Brutto
', ]); } function view_reseller_billing_index(array $app, array $data): string { $runs = $data['runs'] ?? []; $domains = $data['domains'] ?? []; $runRows = ''; foreach ($runs as $run) { $runRows .= ' ' . app_h((string)$run['billing_month']) . '/' . app_h((string)$run['billing_year']) . ' ' . app_currency((float)$run['total_net']) . ' ' . app_currency((float)$run['total_gross']) . ' ' . app_h($run['status']) . ' Öffnen '; } if ($runRows === '') { $runRows = '
Keine Abrechnungen vorhanden.
'; } $domainRows = ''; foreach ($domains as $domain) { $domainRows .= ' ' . app_h($domain['domain_name'] ?? '') . ' ' . app_h($domain['customer_name'] ?? '') . ' ' . app_currency((float)($domain['reseller_price_net'] ?? 0)) . ' ' . app_h($domain['local_status'] ?? '') . ' '; } if ($domainRows === '') { $domainRows = '
Keine Domains vorhanden.
'; } return app_layout($app, [ 'title' => 'Buchhaltung', 'content' => '

Buchhaltung

Deine Abrechnungen und aktuelle Domains.

Abrechnungen

' . $runRows . '
Monat Netto Brutto Status

Aktuelle Domains

' . $domainRows . '
Domain Kunde Preis netto Status
', ]); } function view_reseller_billing_show(array $app, array $data): string { $run = $data['run']; $customers = $data['customers'] ?? []; $rows = ''; foreach ($customers as $customer) { $rows .= ' ' . app_h($customer['customer_name'] ?? '—') . ' ' . app_h((string)($customer['domain_count'] ?? 0)) . ' ' . app_currency((float)$customer['total_net']) . ' ' . app_currency((float)$customer['total_gross']) . ' Details '; } if ($rows === '') { $rows = '
Keine Kundenpositionen vorhanden.
'; } return app_layout($app, [ 'title' => 'Abrechnung', 'content' => '

Abrechnung ' . app_h((string)$run['billing_month']) . '/' . app_h((string)$run['billing_year']) . '

' . dashboard_stat_card('Netto', app_currency((float)$run['total_net']), 'Summe netto', icon_price()) . ' ' . dashboard_stat_card('MwSt', app_currency((float)$run['total_vat']), 'Steuer', icon_receipt()) . ' ' . dashboard_stat_card('Brutto', app_currency((float)$run['total_gross']), 'Summe brutto', icon_receipt()) . '

Kundenpositionen

' . $rows . '
Kunde Domains Netto Brutto
', ]); } function view_reseller_billing_customer_show(array $app, array $data): string { $run = $data['run']; $positions = $data['positions'] ?? []; $customerName = $positions[0]['customer_name'] ?? 'Kunde'; $rows = ''; foreach ($positions as $position) { $rows .= ' ' . app_h($position['domain_name'] ?? '') . ' ' . app_h($position['line_type'] ?? '') . ' ' . app_h((string)($position['quantity'] ?? 0)) . ' ' . app_currency((float)($position['line_net'] ?? 0)) . ' ' . app_currency((float)($position['line_gross'] ?? 0)) . ' '; } if ($rows === '') { $rows = '
Keine Detailpositionen vorhanden.
'; } return app_layout($app, [ 'title' => 'Abrechnungsdetails', 'content' => '

' . app_h($customerName) . '

Details zur Abrechnung ' . app_h((string)$run['billing_month']) . '/' . app_h((string)$run['billing_year']) . '

Detailpositionen

' . $rows . '
Domain Typ Menge Netto Brutto
', ]); } function view_account_index(array $app, array $data = []): string { $user = $app['user']; $error = $data['error'] ?? ''; return app_layout($app, [ 'title' => 'Konto', 'content' => '

Konto

Passwort und Basisdaten.

Profil

Name
' . app_h($user['display_name'] ?? '') . '
E-Mail
' . app_h($user['email'] ?? '') . '
Rolle
' . app_h(role_label($app, $user['role'] ?? '')) . '

Passwort ändern

' . ($error ? '
' . app_h($error) . '
' : '') . '
', ]); } /* -------------------- Helpers -------------------- */ function dashboard_stat_card(string $label, string $value, string $meta, string $icon, bool $raw = false, string $overrideValue = ''): string { $valueHtml = $raw ? $overrideValue : app_h($value); return '
' . app_h($label) . '
' . $valueHtml . '
' . $icon . '
' . app_h($meta) . '
'; } function dashboard_customers_card(array $app, array $customers): string { $rows = ''; $isAdmin = ($app['user']['role'] ?? '') === 'admin'; foreach (array_slice($customers, 0, 6) as $customer) { $rows .= ' ' . app_h($customer['name'] ?? '') . ' ' . app_h($customer['email'] ?? '') . ' ' . ($isAdmin ? '' . app_h($customer['reseller_name'] ?? '') . '' : '') . ' '; } if ($rows === '') { $rows = '
Keine Kunden vorhanden.
'; } return '

Letzte Kunden

' . ($isAdmin ? '' : '') . '' . $rows . '
KundeReseller
'; } function dashboard_domains_card(array $app, array $domains): string { $rows = ''; $isAdmin = ($app['user']['role'] ?? '') === 'admin'; foreach (array_slice($domains, 0, 6) as $domain) { $rows .= ' ' . app_h($domain['domain_name'] ?? '') . ' ' . app_h($domain['local_status'] ?? '') . ' ' . app_h($domain['customer_name'] ?? '') . ' ' . ($isAdmin ? '' . app_h($domain['reseller_name'] ?? '') . '' : '') . ' '; } if ($rows === '') { $rows = '
Keine Domains vorhanden.
'; } return '

Letzte Domains

' . ($isAdmin ? '' : '') . '' . $rows . '
DomainKundeReseller
'; } function billing_status_options(string $current): string { $items = ['open', 'reviewed', 'exported', 'closed']; $html = ''; foreach ($items as $item) { $selected = $current === $item ? ' selected' : ''; $html .= ''; } return $html; } function handle_type_options(string $current): string { $items = ['owner', 'admin', 'tech', 'billing', 'zone', 'other']; $html = ''; foreach ($items as $item) { $selected = $current === $item ? ' selected' : ''; $html .= ''; } return $html; } function role_label(array $app, string $role): string { return $app['config']['roles'][$role] ?? ucfirst($role); } /* -------------------- Icons -------------------- */ function icon_wrap(string $path): string { return ''; } function icon_home(): string { return icon_wrap(''); } function icon_users(): string { return icon_wrap(''); } function icon_user_card(): string { return icon_wrap(''); } function icon_price(): string { return icon_wrap(''); } function icon_settings(): string { return icon_wrap(''); } function icon_status(): string { return icon_wrap(''); } function icon_search(): string { return icon_wrap(''); } function icon_menu(): string { return icon_wrap(''); } function icon_receipt(): string { return icon_wrap(''); } function icon_domain(): string { return icon_wrap(''); } function icon_id(): string { return icon_wrap(''); }
Warning: Cannot modify header information - headers already sent by (output started at /var/www/vhosts/domains.myhostpanel.de/httpdocs/views.php:1) in /var/www/vhosts/domains.myhostpanel.de/httpdocs/app.php on line 252