Ticket dev/_tickets/2026-09-08.md #2: - "Kunde loeschen" oeffnet ein Modal statt direkt per GET zu loeschen. Es zeigt alle Eintraege desselben Kunden (Kundennummer oder E-Mail, ohne Platzhalter-Adressen) mit Anzahl Bestellungen. - Ohne Bestellungen: Komplett-Loeschung (anonymisiert und soft-geloescht, Portal-Logins und Stripe-Kunden entfernt, Zahlungs-Tokens inaktiver Abos geleert). Mit Bestellungen nur DSGVO-Loeschung (Superadmin); die arbeitet jetzt ebenfalls auf der E-Mail-Gruppe und entfernt Portal-Logins. - Bei aktivem Abo oder Berater-Datensatz wird abgelehnt. - Die alte "Loeschung" (CustomerRepository::deleteCustomer) entfaellt. - Fehlermeldungen nutzen alert-error; alert-danger zeigte kein Layout an. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
110 lines
No EOL
7.1 KiB
PHP
110 lines
No EOL
7.1 KiB
PHP
@extends('layouts.layout-2')
|
||
|
||
@section('content')
|
||
|
||
<h4 class="font-weight-bold py-2 mb-2">
|
||
<a href="{{route('admin_customers')}}" class="btn btn-sm btn-default float-right">{{ __('back') }}</a>
|
||
{{ __('customer.customer_details') }}
|
||
</h4>
|
||
@include('admin.customer._detail')
|
||
<a href="{{route('admin_customers')}}" class="btn btn-sm btn-default mt-2 float-right">{{ __('back') }}</a>
|
||
|
||
{{-- Kunden löschen: ein Modal für beide Wege (dev/_tickets/2026-09-08.md, Ticket #2) --}}
|
||
@php($canGdprDelete = Auth::user()->isSuperAdmin())
|
||
<div class="modal fade" id="modals-customer-delete">
|
||
<div class="modal-dialog modal-lg">
|
||
<div class="modal-content">
|
||
<div class="modal-header">
|
||
<h5 class="modal-title">{{ __('customer.delete_customer') }}</h5>
|
||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">×</button>
|
||
</div>
|
||
<div class="modal-body">
|
||
@if ($deletion['is_member'])
|
||
<div class="alert alert-warning mb-0">{{ __('msg.gdpr_error_customer_is_member') }}</div>
|
||
@else
|
||
<p>
|
||
Der Kunde ist <b>{{ $deletion['rows']->count() }}-mal</b> angelegt
|
||
@if ($deletion['email'])
|
||
(E-Mail <b>{{ $deletion['email'] }}</b>, Kundennummer {{ $shopping_user->number ?: '-' }}).
|
||
@else
|
||
(Kundennummer {{ $shopping_user->number ?: '-' }}; keine gültige E-Mail zur Duplikat-Suche).
|
||
@endif
|
||
Alle folgenden Einträge werden gemeinsam behandelt:
|
||
</p>
|
||
<div class="table-responsive">
|
||
<table class="table table-sm table-bordered" id="customer-delete-rows">
|
||
<thead>
|
||
<tr>
|
||
<th>ID</th>
|
||
<th>Kd-Nr.</th>
|
||
<th>Name</th>
|
||
<th>Berater</th>
|
||
<th>Bestellungen</th>
|
||
<th>Angelegt</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
@foreach ($deletion['rows'] as $row)
|
||
<tr class="{{ $row->id === $shopping_user->id ? 'font-weight-bold' : '' }}">
|
||
<td>{{ $row->id }}</td>
|
||
<td>{{ $row->number ?: '-' }}</td>
|
||
<td>{{ trim($row->billing_firstname.' '.$row->billing_lastname) }}
|
||
@if ($row->deleted_at) <span class="badge badge-secondary">gelöscht</span> @endif
|
||
</td>
|
||
<td>{{ $row->member->email ?? '-' }}</td>
|
||
<td>{{ $deletion['orders_by_row'][$row->id] ?? 0 }}</td>
|
||
<td>{{ $row->created_at ? $row->created_at->format('d.m.Y') : '-' }}</td>
|
||
</tr>
|
||
@endforeach
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
@if ($deletion['orders_count'] > 0)
|
||
<div class="alert alert-warning">
|
||
Der Kunde hat schon <b>{{ $deletion['orders_count'] }} Bestellung(en)</b>. Es ist nur <b>DSGVO löschen</b> möglich:
|
||
Alle personenbezogenen Daten werden unwiderruflich anonymisiert. Bei Einträgen mit Bestellung bleiben Name und
|
||
Rechnungsadresse wegen der gesetzlichen Aufbewahrungspflichten erhalten; alle Kontaktdaten (E-Mail, Telefon,
|
||
Notizen, Newsletter) sowie die Portal-Logins werden entfernt.
|
||
@if ($deletion['active_abos'] > 0)
|
||
<br><b>{{ __('msg.gdpr_error_active_abo') }}</b>
|
||
@endif
|
||
</div>
|
||
@if ($canGdprDelete)
|
||
<form action="{{ route('admin_customer_gdpr_delete', [$shopping_user->id]) }}" method="post" id="form-customer-gdpr-delete">
|
||
@csrf
|
||
<label class="custom-control custom-checkbox mb-3">
|
||
<input type="checkbox" class="custom-control-input" name="gdpr_delete_customer" value="1">
|
||
<span class="custom-control-label">DSGVO-Löschung unwiderruflich ausführen?</span>
|
||
</label>
|
||
<button type="submit" class="btn btn-danger" {{ $deletion['active_abos'] > 0 ? 'disabled' : '' }}>{{ __('msg.gdpr_delete_customer_button') }}</button>
|
||
</form>
|
||
@else
|
||
<p class="text-muted mb-0">Die DSGVO-Löschung kann nur von einem Superadmin ausgeführt werden.</p>
|
||
@endif
|
||
@elseif ($deletion['active_abos'] > 0)
|
||
<div class="alert alert-warning mb-0">{{ __('msg.gdpr_error_active_abo') }}</div>
|
||
@else
|
||
<div class="alert alert-info">
|
||
Der Kunde hat <b>keine Bestellungen</b> und kann <b>komplett gelöscht</b> werden: Alle oben aufgeführten Einträge
|
||
werden vollständig anonymisiert und entfernt, inklusive Portal-Login und inaktiver Abos.
|
||
</div>
|
||
<form action="{{ route('admin_customer_delete', [$shopping_user->id]) }}" method="post" id="form-customer-delete">
|
||
@csrf
|
||
<label class="custom-control custom-checkbox mb-3">
|
||
<input type="checkbox" class="custom-control-input" name="delete_customer" value="1">
|
||
<span class="custom-control-label">Kunden mit allen {{ $deletion['rows']->count() }} Einträgen unwiderruflich löschen?</span>
|
||
</label>
|
||
<button type="submit" class="btn btn-danger">{{ __('msg.gdpr_purge_customer_button') }}</button>
|
||
</form>
|
||
@endif
|
||
@endif
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button type="button" class="btn btn-default" data-dismiss="modal">{{ __('close') }}</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
@endsection |