mivita/resources/views/admin/customer/detail.blade.php
Kevin 90c2188ffa 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>
2026-09-23 15:43:35 +00:00

110 lines
No EOL
7.1 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

@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