Feedback-Umsetzung (dev/2026-07-22/feedback-analyse-2026-07-24.md, alle 10 Punkte):
- VIP-Statistik: eigener Berater ('ich', Linie 0) in Neue-Kundenabos- und beiden Top-10-Listen; Top-10-Umsatz sortiert nach abgerechneten Ist-Punkten + Abo-Anzahl-Spalte; Fußnote nicht-payline-wirksame Punkte (SalesVolumePoints::nonPaylinePoints)
- Führungskräfte-Liste: beide Sichten 'direkt' (an nächster FK abgeschnitten, additiv) und 'gesamt' (komplette Downline), Gesamt-Spalte nach Kundenzählweise
- Team-Abos: je Ebene 'abgerechnet (Monat)' und 'bis zum 25. erwartet'; Payline-Karte mit Teamabo-/Kundenabo-Zählern
- Incentive-Live-Ranking: Qualifizierte zuerst nummeriert (fixt auch isWinner rank<=max_winners)
- Porto: Netto-/Brutto-Kennzeichnung (Berater netto, Endkunden inkl. MwSt., portal_view-Flag; auch CRM-/Shop-Warenkorb + Checkout), Yard::shipping_tax-Fix
- Struktur-Ansicht: Abo-Badges 'A' (eigenes Abo) und '(n)' (Kundenabos) je Teampartner, gebatcht
- Abo-Löschung: Softdelete setzt active=0 (UserAbo deleting-Hook) + Bereinigungs-Migration für gelöschte-aber-aktive Abos
- Doku: technische Analyse + Kundinnen-Feedback-Dokument unter dev/2026-07-22/
- Tests: IncentiveRankingTest, TeamStructureAboBadgesTest, YardShippingTaxTest (neu); BackofficeStatisticsListsTest, TeamAboOverviewTest, PaylineForecastServiceTest, AboAdminDeleteTest, AboOneTimeViewTest erweitert
Außerdem enthalten (Branch-WIP vor dem Feedback): DATEV-Abgleich-Fixes 08+09/2025, USt-ID-Live-Validierung sowie restliche unkommittete Stände (u. a. Abo-Pause-Sprachkeys).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
384 lines
17 KiB
PHP
384 lines
17 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Exceptions\GdprDeletionException;
|
|
use App\Mail\UserRestoreEmail;
|
|
use App\Models\UserAccount;
|
|
use App\Repositories\UserRepository;
|
|
use App\Services\GdprDeletionService;
|
|
use App\Services\HTMLHelper;
|
|
use App\Services\SysLog;
|
|
use App\Services\UserUtil;
|
|
use App\User;
|
|
use Auth;
|
|
use Carbon;
|
|
use Illuminate\Contracts\View\Factory;
|
|
use Illuminate\Http\RedirectResponse;
|
|
use Illuminate\Routing\Redirector;
|
|
use Illuminate\Support\Facades\Mail;
|
|
use Illuminate\View\View;
|
|
use Request;
|
|
|
|
class AdminUserController extends Controller
|
|
{
|
|
protected $userRepo;
|
|
|
|
public function __construct(UserRepository $userRepo)
|
|
{
|
|
$this->middleware('superadmin');
|
|
$this->userRepo = $userRepo;
|
|
}
|
|
|
|
/**
|
|
* @return Factory|View
|
|
*/
|
|
public function index()
|
|
{
|
|
$data = [
|
|
// 'values' => User::where('admin', 0)->get(),
|
|
'values' => User::where('confirmation_code_remider', '!=', 2)->get(),
|
|
];
|
|
|
|
return view('admin.user.index', $data);
|
|
}
|
|
|
|
public function edit($user_id)
|
|
{
|
|
$user = User::findOrFail($user_id);
|
|
if (! $user->account) {
|
|
$user->account = new UserAccount;
|
|
}
|
|
|
|
$data = [
|
|
'user' => $user,
|
|
];
|
|
|
|
return view('admin.user.edit', $data);
|
|
}
|
|
|
|
/**
|
|
* @param Request $request
|
|
* @return Factory|RedirectResponse|Redirector|View
|
|
*/
|
|
public function store()
|
|
{
|
|
|
|
$data = Request::all();
|
|
$user = User::withTrashed()->findOrFail($data['id']);
|
|
|
|
/* if(isset($data['user-delete'])){
|
|
if(isset($data['realy_delete_user'])){
|
|
return redirect(route('admin_user_delete', [$user->id]));
|
|
}
|
|
}*/
|
|
if (isset($data['save-admin'])) {
|
|
$user->admin = $data['admin'];
|
|
SysLog::action('save-admin', 'admin_user', 3)
|
|
->setUserId(Auth::user()->id)
|
|
->setModel($user->id, User::class)
|
|
->setMessage('Set user admin value: '.HTMLHelper::getLabel($user->admin))
|
|
->save();
|
|
}
|
|
|
|
if (isset($data['save-confirmed'])) {
|
|
$data['confirmed'] = isset($data['confirmed']) ? true : false;
|
|
$user->confirmed = $data['confirmed'];
|
|
if ($data['confirmed']) {
|
|
if (! isset($data['confirmation_date']) || $data['confirmation_date'] == '') {
|
|
$user->confirmation_date = now();
|
|
} else {
|
|
$user->confirmation_date = Carbon::parse(str_replace('- ', '', $data['confirmation_date']));
|
|
}
|
|
} else {
|
|
$user->confirmation_date = null;
|
|
}
|
|
SysLog::action('save-confirmed', 'admin_user', 3)
|
|
->setUserId(Auth::user()->id)
|
|
->setModel($user->id, User::class)
|
|
->setMessage('Set user confirmed value: '.$user->confirmed.' to date: '.$data['confirmation_date'])
|
|
->save();
|
|
}
|
|
|
|
if (isset($data['save-active'])) {
|
|
$data['active'] = isset($data['active']) ? true : false;
|
|
$user->active = $data['active'];
|
|
if ($data['active'] === true && $user->wizard < 20) {
|
|
$user->wizard = 20;
|
|
}
|
|
if ($data['active']) {
|
|
if (! isset($data['active_date']) || $data['active_date'] == '') {
|
|
$user->active_date = now();
|
|
} else {
|
|
$user->active_date = Carbon::parse(str_replace('- ', '', $data['active_date']));
|
|
}
|
|
} else {
|
|
$user->active_date = null;
|
|
}
|
|
SysLog::action('save-active', 'admin_user', 3)
|
|
->setUserId(Auth::user()->id)
|
|
->setModel($user->id, User::class)
|
|
->setMessage('Set user active value: '.$user->active.' to date: '.$data['active_date'])
|
|
->save();
|
|
}
|
|
|
|
if (isset($data['save-restore'])) {
|
|
$restore_account = isset($data['restore_account']) ? true : false;
|
|
$restore_childs = isset($data['restore_childs']) ? true : false;
|
|
$restore_send_email = isset($data['restore_send_email']) ? true : false;
|
|
if (isset($data['payment_account']) || $data['payment_account'] != '') {
|
|
|
|
$error = UserUtil::checkEmailExists($user);
|
|
if ($error) {
|
|
\Session()->flash('alert-error', $error);
|
|
|
|
return redirect()->back()->withInput()->withErrors(['error' => $error]);
|
|
}
|
|
$payment_account = Carbon::parse(str_replace('- ', '', $data['payment_account']));
|
|
if ($restore_account) {
|
|
UserUtil::restoreUser($user, $payment_account);
|
|
if ($restore_childs) {
|
|
UserUtil::resetChildsToSponsor($user->id);
|
|
}
|
|
if ($restore_send_email) {
|
|
$user = User::with('account')->findOrFail($data['id']);
|
|
Mail::to($user->email)->send(new UserRestoreEmail($user));
|
|
}
|
|
}
|
|
}
|
|
SysLog::action('save-restore', 'admin_user', 3)
|
|
->setUserId(Auth::user()->id)
|
|
->setModel($user->id, User::class)
|
|
->setMessage('Set user restore_account value: '.$user->restore_account.' and restore_childs value: '.$user->restore_childs)
|
|
->save();
|
|
}
|
|
|
|
if (isset($data['save-account'])) {
|
|
$old = $user->getPaymentAccountDateFormat(true);
|
|
if (! isset($data['payment_account']) || $data['payment_account'] == '') {
|
|
$user->payment_account = null;
|
|
} else {
|
|
$user->wizard = 100;
|
|
$payment_account = Carbon::parse(str_replace('- ', '', $data['payment_account']));
|
|
$user->payment_account = $payment_account;
|
|
if ($payment_account > Carbon::now()) {
|
|
if ($user->active === 0) {
|
|
$user->active = true;
|
|
UserUtil::reactiveUserResetChilds($user->id, 'on save-account AdminUserController');
|
|
}
|
|
} else {
|
|
if ($user->active === 1) {
|
|
$user->active = false;
|
|
UserUtil::deactiveUserNewSponsorChilds($user->id, 'on save-account AdminUserController');
|
|
}
|
|
}
|
|
}
|
|
// th.schifferegger@gmail.com
|
|
SysLog::action('save-account', 'admin_user', 3)
|
|
->setUserId(Auth::user()->id)
|
|
->setModel($user->id, User::class)
|
|
->setMessage('Set user payment_account from date: '.$old.' to date: '.$data['payment_account'])
|
|
->save();
|
|
}
|
|
|
|
if (isset($data['save-shop'])) {
|
|
$old = $user->getPaymentShopDateFormat(true);
|
|
if (! isset($data['payment_shop']) || $data['payment_shop'] == '') {
|
|
$user->payment_shop = null;
|
|
} else {
|
|
$user->wizard = 100;
|
|
$user->payment_shop = Carbon::parse(str_replace('- ', '', $data['payment_shop']));
|
|
}
|
|
SysLog::action('save-shop', 'admin_user', 3)
|
|
->setUserId(Auth::user()->id)
|
|
->setModel($user->id, User::class)
|
|
->setMessage('Set user payment_shop from date: '.$old.' to date: '.$data['payment_shop'])
|
|
->save();
|
|
}
|
|
|
|
if (isset($data['save-test_mode'])) {
|
|
$user->test_mode = isset($data['test_mode']) ? true : false;
|
|
SysLog::action('save-test_mode', 'admin_user', 3)
|
|
->setUserId(Auth::user()->id)
|
|
->setModel($user->id, User::class)
|
|
->setMessage('Set user test_mode value: '.$user->test_mode)
|
|
->save();
|
|
}
|
|
|
|
if (isset($data['save-payment_methods'])) {
|
|
$user->payment_methods = isset($data['payment_methods']) ? array_map('intval', $data['payment_methods']) : null;
|
|
SysLog::action('save-payment_methods', 'admin_user', 3)
|
|
->setUserId(Auth::user()->id)
|
|
->setModel($user->id, User::class)
|
|
->setMessage('Set user payment_methods value: '.$user->getPaymentMethodsShort())
|
|
->save();
|
|
}
|
|
|
|
$user->save();
|
|
|
|
\Session()->flash('alert-save', true);
|
|
|
|
return redirect('/admin/users');
|
|
}
|
|
|
|
public function deleteUser()
|
|
{
|
|
$data = Request::all();
|
|
$user = User::withTrashed()->findOrFail($data['id']);
|
|
if (isset($data['realy_delete_user'])) {
|
|
$this->userRepo->deleteUser($user);
|
|
\Session()->flash('alert-success', __('msg.contact_delete'));
|
|
}
|
|
if (isset($data['realy_delete_user_complete'])) {
|
|
// $this->userRepo->deleteUserComplete($user);
|
|
$this->userRepo->deleteUser($user, true);
|
|
\Session()->flash('alert-success', __('msg.contact_delete'));
|
|
}
|
|
if (isset($data['gdpr_delete_user'])) {
|
|
try {
|
|
app(GdprDeletionService::class)->deleteUser($user, Auth::id());
|
|
\Session()->flash('alert-success', __('msg.gdpr_delete_success'));
|
|
} catch (GdprDeletionException $e) {
|
|
\Session()->flash('alert-danger', $e->getMessage());
|
|
}
|
|
}
|
|
|
|
return redirect('/admin/users');
|
|
}
|
|
|
|
public function userLoginAs($userId)
|
|
{
|
|
if (Auth::user()->isSuperAdmin()) {
|
|
$user = User::find($userId);
|
|
Auth::login($user);
|
|
|
|
return redirect('/home');
|
|
}
|
|
}
|
|
|
|
public function getUsers()
|
|
{
|
|
$query = User::withTrashed()
|
|
->where(function ($q) {
|
|
$q->where('pre_deleted_at', '!=', null)
|
|
->orWhere(function ($query) {
|
|
$query->whereNull('deleted_at')
|
|
->whereNull('pre_deleted_at');
|
|
});
|
|
})
|
|
->with('account')
|
|
->select('users.*')
|
|
->where('users.admin', '<', 5);
|
|
|
|
return \DataTables::eloquent($query)
|
|
->addColumn('first_name', function (User $user) {
|
|
return $user->account ? $user->account->first_name : '';
|
|
})
|
|
->addColumn('email', function (User $user) {
|
|
if ($user->pre_deleted_at) {
|
|
return '<span class="badge badge-pill badge-danger">'.$user->email.'</span>';
|
|
}
|
|
|
|
return $user->email;
|
|
})
|
|
->addColumn('last_name', function (User $user) {
|
|
return $user->account ? $user->account->last_name : '';
|
|
})
|
|
->addColumn('id', function (User $user) {
|
|
return '<a href="'.route('admin_lead_edit', [$user->id]).'" class="btn icon-btn btn-sm btn-primary"><span class="fa fa-edit"></span></a>';
|
|
})
|
|
->addColumn('admin', function (User $user) {
|
|
return '<a href="#" data-toggle="modal" data-target="#modals-admin" data-id="'.$user->id.'" data-email="'.$user->email.'" data-admin="'.$user->admin.'">'.HTMLHelper::getRoleLabel($user->admin).'</a>';
|
|
})
|
|
->addColumn('confirmed', function (User $user) {
|
|
$date = $user->getConfirmationDateFormat();
|
|
$link = '<a href="#" data-toggle="modal" data-target="#modals-confirmed" data-id="'.$user->id.'" data-email="'.$user->email.'" data-confirmed="'.$user->confirmed.'" data-confirmation_date="'.$date.'">';
|
|
|
|
return $user->confirmed ? $link.'<span class="badge badge-pill badge-success"><i class="fa fa-check"></i> '.$date.'</span></a>' : $link.'<span class="badge badge-pill badge-danger"><i class="fa fa-times"></i></span></a>';
|
|
})
|
|
->addColumn('active', function (User $user) {
|
|
if ($user->trashed()) {
|
|
$date = Carbon::parse(now())->addDays(10)->format('d.m.Y H:i');
|
|
$email = str_replace('delete-', '', $user->email);
|
|
$link = '<a href="#" data-toggle="modal" data-target="#modals-restore" data-id="'.$user->id.'" data-email="'.$email.'" data-active="'.$user->active.'" data-payment_account="'.$date.'">';
|
|
|
|
return $link.'<span class="badge badge-pill badge-info"><i class="fa fa-undo"></i> Account reaktivieren</span></a>';
|
|
}
|
|
$date = $user->getActiveDateFormat();
|
|
$link = '<a href="#" data-toggle="modal" data-target="#modals-active" data-id="'.$user->id.'" data-email="'.$user->email.'" data-active="'.$user->active.'" data-active_date="'.$date.'">';
|
|
|
|
return $user->active ? $link.'<span class="badge badge-pill badge-success"><i class="fa fa-check"></i> '.$date.'</span></a>' : $link.'<span class="badge badge-pill badge-danger"><i class="fa fa-times"></i></span></a>';
|
|
})
|
|
->addColumn('account', function (User $user) {
|
|
$date = $user->getPaymentAccountDateFormat();
|
|
$link = '<a href="#" data-toggle="modal" data-target="#modals-account" data-id="'.$user->id.'" data-email="'.$user->email.'" data-payment_account="'.$date.'">';
|
|
if ($user->payment_account) {
|
|
if ($user->isActiveAccount()) {
|
|
return $link.'<span class="badge badge-pill badge-success"><i class="fa fa-check"></i> '.$date.'</span></a>';
|
|
}
|
|
|
|
return $link.'<span class="badge badge-pill badge-warning"><i class="fa fa-ban"></i> '.$date.'</span></a>';
|
|
}
|
|
|
|
return $link.'<span class="badge badge-pill badge-danger"><i class="fa fa-times"></i></span></a>';
|
|
})
|
|
->addColumn('shop', function (User $user) {
|
|
$date = $user->getPaymentShopDateFormat();
|
|
$link = '<a href="#" data-toggle="modal" data-target="#modals-shop" data-id="'.$user->id.'" data-email="'.$user->email.'" data-payment_shop="'.$date.'">';
|
|
if ($user->payment_shop) {
|
|
if ($user->isActiveShop()) {
|
|
return $link.'<span class="badge badge-pill badge-success"><i class="fa fa-check"></i> '.$date.'</span></a>';
|
|
}
|
|
|
|
return $link.'<span class="badge badge-pill badge-warning"><i class="fa fa-ban"></i> '.$date.'</span></a>';
|
|
}
|
|
|
|
return $link.'<span class="badge badge-pill badge-danger"><i class="fa fa-times"></i></span></a>';
|
|
})
|
|
->addColumn('shop_domain', function (User $user) {
|
|
return $user->shop ? '<a href="'.$user->shop->getSubdomain(false).'" target="_blank">'.$user->shop->getSubdomain(false).'</a>' : '';
|
|
})
|
|
->addColumn('since', function (User $user) {
|
|
if ($user->shop) {
|
|
if ($user->shop->active) {
|
|
return $user->shop->getActiveDateFormatSmall();
|
|
}
|
|
|
|
return $user->shop->getActiveDateFormatSmall();
|
|
}
|
|
|
|
return '-';
|
|
})
|
|
->addColumn('country', function (User $user) {
|
|
return ($user->account && $user->account->country) ? $user->account->country->de : '';
|
|
})
|
|
->addColumn('my_payment_methods', function (User $user) {
|
|
$payment_methods = json_encode($user->payment_methods);
|
|
$link = '<a href="#" data-toggle="modal" data-target="#modals-payment_methods" data-id="'.$user->id.'" data-email="'.$user->email.'" data-payment_methods="'.htmlspecialchars($payment_methods).'">';
|
|
if (! $user->payment_methods) {
|
|
return $link.'<span class="badge badge-pill badge-danger"><i class="fa fa-times"></i></span></a>';
|
|
}
|
|
|
|
return $link.'<span class="badge badge-pill badge-success"><i class="fa fa-check"></i> '.$user->getPaymentMethodsShort().'</span></a>';
|
|
})
|
|
->addColumn('action_login', function (User $user) {
|
|
return '<a href="'.route('admin_user_login_as', [$user->id]).'" class="btn icon-btn btn-sm btn-warning" onclick="return confirm(\''.__('Login as User?').'\');"><span class="fa fa-sign-in-alt"></span></a>';
|
|
})
|
|
->addColumn('action_delete', function (User $user) {
|
|
return '<a class="btn icon-btn btn-sm btn-danger" href="#" data-toggle="modal" data-target="#modals-user-delete" data-id="'.$user->id.'" data-email="'.$user->email.'"><span class="fa fa-trash"></span></a>';
|
|
})
|
|
->addColumn('test_mode', function (User $user) {
|
|
$link = '<a href="#" data-toggle="modal" data-target="#modals-test_mode" data-id="'.$user->id.'" data-email="'.$user->email.'" data-test_mode="'.$user->test_mode.'">';
|
|
|
|
return $user->test_mode ? $link.'<span class="badge badge-pill badge-success"><i class="fa fa-check"></i></span></a>' : $link.'<span class="badge badge-pill badge-danger"><i class="fa fa-times"></i></span></a>';
|
|
})
|
|
->orderColumn('id', 'id $1')
|
|
->orderColumn('email', 'email $1')
|
|
->orderColumn('confirmed', 'confirmed $1')
|
|
->orderColumn('active', 'active $1')
|
|
->orderColumn('shop', 'shop $1')
|
|
->orderColumn('admin', 'active $1')
|
|
->rawColumns(['id', 'email', 'admin', 'confirmed', 'active', 'account', 'shop', 'shop_domain', 'my_payment_methods', 'test_mode', 'action_login', 'action_delete'])
|
|
->make(true);
|
|
}
|
|
}
|