mivita/resources/views/admin/user/transfer/index.blade.php
Kevin ef7e333bd4 Berater uebertragen: kompletten Berater- und Kundenstamm an einen anderen Berater
Ticket dev/_tickets/2026-09-08.md #1: neuer Punkt "Berater uebertragen" im
Superadmin (/admin/user/transfer). Vorschau zeigt Firstline, Downline,
geparkte Sponsor-Bezuege, Kunden, Kundenabos und Portal-Logins; nach
Bestaetigung wird alles in einer Transaktion umgehaengt und wie die
User-Bereinigung protokolliert (user_clean_up_logs,
shopping_user_member_logs, SysLog). Bestellungen, Umsaetze und
Provisionsdaten bleiben beim bisherigen Berater. Ziel unterhalb der
Firstline der Quelle wird abgelehnt (Kreis im Baum).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-23 15:43:58 +00:00

146 lines
7.9 KiB
PHP

@extends('layouts.layout-2')
@section('content')
<h4 class="font-weight-bold py-2 mb-2">
<i class="ion ion-md-git-network"></i> {{ __('navigation.user_transfer') }}
</h4>
<div class="row mb-3">
<div class="col">
<div class="alert alert-info">
<strong>Info:</strong> Überträgt den <b>gesamten Berater- und Kundenstamm</b> eines Beraters auf einen anderen Berater,
z.&nbsp;B. wenn ein Berater aufhört. Übertragen werden die Firstline (die Teilbäume darunter folgen automatisch),
alle Kunden, deren Abos und Portal-Logins. Bestehende Bestellungen und Provisionen bleiben als Historie beim
bisherigen Berater. Jede Umhängung wird in der
<a href="{{ route('admin_user_cleanup_logs') }}">User-Bereinigung</a> protokolliert.
</div>
</div>
</div>
@if ($errors->any())
<div class="alert alert-danger">
<ul class="mb-0">
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<div class="card mb-4">
<h6 class="card-header">1. Berater auswählen</h6>
<div class="card-body">
{!! Form::open(['route' => 'admin_user_transfer_preview', 'method' => 'post']) !!}
<div class="form-row">
<div class="form-group col-md-6">
<label class="form-label" for="source_user_id">Von Berater (gibt den Stamm ab)</label>
{!! Form::select('source_user_id', $sourceOptions, old('source_user_id', $source->id ?? ''), [
'id' => 'source_user_id',
'class' => 'selectpicker form-control',
'data-live-search' => 'true',
'data-style' => 'btn-light',
'required' => 'required',
]) !!}
</div>
<div class="form-group col-md-6">
<label class="form-label" for="target_user_id">An Berater (übernimmt den Stamm)</label>
{!! Form::select('target_user_id', $targetOptions, old('target_user_id', $target->id ?? ''), [
'id' => 'target_user_id',
'class' => 'selectpicker form-control',
'data-live-search' => 'true',
'data-style' => 'btn-light',
'required' => 'required',
]) !!}
<small class="form-text text-muted">Nur aktive, nicht gesperrte Berater mit gültigem Account.</small>
</div>
</div>
<button type="submit" class="btn btn-primary">Vorschau anzeigen</button>
{!! Form::close() !!}
</div>
</div>
@if ($preview && $source && $target)
<div class="card mb-4">
<h6 class="card-header">2. Vorschau und Bestätigung</h6>
<div class="card-body">
<div class="row">
<div class="col-md-6 mb-3">
<div class="text-muted small">Von</div>
<strong>{{ \App\Http\Controllers\AdminUserTransferController::userLabel($source) }}</strong>
<div class="small">
Status: {{ $source->active ? 'aktiv' : 'deaktiviert' }},
Account bis {{ $source->payment_account ? \Carbon\Carbon::parse($source->payment_account)->format('d.m.Y') : '-' }}
</div>
</div>
<div class="col-md-6 mb-3">
<div class="text-muted small">An</div>
<strong>{{ \App\Http\Controllers\AdminUserTransferController::userLabel($target) }}</strong>
@if ((int) $target->m_sponsor === (int) $source->id)
<div class="small text-warning">Der Zielberater ist selbst in der Firstline des Quellberaters. Er behält seinen Sponsor und bekommt die übrigen Firstline-Berater als Downline.</div>
@endif
</div>
</div>
<div class="table-responsive">
<table class="table table-sm table-bordered mb-3" id="transfer-preview">
<tbody>
<tr>
<th style="width: 50%">Firstline-Berater (werden direkt umgehängt)</th>
<td>{{ $preview['firstline_count'] }}</td>
</tr>
<tr>
<th>Gesamte Downline (alle Ebenen, folgt automatisch)</th>
<td>{{ $preview['downline_count'] }}</td>
</tr>
<tr>
<th>Deaktivierte Berater mit geparktem Sponsor-Bezug</th>
<td>{{ $preview['pre_sponsor_count'] }}</td>
</tr>
<tr>
<th>Kunden-Datensätze (davon gelöscht)</th>
<td>{{ $preview['customers_count'] }} ({{ $preview['customers_deleted_count'] }})</td>
</tr>
<tr>
<th>Kunden-Abos (davon aktiv)</th>
<td>{{ $preview['abos_count'] }} ({{ $preview['abos_active_count'] }})</td>
</tr>
<tr>
<th>Kunden-Portal-Logins</th>
<td>{{ $preview['portal_customers_count'] }}</td>
</tr>
</tbody>
</table>
</div>
@if ($preview['firstline']->isNotEmpty())
<div class="text-muted small mb-1">Firstline-Berater:</div>
<ul class="mb-3">
@foreach ($preview['firstline']->take(50) as $child)
<li>
{{ \App\Http\Controllers\AdminUserTransferController::userLabel($child) }}
@if ($child->id === $target->id) <span class="badge badge-warning">Zielberater, bleibt</span> @endif
@if ($child->deleted_at) <span class="badge badge-secondary">gelöscht</span> @elseif (! $child->active) <span class="badge badge-secondary">deaktiviert</span> @endif
</li>
@endforeach
@if ($preview['firstline']->count() > 50)
<li>… und {{ $preview['firstline']->count() - 50 }} weitere</li>
@endif
</ul>
@endif
{!! Form::open(['route' => 'admin_user_transfer_execute', 'method' => 'post']) !!}
{!! Form::hidden('source_user_id', $source->id) !!}
{!! Form::hidden('target_user_id', $target->id) !!}
<label class="custom-control custom-checkbox mb-3">
<input type="checkbox" class="custom-control-input" name="confirm_transfer" value="1">
<span class="custom-control-label">Ich habe die Vorschau geprüft und möchte den gesamten Berater- und Kundenstamm von <b>{{ $source->email }}</b> an <b>{{ $target->email }}</b> übertragen.</span>
</label>
<div>
<button type="submit" class="btn btn-danger">Übertragung ausführen</button>
<a href="{{ route('admin_user_transfer') }}" class="btn btn-default">Abbrechen</a>
</div>
{!! Form::close() !!}
</div>
</div>
@endif
@endsection