resolveRole($payload); $user = $this->resolveOrCreateUser($payload, $role); $userId = (int) $user->id; $roleName = (string) $role->name; $activeRole = strtolower($roleName); if (! empty($payload['status']) && strtolower((string) $payload['status']) === 'inactive') { $activeRole = 'inactive'; } $schoolYear = (string) ($payload['school_year'] ?? $this->configService->getSchoolYear() ?? ''); DB::table('user_roles')->updateOrInsert( ['user_id' => $userId, 'role_id' => (int) $role->id], ['created_at' => now(), 'updated_at' => now()] ); $staff = Staff::query()->updateOrCreate([ 'user_id' => $userId, ], [ 'firstname' => (string) $payload['firstname'], 'lastname' => (string) $payload['lastname'], 'email' => (string) $payload['email'], 'phone' => $payload['phone'] ?? null, 'role_name' => $roleName, 'active_role' => $activeRole, 'school_year' => $schoolYear, 'updated_at' => now(), ]); if (! $staff) { throw new RuntimeException('Failed to create staff member.'); } return $staff; }); } public function update(Staff $staff, array $payload): Staff { return DB::transaction(function () use ($staff, $payload) { $role = array_key_exists('role_id', $payload) || array_key_exists('role_name', $payload) ? $this->resolveRole($payload) : null; $updates = []; foreach (['firstname', 'lastname', 'email', 'phone', 'school_year'] as $field) { if (array_key_exists($field, $payload) && $payload[$field] !== '') { $updates[$field] = $payload[$field]; } } if ($role) { $updates['role_name'] = (string) $role->name; $updates['active_role'] = strtolower((string) $updates['role_name']); DB::table('user_roles')->updateOrInsert( ['user_id' => (int) $staff->user_id, 'role_id' => (int) $role->id], ['created_at' => now(), 'updated_at' => now()] ); } if (! empty($payload['status']) && strtolower((string) $payload['status']) === 'inactive') { $updates['active_role'] = 'inactive'; } $updates['updated_at'] = now(); if (! empty($updates)) { $staff->fill($updates); $staff->save(); $userUpdates = array_intersect_key($updates, array_flip(['firstname', 'lastname', 'email', 'phone', 'school_year'])); if (isset($userUpdates['phone'])) { $userUpdates['cellphone'] = $userUpdates['phone']; unset($userUpdates['phone']); } if ($userUpdates !== []) { User::query()->whereKey((int) $staff->user_id)->update($userUpdates + ['updated_at' => now()]); } } return $staff->fresh(); }); } public function delete(Staff $staff): bool { return (bool) $staff->delete(); } private function resolveRole(array $payload): Role { if (! empty($payload['role_id'])) { $role = Role::query()->whereKey((int) $payload['role_id'])->where('is_active', 1)->first(); if ($role) { return $role; } } $roleName = trim((string) ($payload['role_name'] ?? '')); if ($roleName !== '') { $role = Role::query() ->where('is_active', 1) ->where(function ($query) use ($roleName) { $query->whereRaw('LOWER(name) = ?', [strtolower($roleName)]) ->orWhereRaw('LOWER(slug) = ?', [strtolower($roleName)]); }) ->first(); if ($role) { return $role; } } throw new RuntimeException('A valid active role is required.'); } private function resolveOrCreateUser(array $payload, Role $role): User { if (! empty($payload['user_id'])) { $user = User::query()->find((int) $payload['user_id']); if (! $user) { throw new RuntimeException('The selected user was not found.'); } } else { $email = strtolower(trim((string) ($payload['email'] ?? ''))); if ($email === '') { throw new RuntimeException('A valid email is required.'); } $user = User::query()->whereRaw('LOWER(email) = ?', [$email])->first() ?? new User(); } $isNew = ! $user->exists; $user->firstname = (string) $payload['firstname']; $user->lastname = (string) $payload['lastname']; $user->email = strtolower(trim((string) $payload['email'])); $user->cellphone = $payload['phone'] ?? $user->cellphone ?? null; $user->school_year = (string) ($payload['school_year'] ?? $this->configService->getSchoolYear() ?? ''); $user->semester = $user->semester ?: (string) ($this->configService->getSemester() ?? ''); $user->status = ! empty($payload['status']) && strtolower((string) $payload['status']) === 'inactive' ? 'Inactive' : 'Active'; $user->is_verified = 1; $user->is_suspended = 0; $user->accept_school_policy = $user->accept_school_policy ?? 1; $user->school_id = $user->school_id ?: random_int(100000, 999999); if ($isNew) { $password = (string) ($payload['password'] ?? ''); if ($password === '') { throw new RuntimeException('A temporary password is required for a new staff user.'); } $user->password = Hash::make($password); } $user->user_type = (string) $role->name; $user->save(); return $user; } }