middleware('admin'); } public function index(string $tab = 'reviews'): View { abort_unless(in_array($tab, self::TABS, true), 404); return view('admin.customer_priority.index', [ 'tab' => $tab, 'counts' => $this->overview->counts(), ]); } public function reviewsDatatable(): JsonResponse { $back = route('admin_customer_priority', ['reviews']); return \DataTables::eloquent($this->overview->reviewsQuery()) ->addColumn('created', fn (ShoppingUser $customer): string => $customer->created_at->format('d.m.Y H:i') .'
'.$customer->created_at->diffForHumans().'') ->addColumn('customer', fn (ShoppingUser $customer): string => $this->customerCell($customer)) ->addColumn('member', fn (ShoppingUser $customer): string => $this->memberCell($customer->member)) ->addColumn('shop', fn (ShoppingUser $customer): string => $this->memberCell($customer->shopping_order?->user_shop?->user)) ->addColumn('matches', fn (ShoppingUser $customer): string => (string) count($customer->getNotice('like') ?: [])) ->addColumn('action', function (ShoppingUser $customer) use ($back): string { return ' ' .'
' .csrf_field() .'
'; }) ->filterColumn('customer', function ($query, $keyword): void { $query->where(function ($query) use ($keyword) { $query->where('billing_email', 'like', '%'.$keyword.'%') ->orWhere('billing_lastname', 'like', '%'.$keyword.'%') ->orWhere('billing_firstname', 'like', '%'.$keyword.'%') ->orWhere('billing_zipcode', 'like', '%'.$keyword.'%'); }); }) ->orderColumn('created', 'shopping_users.created_at $1') ->rawColumns(['created', 'customer', 'member', 'shop', 'action']) ->make(true); } public function conflictsDatatable(): JsonResponse { $back = route('admin_customer_priority', ['conflicts']); return \DataTables::of($this->overview->conflicts()) ->addColumn('customer', fn (array $row): string => ''.e($row['name']).'
'.e($row['email'])) ->addColumn('groups', function (array $row) use ($back): string { $html = ''; foreach ($row['groups'] as $group) { $html .= '
' .($group['oldest'] ? 'älteste Zuordnung ' : 'weitere Zuordnung ') .$this->memberCell($group['member']) .' · Kunden-Nr. '.e($group['number']).' · '.$group['entries'].' Einträge · zuletzt '.e(date('d.m.Y', strtotime($group['last_at']))).' ' .' ' .'' .'
'; } return $html; }) ->addColumn('last', fn (array $row): string => date('d.m.Y', strtotime($row['last_at']))) ->filter(function ($instance): void { $keyword = mb_strtolower((string) request('search.value')); if ($keyword !== '') { $instance->collection = $instance->collection->filter( fn (array $row) => str_contains($row['email'], $keyword) || str_contains(mb_strtolower($row['name']), $keyword) ); } }) ->rawColumns(['customer', 'groups']) ->make(true); } public function emailChangesDatatable(): JsonResponse { return \DataTables::eloquent($this->overview->emailChangesQuery()) ->addColumn('created', fn (ShoppingUserEmailChange $change): string => $change->created_at->format('d.m.Y H:i')) ->addColumn('customer', fn (ShoppingUserEmailChange $change): string => $change->shopping_user ? $this->customerCell($change->shopping_user) : 'Kunde #'.$change->shopping_user_id.' gelöscht') ->addColumn('change', fn (ShoppingUserEmailChange $change): string => e($change->old_email).' '.e($change->new_email).'') ->addColumn('requested_by', fn (ShoppingUserEmailChange $change): string => $this->memberCell($change->requested_by)) ->addColumn('status', function (ShoppingUserEmailChange $change): string { if ($change->blocked_at) { return 'abgelehnt (Kundenhoheit)
Adresse gehört einem anderen Berater oder Beraterkonto'; } return 'wartet auf Bestätigung
Link gültig bis '.$change->expires_at->format('d.m.Y H:i').''; }) ->addColumn('action', function (ShoppingUserEmailChange $change): string { if ($change->blocked_at) { return '
' .csrf_field().'
'; } return '
' .csrf_field().'
'; }) ->orderColumn('created', 'shopping_user_email_changes.created_at $1') ->rawColumns(['customer', 'change', 'requested_by', 'status', 'action']) ->make(true); } public function keepAssignment(int $id): RedirectResponse { $customer = ShoppingUser::where('is_like', true)->findOrFail($id); CustomerPriority::keepAssignment($customer); \Session()->flash('alert-success', 'Prüffall geschlossen, Zuordnung beibehalten.'); return redirect(route('admin_customer_priority', ['reviews'])); } public function resolveEmailChange(int $id, CustomerEmailChangeService $service): RedirectResponse { $service->resolveBlocked(ShoppingUserEmailChange::blockedOpen()->findOrFail($id), \Auth::id()); \Session()->flash('alert-success', 'Als erledigt markiert.'); return redirect(route('admin_customer_priority', ['email-changes'])); } public function discardEmailChange(int $id, CustomerEmailChangeService $service): RedirectResponse { $service->discard(ShoppingUserEmailChange::pending()->findOrFail($id)); \Session()->flash('alert-success', 'Anfrage verworfen.'); return redirect(route('admin_customer_priority', ['email-changes'])); } private function customerCell(ShoppingUser $customer): string { return '' .e(trim($customer->billing_firstname.' '.$customer->billing_lastname)).'' .($customer->number ? ' #'.e($customer->number).'' : '') .'
'.e($customer->billing_email) .'
'.e($customer->billing_zipcode.' '.$customer->billing_city).''; } private function memberCell(?User $member): string { if (! $member) { return '–'; } return ''.e($member->getFullName(false) ?: $member->email).'' .' #'.e($member->number).''; } }