id = $id;
$context = app(CustomerCompanyContext::class);
$company = $context->findFor(auth()->user(), $id);
abort_unless($company !== null, 404);
$context->select(auth()->user(), $id);
}
public function startEditCompany(): void
{
$company = $this->company();
$this->authorize('update', $company);
$this->companyName = (string) $company->name;
$this->companyAddress = (string) ($company->address ?? '');
$this->companyEmail = (string) ($company->email ?? '');
$this->companyPhone = (string) ($company->phone ?? '');
$this->companyWebsite = (string) ($company->website ?? '');
$this->companyCountryCode = (string) ($company->country_code ?? 'DE');
$this->companyDisableFooterCode = (bool) $company->disable_footer_code;
$this->companyLogo = null;
$this->removeCompanyLogo = false;
$this->showCompanyForm = true;
}
public function cancelCompanyForm(): void
{
$this->resetCompanyForm();
}
public function saveCompany(ImageService $imageService): void
{
$company = $this->company();
$this->authorize('update', $company);
$validated = $this->validate([
'companyName' => ['required', 'string', 'max:255'],
'companyAddress' => ['nullable', 'string', 'max:1000'],
'companyEmail' => ['nullable', 'email', 'max:190'],
'companyPhone' => ['nullable', 'string', 'max:40'],
'companyWebsite' => ['nullable', 'url', 'max:190'],
'companyCountryCode' => ['nullable', 'string', 'size:2', Rule::in(array_keys((array) config('countries.items', [])))],
'companyLogo' => ['nullable', 'image', 'max:' . (int) (ImageService::MAX_LOGO_BYTES / 1024)],
]);
$company->fill([
'name' => $validated['companyName'],
'address' => $validated['companyAddress'] ?: null,
'email' => $validated['companyEmail'] ?: null,
'phone' => $validated['companyPhone'] ?: null,
'website' => $validated['companyWebsite'] ?: null,
'country_code' => $validated['companyCountryCode'] ?: null,
'disable_footer_code' => $this->companyDisableFooterCode,
]);
if ($this->removeCompanyLogo) {
$imageService->deleteCompanyLogo($company->logo_path, $company->logo_variants);
$company->logo_path = null;
$company->logo_variants = null;
}
if ($this->companyLogo) {
$imageService->deleteCompanyLogo($company->logo_path, $company->logo_variants);
$stored = $imageService->storeCompanyLogo($this->companyLogo, $company->portal?->value ?? 'presseecho', $company->id);
$company->logo_path = $stored['path'];
$company->logo_variants = $stored['variants'];
}
$company->save();
$this->resetCompanyForm();
session()->flash('company-status', __('Stammdaten wurden gespeichert.'));
}
public function startCreateContact(): void
{
$this->authorize('update', $this->company());
$this->resetContactForm();
$this->showContactForm = true;
}
public function editContact(int $contactId): void
{
$this->authorize('update', $this->company());
$contact = $this->contact($contactId);
$this->editingContactId = $contact->id;
$this->contactFirstName = (string) ($contact->first_name ?? '');
$this->contactLastName = (string) ($contact->last_name ?? '');
$this->contactResponsibility = (string) ($contact->responsibility ?? '');
$this->contactEmail = (string) ($contact->email ?? '');
$this->contactPhone = (string) ($contact->phone ?? '');
$this->showContactForm = true;
}
public function cancelContactForm(): void
{
$this->resetContactForm();
}
public function saveContact(): void
{
$company = $this->company();
$this->authorize('update', $company);
$validated = $this->validate([
'contactFirstName' => ['nullable', 'string', 'max:80'],
'contactLastName' => ['nullable', 'string', 'max:80'],
'contactResponsibility' => ['nullable', 'string', 'max:255'],
'contactEmail' => ['required', 'email', 'max:255'],
'contactPhone' => ['nullable', 'string', 'max:40'],
]);
if (blank($validated['contactFirstName']) && blank($validated['contactLastName'])) {
throw ValidationException::withMessages([
'contactLastName' => __('Bitte geben Sie mindestens einen Namen an.'),
]);
}
$payload = [
'company_id' => $company->id,
'portal' => $company->portal?->value,
'first_name' => $validated['contactFirstName'] ?: null,
'last_name' => $validated['contactLastName'] ?: null,
'responsibility' => $validated['contactResponsibility'] ?: null,
'email' => $validated['contactEmail'],
'phone' => $validated['contactPhone'] ?: null,
];
if ($this->editingContactId) {
$this->contact($this->editingContactId)->update($payload);
session()->flash('contact-status', __('Pressekontakt wurde aktualisiert.'));
} else {
Contact::query()->create($payload);
session()->flash('contact-status', __('Pressekontakt wurde angelegt.'));
}
$this->resetContactForm();
}
public function deleteContact(int $contactId): void
{
$this->authorize('update', $this->company());
$contact = $this->contact($contactId);
$contact->delete();
if ($this->editingContactId === $contactId) {
$this->resetContactForm();
}
session()->flash('contact-status', __('Pressekontakt wurde gelöscht.'));
}
public function with(): array
{
$user = auth()->user();
$context = app(CustomerCompanyContext::class);
$company = $context
->accessibleCompanyQuery($user)
->withCount(['contacts', 'pressReleases'])
->findOrFail($this->id);
return [
'company' => $company,
'roleLabel' => $context->roleLabelFor($company, $user),
'canManageCompany' => $user->can('update', $company),
'canManageContacts' => $user->can('update', $company),
'countries' => (array) config('countries.items', []),
'contacts' => Contact::withoutGlobalScopes()
->where('company_id', $company->id)
->withCount('pressReleases')
->orderBy('last_name')
->orderBy('first_name')
->limit(10)
->get(['id', 'company_id', 'first_name', 'last_name', 'responsibility', 'email', 'phone']),
'pressReleases' => PressRelease::withoutGlobalScopes()
->where('user_id', $user->id)
->where('company_id', $company->id)
->latest()
->limit(10)
->get(['id', 'title', 'status', 'created_at', 'published_at']),
];
}
private function company(): Company
{
$company = app(CustomerCompanyContext::class)->findFor(auth()->user(), $this->id);
abort_unless($company !== null, 404);
return $company;
}
private function contact(int $contactId): Contact
{
return Contact::withoutGlobalScopes()->where('company_id', $this->id)->findOrFail($contactId);
}
private function resetCompanyForm(): void
{
$this->showCompanyForm = false;
$this->companyName = '';
$this->companyAddress = '';
$this->companyEmail = '';
$this->companyPhone = '';
$this->companyWebsite = '';
$this->companyCountryCode = 'DE';
$this->companyDisableFooterCode = false;
$this->companyLogo = null;
$this->removeCompanyLogo = false;
$this->resetValidation();
}
private function resetContactForm(): void
{
$this->showContactForm = false;
$this->editingContactId = null;
$this->contactFirstName = '';
$this->contactLastName = '';
$this->contactResponsibility = '';
$this->contactEmail = '';
$this->contactPhone = '';
$this->resetValidation();
}
}; ?>
{{-- ============== PAGE HEADER ============== --}}
{{-- ============== QUICK-NAV ============== --}}
{{-- ============== KPI-Reihe ============== --}}
{{ __('zugeordnet') }}
{{ __('Content-Output') }}
{{ __('Ansprechpartner') }}
{{ __('für PMs verfügbar') }}
{{ __('Sichtbarkeit') }}
{{ __('für diese Firma') }}
{{ __('Berechtigungen') }}
{{ $canManageCompany ? __('Voller Schreibzugriff') : __('Lesezugriff') }}
{{-- ============== STAMMDATEN ============== --}}
{{ __('Stammdaten') }}
@if ($canManageCompany)
{{ __('Bearbeiten') }}
@endif
@if (session('company-status'))
{{ session('company-status') }}
@endif
@if ($showCompanyForm)
{{ __('Stammdaten bearbeiten') }}
@foreach ($countries as $code => $name)
@endforeach
{{ __('Firmenlogo') }}
@php($logoUrl = $company->logoUrl())
@if ($logoUrl && ! $removeCompanyLogo)
{{ __('Logo entfernen') }}
@endif
@if ($companyLogo)
@endif
{{ __('Abbrechen') }}
{{ __('Speichern') }}
@endif
- {{ __('E-Mail') }}
- {{ $company->email ?: '–' }}
- {{ __('Telefon') }}
- {{ $company->phone ?: '–' }}
- {{ __('Land') }}
- {{ $company->country_code ?: '–' }}
- {{ __('Adresse') }}
- {{ $company->address ?: '–' }}
{{-- ============== PRESSEKONTAKTE ============== --}}
{{ __('Pressekontakte') }}
{{ trans_choice(':count Kontakt|:count Kontakte', $company->contacts_count, ['count' => $company->contacts_count]) }}
@if ($canManageContacts)
{{ __('Kontakt hinzufügen') }}
@endif
@if (session('contact-status'))
{{ session('contact-status') }}
@endif
@if ($showContactForm)
{{ $editingContactId ? __('Pressekontakt bearbeiten') : __('Neuen Pressekontakt anlegen') }}
{{ __('Abbrechen') }}
{{ __('Speichern') }}
@endif
@forelse ($contacts as $contact)
{{ trim(($contact->first_name ?? '').' '.($contact->last_name ?? '')) ?: __('Kontakt ohne Name') }}
{{ $contact->responsibility ?: __('Keine Rolle hinterlegt') }}
@if ($contact->email)
{{ $contact->email }}
@endif
@if ($contact->phone)
{{ $contact->phone }}
@endif
@if ($contact->press_releases_count > 0)
{{ trans_choice('in :count Pressemitteilung hinterlegt|in :count Pressemitteilungen hinterlegt', $contact->press_releases_count, ['count' => $contact->press_releases_count]) }}
@endif
@if ($canManageContacts)
{{ __('Bearbeiten') }}
{{ __('Löschen') }}
@endif
@empty
{{ __('Keine Pressekontakte hinterlegt') }}
{{ __('Pressekontakte helfen, Pressemitteilungen eindeutig einer Ansprechperson zuzuordnen.') }}
@if ($canManageContacts)
{{ __('Kontakt hinzufügen') }}
@endif
@endforelse
{{-- ============== PRESSEMITTEILUNGEN ============== --}}
{{ __('Pressemitteilungen dieser Firma') }}
{{ __('Alle anzeigen') }}
{{ __('Titel') }}
{{ __('Status') }}
{{ __('Datum') }}
{{ __('Aktionen') }}
@forelse ($pressReleases as $pressRelease)
{{ $pressRelease->title }}
@php($statusValue = $pressRelease->status->value)
$statusValue === 'published',
'warn' => $statusValue === 'review',
'err' => $statusValue === 'rejected',
'hub' => ! in_array($statusValue, ['published', 'review', 'rejected'], true),
])>
{{ $pressRelease->status->label() }}
{{ $pressRelease->published_at?->format('d.m.Y') ?? ($pressRelease->created_at?->format('d.m.Y') ?? '–') }}
{{ __('Öffnen') }}
@empty
{{ __('Keine Pressemitteilungen für diese Firma') }}
{{ __('Erstellen Sie die erste Pressemitteilung direkt mit dieser Firma als Kontext.') }}
{{ __('Neue Pressemitteilung') }}
@endforelse
{{-- ============== ABRECHNUNG ============== --}}
{{ __('Abrechnung') }}
{{ __('In Vorbereitung') }}
{{ __('Firmenspezifische Zahlungsarten und Add-ons werden hier später zusammengeführt.') }}
{{ __('Noch keine firmenspezifische Abrechnung') }}
{{ __('Rechnungen finden Sie aktuell gesammelt im Finanzbereich. Firmenscharfe Zahlungsarten folgen mit dem Preismodell.') }}
{{ __('Rechnungen öffnen') }}
{{-- ============== STATISTIK ============== --}}
{{ __('Statistik') }}
{{ __('Später') }}
{{ __('Erste Kennzahlen zur Firma; detaillierte Auswertungen folgen später.') }}
{{ __('Pressemitteilungen') }}
{{ $company->press_releases_count }}
{{ __('Pressekontakte') }}
{{ $company->contacts_count }}