mivita/app/Http/Controllers/AdminUserController.php
Kevin ac3bd6e8ea Statistiken/Abo: Kundenfeedback 2026-07-24 komplett umgesetzt + Steuern: DATEV-Fixes 08+09/2025 (Sammel-Commit Branch-WIP)
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>
2026-07-24 13:56:02 +00:00

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);
}
}