Kunden loeschen: Modal mit Komplett- oder DSGVO-Loeschung ueber alle Dubletten
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>
This commit is contained in:
parent
728dde4c76
commit
90c2188ffa
12 changed files with 631 additions and 88 deletions
|
|
@ -45,6 +45,7 @@ class CustomerController extends Controller
|
|||
$shopping_user = ShoppingUser::findOrFail($id);
|
||||
$data = [
|
||||
'shopping_user' => $shopping_user,
|
||||
'deletion' => app(GdprDeletionService::class)->analyzeShoppingUser($shopping_user),
|
||||
'isAdmin' => true,
|
||||
'isView' => 'customer',
|
||||
];
|
||||
|
|
@ -52,16 +53,26 @@ class CustomerController extends Controller
|
|||
return view('admin.customer.detail', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Komplett-Löschung (nur ohne Bestellungen), dev/_tickets/2026-09-08.md #2.
|
||||
*/
|
||||
public function delete($id)
|
||||
{
|
||||
$shopping_user = ShoppingUser::findOrFail($id);
|
||||
$result = $this->customerRepository->deleteCustomer($shopping_user);
|
||||
if (! $result) {
|
||||
return back()->with('alert-error', 'Kunde hat Bestellungen. Löschen nicht möglich.');
|
||||
} else {
|
||||
\Session()->flash('alert-success', 'Kunde wurde gelöscht');
|
||||
$shopping_user = ShoppingUser::withTrashed()->findOrFail($id);
|
||||
|
||||
return redirect(route('admin_customers'));
|
||||
if (! Request::get('delete_customer')) {
|
||||
\Session()->flash('alert-error', __('msg.delete_confirm_checkbox_missing'));
|
||||
|
||||
return redirect(route('admin_customer_detail', [$shopping_user->id]));
|
||||
}
|
||||
|
||||
try {
|
||||
$summary = app(GdprDeletionService::class)->purgeShoppingUser($shopping_user, Auth::id());
|
||||
\Session()->flash('alert-success', __('msg.gdpr_purge_customer_success', ['count' => $summary['shopping_users_purged']]));
|
||||
} catch (GdprDeletionException $e) {
|
||||
\Session()->flash('alert-error', $e->getMessage());
|
||||
|
||||
return redirect(route('admin_customer_detail', [$shopping_user->id]));
|
||||
}
|
||||
|
||||
return redirect(route('admin_customers'));
|
||||
|
|
@ -72,7 +83,7 @@ class CustomerController extends Controller
|
|||
$shopping_user = ShoppingUser::withTrashed()->findOrFail($id);
|
||||
|
||||
if (! Request::get('gdpr_delete_customer')) {
|
||||
\Session()->flash('alert-danger', __('msg.gdpr_confirm_checkbox_missing'));
|
||||
\Session()->flash('alert-error', __('msg.gdpr_confirm_checkbox_missing'));
|
||||
|
||||
return redirect(route('admin_customer_detail', [$shopping_user->id]));
|
||||
}
|
||||
|
|
@ -81,7 +92,7 @@ class CustomerController extends Controller
|
|||
app(GdprDeletionService::class)->deleteShoppingUser($shopping_user, Auth::id());
|
||||
\Session()->flash('alert-success', __('msg.gdpr_delete_customer_success'));
|
||||
} catch (GdprDeletionException $e) {
|
||||
\Session()->flash('alert-danger', $e->getMessage());
|
||||
\Session()->flash('alert-error', $e->getMessage());
|
||||
|
||||
return redirect(route('admin_customer_detail', [$shopping_user->id]));
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue