startOfMonth(); $endOfMonth = Carbon::parse($selectedMonth)->endOfMonth(); return Administration::where('msnv', $user->msnv) ->whereBetween('date', [$startOfMonth, $endOfMonth]) ->orderBy('date', 'desc') ->paginate(10) ->withQueryString(); } public function getOtherActiveUsers(User $currentUser): Collection { return User::where('status', User::STATUS_ACTIVE) ->where('msnv', '!=', $currentUser->msnv) ->get(); } public function sendThankcards(User $sender, string $receiverMsnv, int $amount): void { if ($sender->flag_send == User::FLAG_SEND_DISABLED) { throw new \RuntimeException(__('messages.error.no_send_permission')); } $receiver = User::where('msnv', $receiverMsnv)->first(); if (!$receiver || $receiver->status != User::STATUS_ACTIVE) { throw new \RuntimeException(__('messages.error.receiver_invalid')); } $startOfMonth = Carbon::now()->startOfMonth(); $endOfMonth = Carbon::now()->endOfMonth(); $cardsSentToThisUserThisMonth = Administration::where('msnv', $sender->msnv) ->where('receiver', $receiverMsnv) ->whereBetween('date', [$startOfMonth, $endOfMonth]) ->sum('sent'); if ($cardsSentToThisUserThisMonth + $amount > Administration::MAX_SEND_CARD_PER_MONTH) { throw new \RuntimeException( __('messages.error.max_send_limit_template', [ 'max' => Administration::MAX_SEND_CARD_PER_MONTH, 'sent' => $cardsSentToThisUserThisMonth ]) ); } if ($sender->card < $amount) { throw new \RuntimeException(__('messages.error.not_enough_cards')); } DB::transaction(function () use ($sender, $receiverMsnv, $amount) { Administration::create([ 'msnv' => $receiverMsnv, 'received' => $amount, 'sender' => $sender->msnv, 'sent' => 0, 'receiver' => null, 'date' => Carbon::today(), ]); Administration::create([ 'msnv' => $sender->msnv, 'received' => 0, 'sender' => null, 'sent' => $amount, 'receiver' => $receiverMsnv, 'date' => Carbon::today(), ]); $sender->card -= $amount; $sender->save(); }); } public function updatePassword(User $user, string $newPassword): void { $user->pass = md5($newPassword); $user->first_login = User::FIRST_LOGIN_FALSE; $user->save(); } public function getPersonalStats(User $user, string $selectedMonth): array { $startOfMonth = Carbon::parse($selectedMonth)->startOfMonth(); $endOfMonth = Carbon::parse($selectedMonth)->endOfMonth(); $receivedCount = (int) Administration::where('msnv', $user->msnv) ->whereBetween('date', [$startOfMonth, $endOfMonth]) ->sum('received'); $sentCount = (int) Administration::where('msnv', $user->msnv) ->whereBetween('date', [$startOfMonth, $endOfMonth]) ->sum('sent'); // Calculate current rank (based on received) $rankings = User::where('status', User::STATUS_ACTIVE) ->addSelect([ 'score' => Administration::selectRaw('COALESCE(SUM(received), 0)') ->whereColumn('msnv', 'user.msnv') ->whereBetween('date', [$startOfMonth, $endOfMonth]) ]) ->orderByDesc('score') ->get(); $currentRank = 0; $prevScore = null; $rank = 1; $denseRank = 0; foreach ($rankings as $item) { $score = (int) $item->score; if ($score !== $prevScore) { $denseRank = $rank; $prevScore = $score; } if ($item->msnv == $user->msnv) { $currentRank = $denseRank; break; } $rank++; } return [ 'receivedCount' => $receivedCount, 'sentCount' => $sentCount, 'currentRank' => $currentRank ]; } public function getRankingList(string $type, string $selectedMonth, User $currentUser): array { $startOfMonth = Carbon::parse($selectedMonth)->startOfMonth(); $endOfMonth = Carbon::parse($selectedMonth)->endOfMonth(); $column = $type === 'sent' ? 'sent' : 'received'; $users = User::where('status', User::STATUS_ACTIVE) ->addSelect([ 'score' => Administration::selectRaw('COALESCE(SUM(' . $column . '), 0)') ->whereColumn('msnv', 'user.msnv') ->whereBetween('date', [$startOfMonth, $endOfMonth]) ]) ->orderByDesc('score') ->get(); $prevScore = null; $rank = 1; $denseRank = 0; $rankers = []; $currentUserRankItem = null; foreach ($users as $index => $userItem) { $score = (int) $userItem->score; if ($score !== $prevScore) { $denseRank = $rank; $prevScore = $score; } $userItem->rank = $denseRank; $userItem->score = $score; if ($userItem->msnv == $currentUser->msnv) { $currentUserRankItem = $userItem; } if ($index < 5) { $rankers[] = $userItem; } $rank++; } return [ 'rankers' => $rankers, 'currentUserRankItem' => $currentUserRankItem ]; } }