mtUtil = $mtUtil; } protected function authorizeManage() { if (! auth()->user()->can('managementtools.access') || ! auth()->user()->can('managementtools.manage_scores')) { abort(403, 'Unauthorized action.'); } } protected function authorizeViewOwn() { if (! auth()->user()->can('managementtools.score_view_own') && ! auth()->user()->can('managementtools.manage_scores')) { abort(403, 'Unauthorized action.'); } } /** * Admin: manage score cards + assign scores. */ public function index(Request $request) { $this->authorizeManage(); $business_id = (int) $request->session()->get('user.business_id'); if ($request->ajax() && $request->get('table') === 'assignments') { $scores = MtUserScore::forBusiness($business_id) ->with(['user', 'task', 'scoreCard']) ->select('mt_user_scores.*'); if ($request->filled('user_id')) { $scores->where('user_id', (int) $request->user_id); } return DataTables::of($scores) ->addColumn('employee', function ($row) { return $row->user ? trim($row->user->first_name.' '.($row->user->last_name ?? '')) : '—'; }) ->addColumn('card_preview', function ($row) { if ($row->scoreCard) { return view('managementtools::score_cards.partials.card_badge', ['card' => $row->scoreCard])->render(); } return ''.$row->typeLabel().''; }) ->addColumn('points_fmt', fn ($row) => $row->displayPoints()) ->addColumn('task_title', fn ($row) => $row->task ? e($row->task->title) : '—') ->addColumn('action', function ($row) { $html = '
'; $html .= ''; $html .= ' '; $html .= '
'; return $html; }) ->editColumn('description', fn ($row) => e(\Str::limit($row->description, 80))) ->editColumn('created_at', fn ($row) => $this->mtUtil->formatDateTime($row->created_at)) ->rawColumns(['card_preview', 'action']) ->make(true); } $users = User::forDropdown($business_id, true); $cards = MtScoreCard::forBusiness($business_id)->active()->ordered()->get(); return view('managementtools::scores.index', compact('users', 'cards')); } /** * Employee: view own score cards. */ public function myScores(Request $request) { $this->authorizeViewOwn(); $business_id = (int) $request->session()->get('user.business_id'); $user_id = auth()->id(); $scores = MtUserScore::forBusiness($business_id) ->where('user_id', $user_id) ->with(['scoreCard', 'creator', 'task']) ->orderByDesc('created_at') ->paginate(20); $total_points = MtUserScore::forBusiness($business_id) ->where('user_id', $user_id) ->get() ->sum(function ($s) { return $s->scoreCard ? (float) $s->scoreCard->points : (float) $s->score; }); return view('managementtools::scores.my', compact('scores', 'total_points')); } public function create() { $this->authorizeManage(); $business_id = (int) request()->session()->get('user.business_id'); $users = User::forDropdown($business_id, true); $tasks = MtUserTask::forBusiness($business_id)->orderBy('title')->pluck('title', 'id'); $cards = MtScoreCard::forBusiness($business_id)->active()->ordered()->get(); return view('managementtools::scores.create', compact('users', 'tasks', 'cards')); } public function store(Request $request) { $this->authorizeManage(); $business_id = (int) $request->session()->get('user.business_id'); $request->validate([ 'user_id' => 'required|integer|exists:users,id', 'score_card_id' => 'required|integer|exists:mt_score_cards,id', 'description' => 'nullable|string|max:1000', 'task_id' => 'nullable|integer|exists:mt_user_tasks,id', ]); $card = MtScoreCard::forBusiness($business_id)->findOrFail($request->score_card_id); MtUserScore::create([ 'business_id' => $business_id, 'user_id' => $request->user_id, 'score_card_id' => $card->id, 'score' => $card->points, 'type' => $card->points >= 0 ? '1' : '2', 'description' => $request->description, 'task_id' => $request->task_id ?: null, 'created_by' => auth()->id(), ]); return response()->json(['success' => true, 'msg' => __('managementtools::lang.score_record_added')]); } public function edit($id) { $this->authorizeManage(); $business_id = (int) request()->session()->get('user.business_id'); $score = MtUserScore::forBusiness($business_id)->findOrFail($id); $users = User::forDropdown($business_id, true); $tasks = MtUserTask::forBusiness($business_id)->orderBy('title')->pluck('title', 'id'); $cards = MtScoreCard::forBusiness($business_id)->active()->ordered()->get(); return view('managementtools::scores.edit', compact('score', 'users', 'tasks', 'cards')); } public function update(Request $request, $id) { $this->authorizeManage(); $business_id = (int) $request->session()->get('user.business_id'); $score = MtUserScore::forBusiness($business_id)->findOrFail($id); $request->validate([ 'user_id' => 'required|integer|exists:users,id', 'score_card_id' => 'required|integer|exists:mt_score_cards,id', 'description' => 'nullable|string|max:1000', 'task_id' => 'nullable|integer|exists:mt_user_tasks,id', ]); $card = MtScoreCard::forBusiness($business_id)->findOrFail($request->score_card_id); $score->update([ 'user_id' => $request->user_id, 'score_card_id' => $card->id, 'score' => $card->points, 'type' => $card->points >= 0 ? '1' : '2', 'description' => $request->description, 'task_id' => $request->task_id ?: null, ]); return response()->json(['success' => true, 'msg' => __('managementtools::lang.score_record_updated')]); } public function destroy($id) { $this->authorizeManage(); $business_id = (int) request()->session()->get('user.business_id'); $score = MtUserScore::forBusiness($business_id)->findOrFail($id); $score->delete(); return response()->json(['success' => true, 'msg' => __('managementtools::lang.score_record_deleted')]); } }