acct_type, UserActions::ViewAllUserTypes)) { return Response::json(['error' => 'Unauthorized'], 401); } $currentUserType = $currentUser->acct_type; $allowedTypes = \App\Http\Controllers\Helpers\Permissions\UserTypeService::getAllowedUserTypes($currentUserType); $formatted = []; foreach ($allowedTypes as $case) { $label = str_replace('_', ' ', ucwords(strtolower($case->name))); $formatted[] = [$case->value, $label]; } return Response::json($formatted); } public static function listAllUsersforParentSelectHTML(Request $request, $dataResult = false) { $currentUser = \Hypervel\Support\Facades\Auth::user(); if (!$currentUser) { return Response::json([], 200); } // Ultimate accounts can see all users if ($currentUser->acct_type === UserTypes::ULTIMATE) { $allowedIds = null; } else { // Only show current user and their descendants (direct or indirect children) try { $descendants = $currentUser->getAllDescendants(); $allowedIds = $descendants->pluck('id')->toArray(); $allowedIds[] = $currentUser->id; } catch (\Throwable $th) { return Response::json([], 200); } } $excludeUser = $request->input('exclude_user', null); $typeFilter = $request->input('type', null); $usersQuery = User::select(['id', 'username', 'name', 'fullname', 'mobile_number', 'hashkey', 'acct_type']); if ($allowedIds !== null) { $usersQuery = $usersQuery->whereIn('id', $allowedIds); } // Exclude the specified user if provided if ($excludeUser) { $usersQuery = $usersQuery->where('hashkey', '!=', $excludeUser); } if ($typeFilter) { $types = is_array($typeFilter) ? $typeFilter : [$typeFilter]; $usersQuery = $usersQuery->whereIn('acct_type', $types); } $users = $usersQuery->get(); if (!$dataResult) { return Response::json($users); } else { return $users; } } public function CreateUser(Request $request) { $usertypeString = $request->input('type'); if (!is_string($usertypeString) || empty($usertypeString)) { return Response::json(['error' => 'User type is required'], 400); } $usertypeEnum = UserTypes::tryFrom($usertypeString); if (!$usertypeEnum) { return Response::json(['error' => 'Invalid User Type'], 400); } // Map UserTypes to specialized CreateUser UserActions $action = match ($usertypeEnum) { UserTypes::ULTIMATE => UserActions::CreateUserUltimate, UserTypes::SUPER_OPERATOR => UserActions::CreateUserSuperOperator, UserTypes::OPERATOR => UserActions::CreateUserOperator, UserTypes::COORDINATOR => UserActions::CreateUserCoordinator, UserTypes::SUPPLIER_OVERSEER => UserActions::CreateUserSupplierOverseer, UserTypes::WHOLESALE_BUYER => UserActions::CreateUserWholesaleBuyer, UserTypes::SUPPLIER => UserActions::CreateUserSupplier, UserTypes::STORE_OWNER => UserActions::CreateUserStoreOwner, UserTypes::STORE_MANAGER => UserActions::CreateUserStoreManager, UserTypes::USER => UserActions::CreateUserUser, UserTypes::RIDER => UserActions::CreateUserRider, UserTypes::POS_TERMINAL => UserActions::CreateUserPOSTerminal, UserTypes::AUDIT => UserActions::CreateUserAudit, default => UserActions::CreateUser, }; $currentUser = \Hypervel\Support\Facades\Auth::user(); $targetParentHash = $request->input('parent'); if (!$currentUser) { return Response::json(['error' => 'Unauthorized'], 401); } $currentUserType = $currentUser->acct_type; if (!($currentUserType instanceof UserTypes)) { $currentUserType = UserTypes::tryFrom($currentUserType) ?? UserTypes::PUBLIC; } if ($currentUserType !== UserTypes::ULTIMATE) { // Check the new user's type is in the allowed list for this creator $allowedTypes = \App\Http\Controllers\Helpers\Permissions\UserTypeService::getAllowedUserTypes($currentUserType); if (!in_array($usertypeEnum, $allowedTypes)) { return Response::json(['error' => 'You are not allowed to create this user type.'], 401); } // Check that the chosen parent is the current user or a descendant if ($targetParentHash) { $isParentSelfOrDescendant = ($currentUser->hashkey === $targetParentHash) || UserPermissions::isDescendantOfCurrentUser($targetParentHash); if (!$isParentSelfOrDescendant) { return Response::json(['error' => 'Parent user is not in your hierarchy.'], 401); } } } $mobileRules = ['required', 'string', 'max:20', 'unique:users,mobile_number']; if (!UserPermissions::isActionPermitted($currentUser->acct_type, UserActions::BypassMobileNumberFormat)) { $mobileRules[] = 'regex:/^(09|\+639)\d{9}$/'; } try { $validated = $request->validate([ 'username' => 'required|string|max:255|unique:users,username', 'name' => 'required|string|max:255', 'fullname' => 'nullable|string|max:255', 'mobile_number' => $mobileRules, 'password' => 'required|string|min:6', 'nickname' => 'nullable|string|max:255', 'parent' => 'required|string', 'type' => 'required|string', ]); } catch (\Hypervel\Validation\ValidationException $e) { return Response::json(['errors' => $e->errors()], 422); } $parentUser = User::where('hashkey', $validated['parent'])->first(); if (!$parentUser) { return Response::json(['error' => 'Parent user not found'], 404); } $parent = $parentUser->id; $user = new User(); $user->username = $validated['username']; $user->name = $validated['name']; $user->fullname = $validated['fullname'] ?? null; $user->mobile_number = $validated['mobile_number']; $user->password = Hash::make($validated['password']); $user->nickname = $validated['nickname'] ?? null; $user->parentuid = $parent; $user->acct_type = $validated['type']; $user->active = true; $user->save(); return Response::json(['success' => true, 'hashkey' => $user->hashkey, 'message' => 'User created successfully'], 201); } public function checkIfUserMobileNumberExists(Request $request) { $request->validate([ 'mobile_number' => 'required|string', ]); $mobileNumber = $request->input('mobile_number'); $userExists = User::where('mobile_number', $mobileNumber)->exists(); return Response::json(['exists' => $userExists]); } public function checkIfUsernameExists(Request $request) { $request->validate([ 'username' => 'required|string', ]); $username = $request->input('username'); $userExists = User::where('username', $username)->exists(); return Response::json(['exists' => $userExists]); } public function publicRegisterUser(Request $request) { try { $validated = $request->validate([ 'name' => 'required|string|max:255', 'mobile_number' => 'required|string|max:20|unique:users,mobile_number|regex:/^(09|\+639)\d{9}$/', 'password' => 'required|string|min:6', 'nickname' => 'nullable|string|max:255', ]); } catch (\Hypervel\Validation\ValidationException $e) { return Response::json(['success' => false, 'errors' => $e->errors()], 422); } $parent = User::where('acct_type', UserTypes::ULTIMATE->value)->orderBy('id')->first(); if (!$parent) { $parent = User::where('acct_type', UserTypes::COORDINATOR->value)->orderBy('id')->first(); } if (!$parent) { $parent = User::orderBy('id')->first(); } if (!$parent) { return Response::json(['success' => false, 'message' => 'No valid parent user found'], 500); } $user = new User(); $user->name = $validated['name']; $user->mobile_number = $validated['mobile_number']; $user->password = Hash::make($validated['password']); $user->nickname = $validated['nickname'] ?? null; $user->parentuid = $parent->id; $user->acct_type = 'user'; $user->active = true; $user->save(); return Response::json(['success' => true, 'hashkey' => $user->hashkey, 'message' => 'Account created successfully. Please log in.'], 201); } public function publicCheckMobileNumber(Request $request) { $request->validate([ 'mobile_number' => 'required|string', ]); return Response::json(['exists' => User::where('mobile_number', $request->input('mobile_number'))->exists()]); } }