@php
$money = fn (?int $cents, string $currency = 'EUR') => $cents === null
? '—'
: Number::currency($cents / 100, in: $currency, locale: app()->getLocale());
$date = fn ($value) => $value === null ? '—' : $value->local()->isoFormat('D. MMM YYYY');
@endphp
{{-- ── Who, at a glance ─────────────────────────────────────────────────
The four things somebody on the phone needs before they say anything:
who it is, whether the account is live, what they are on, and whether
the machine is running. --}}
{{-- ── The tabs ─────────────────────────────────────────────────────────
Four different questions, and stacking them made a page nobody read to
the bottom. Writing is last, because it is what you do after reading.
The choice is in the query string, so a reload, a bookmark and the back
button all land where the operator was. --}}
@foreach ($tabs as $name)
$tab === $name,
'border-transparent text-muted hover:text-ink' => $tab !== $name,
])>
{{ __('customer_detail.tab.'.$name) }}
@if ($name === 'messages' && $openRequests > 0)
{{ $openRequests }}
@endif
@endforeach
{{-- ══ Stammdaten ═══════════════════════════════════════════════════════ --}}
@if ($tab === 'overview')
{{ __('customer_detail.identity') }}
@foreach ([
__('customer_detail.company') => $customer->name,
__('customer_detail.contact') => $customer->contact_name ?: '—',
__('customer_detail.email') => $customer->email,
__('customer_detail.phone') => $customer->phone ?: '—',
__('customer_detail.since') => $date($customer->created_at),
__('customer_detail.locale') => strtoupper((string) ($customer->locale ?: '—')),
] as $term => $value)
{{ $term }}
{{ $value }}
@endforeach
{{-- Whose money it is, in the tax sense. Consumer or business is
not cosmetic: it decides whether a withdrawal right exists
at all, and "nobody asked" is treated as consumer. --}}
{{ __('customer_detail.tax') }}
{{ __('customer_detail.type') }}
@if ($customer->hasRecordedType())
{{ __('customer_detail.type_'.$customer->customer_type) }}
@else
{{ __('customer_detail.type_unknown') }}
@endif
{{ __('customer_detail.vat_id') }}
{{ $customer->vat_id ?: '—' }}
@if ($customer->vat_id && $customer->hasVerifiedVatId())
{{ __('customer_detail.verified') }}
@elseif ($customer->vat_id)
{{ __('customer_detail.unverified') }}
@endif
{{ __('customer_detail.stripe') }}
{{ $customer->stripe_customer_id ?: '—' }}
{{ __('customer_detail.address') }}
{{ $customer->billing_address ?: __('customer_detail.no_address') }}
@endif
{{-- ══ Paket & Maschine ═════════════════════════════════════════════════ --}}
@if ($tab === 'package')
@if ($subscription === null)
{{ __('customer_detail.no_contract') }}
@else
{{ __('billing.plan.'.$subscription->plan) }}
{{ $subscription->status }}
{{-- The contract's OWN frozen figures, not today's catalogue:
this is what the customer is owed, and a price rise does
not reach back into it. --}}
@foreach ([
__('customer_detail.price') => $money($subscription->price_cents, $subscription->currency).' '.__('customer_detail.net_per', ['term' => __('customer_detail.term_'.$subscription->term)]),
__('customer_detail.quota') => $subscription->quota_gb.' GB',
__('customer_detail.traffic') => $subscription->traffic_gb.' GB',
__('customer_detail.seats') => $subscription->seats,
__('customer_detail.started') => $date($subscription->started_at),
__('customer_detail.period_end') => $date($subscription->current_period_end),
] as $term => $value)
{{ $term }}
{{ $value }}
@endforeach
@if ($subscription->cancelled_at)
{{ __('customer_detail.cancelled', ['date' => $date($subscription->cancelled_at)]) }}
@endif
@if ($subscription->addons->isNotEmpty())
{{ __('customer_detail.addons') }}
@foreach ($subscription->addons as $addon)
{{-- addon_key and price_cents are the column
names; the price is the one it was
BOOKED at, which is what the customer
agreed to and what the row freezes. --}}
{{ __('billing.addon.'.$addon->addon_key.'.name') }}
@if ($addon->cancels_at)
{{ __('customer_detail.addon_until', ['date' => $date($addon->cancels_at)]) }}
@endif
{{ $addon->quantity > 1 ? $addon->quantity.' × ' : '' }}{{ $money($addon->price_cents, $subscription->currency) }}
@endforeach
@endif
{{ __('customer_detail.machine') }}
@if ($instance === null)
{{ __('customer_detail.no_instance') }}
@else
@foreach ([
__('customer_detail.address_web') => $instance->subdomain ?: '—',
__('customer_detail.instance_status') => __('admin.status.'.$instance->status),
__('customer_detail.host') => $instance->host?->name ?? '—',
__('customer_detail.datacenter') => $instance->host?->datacenter ?? '—',
__('customer_detail.disk') => $instance->disk_gb.' GB',
] as $term => $value)
{{ $term }}
{{ $value }}
@endforeach
@endif
@endif
@endif
{{-- ══ Zahlungen ════════════════════════════════════════════════════════ --}}
@if ($tab === 'billing')
{{ __('customer_detail.invoices') }}
{{ __('customer_detail.write_invoice') }}
@if ($invoices->isEmpty())
{{ __('customer_detail.no_invoices') }}
@else
{{ __('customer_detail.number') }}
{{ __('customer_detail.issued') }}
{{ __('customer_detail.net') }}
{{ __('customer_detail.gross') }}
@foreach ($invoices as $invoice)
{{ $invoice->number }}
{{ $date($invoice->issued_on) }}
{{ $money($invoice->net_cents, $invoice->currency) }}
{{ $money($invoice->gross_cents, $invoice->currency) }}
PDF
@endforeach
@endif
{{-- What they actually bought, as opposed to what was invoiced. The
two answer different questions: an order is a purchase, an
invoice is a document about one. --}}
{{ __('customer_detail.orders') }}
@if ($orders->isEmpty())
{{ __('customer_detail.no_orders') }}
@else
@foreach ($orders as $order)
{{ $order->label() }}
{{ $order->status }}
{{ $date($order->created_at) }}
{{ $money($order->amount_cents, $order->currency) }}
@endforeach
@endif
@endif
{{-- ══ Nachrichten ══════════════════════════════════════════════════════ --}}
@if ($tab === 'messages')
{{-- What they asked through the portal --}}
{{ __('customer_detail.requests') }}
@if ($requests->isEmpty())
{{ __('customer_detail.no_requests') }}
@else
@endif
{{-- What they wrote by mail --}}
@if ($inbound->isEmpty())
{{ __('customer_detail.no_inbound') }}
@else
@endif
{{-- What we sent --}}
@if ($mails->isEmpty())
{{ __('customer_detail.no_mails') }}
@else
@endif
@endif
{{-- ══ Schreiben ════════════════════════════════════════════════════════ --}}
@if ($tab === 'compose')
{{ __('customer_message.title') }}
@if ($answering)
{{ __('customer_message.answering') }}
{{ __('customer_message.cancel_answer') }}
@endif
{{-- The templates. Inserted with this customer's own details already
in them; the last two sentences stay the operator's to write. --}}
@if ($templates->isEmpty())
{{ __('customer_message.no_templates') }}
@else
{{ __('customer_message.templates_note') }}
@foreach ($templates as $template)
{{ $template->name }}
@endforeach
@endif
@endif