add spaces
This commit is contained in:
233
src/main/kotlin/space/luminic/budgerapp/services/SpaceService.kt
Normal file
233
src/main/kotlin/space/luminic/budgerapp/services/SpaceService.kt
Normal file
@@ -0,0 +1,233 @@
|
||||
package space.luminic.budgerapp.services
|
||||
|
||||
import org.bson.types.ObjectId
|
||||
import org.springframework.data.domain.Sort
|
||||
import org.springframework.data.domain.Sort.Direction
|
||||
import org.springframework.security.core.context.ReactiveSecurityContextHolder
|
||||
import org.springframework.stereotype.Service
|
||||
import reactor.core.publisher.Mono
|
||||
import space.luminic.budgerapp.models.Space
|
||||
import space.luminic.budgerapp.models.SpaceInvite
|
||||
import space.luminic.budgerapp.models.Transaction
|
||||
import space.luminic.budgerapp.repos.BudgetRepo
|
||||
import space.luminic.budgerapp.repos.SpaceRepo
|
||||
import space.luminic.budgerapp.repos.UserRepo
|
||||
import java.time.LocalDateTime
|
||||
import java.util.UUID
|
||||
|
||||
@Service
|
||||
class SpaceService(
|
||||
private val spaceRepo: SpaceRepo,
|
||||
private val userService: UserService,
|
||||
private val budgetRepo: BudgetRepo,
|
||||
private val userRepo: UserRepo
|
||||
) {
|
||||
|
||||
fun isValidRequest(spaceId: String): Mono<Space> {
|
||||
return ReactiveSecurityContextHolder.getContext()
|
||||
.map { it.authentication }
|
||||
.flatMap { authentication ->
|
||||
val username = authentication.name
|
||||
// Получаем пользователя по имени
|
||||
userService.getByUsername(username)
|
||||
.switchIfEmpty(Mono.error(IllegalArgumentException("User not found for username: $username")))
|
||||
.flatMap { user ->
|
||||
// Получаем пространство по ID
|
||||
spaceRepo.findById(spaceId)
|
||||
.switchIfEmpty(Mono.error(IllegalArgumentException("Space not found for id: $spaceId")))
|
||||
.flatMap { space ->
|
||||
// Проверяем доступ пользователя к пространству
|
||||
if (space.users.none { it.id.toString() == user.id }) {
|
||||
return@flatMap Mono.error<Space>(IllegalArgumentException("User does not have access to this Space"))
|
||||
}
|
||||
// Если проверка прошла успешно, возвращаем пространство
|
||||
Mono.just(space)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getSpaces(): Mono<List<Space>> {
|
||||
return ReactiveSecurityContextHolder.getContext()
|
||||
.map { it.authentication }
|
||||
.flatMap { authentication ->
|
||||
val username = authentication.name
|
||||
userService.getByUsername(username)
|
||||
.switchIfEmpty(Mono.error(IllegalArgumentException("User not found for username: $username")))
|
||||
.flatMapMany { user ->
|
||||
spaceRepo.findByArrayElement(ObjectId(user.id!!))
|
||||
}
|
||||
.collectList() // Возвращаем Mono<List<Space>>
|
||||
}
|
||||
}
|
||||
|
||||
fun getSpace(spaceId: String): Mono<Space> {
|
||||
return spaceRepo.findById(spaceId)
|
||||
.switchIfEmpty(Mono.error(IllegalArgumentException("SpaceId not found for spaceId: $spaceId")))
|
||||
}
|
||||
|
||||
fun createSpace(space: Space): Mono<Space> {
|
||||
return ReactiveSecurityContextHolder.getContext()
|
||||
.map { it.authentication }
|
||||
.flatMap { authentication ->
|
||||
val username = authentication.name
|
||||
userService.getByUsername(username)
|
||||
.switchIfEmpty(Mono.error(IllegalArgumentException("User not found for username: $username")))
|
||||
.flatMap { user ->
|
||||
space.owner = user
|
||||
space.users.add(user)
|
||||
spaceRepo.save(space)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun deleteSpace(spaceId: String): Mono<Void> {
|
||||
return budgetRepo.findBySpaceId(ObjectId(spaceId), Sort.by(Direction.DESC, "dateFrom"))
|
||||
.flatMap { budget ->
|
||||
budgetRepo.delete(budget) // Удаляем все бюджеты, связанные с этим Space
|
||||
}
|
||||
.then(spaceRepo.deleteById(spaceId)) // Затем удаляем сам Space
|
||||
}
|
||||
|
||||
|
||||
fun createInviteSpace(spaceId: String): Mono<SpaceInvite> {
|
||||
return ReactiveSecurityContextHolder.getContext()
|
||||
.map { it.authentication }
|
||||
.flatMap { authentication ->
|
||||
val username = authentication.name
|
||||
userService.getByUsername(username)
|
||||
.switchIfEmpty(Mono.error(IllegalArgumentException("User not found for username: $username")))
|
||||
.flatMap { user ->
|
||||
spaceRepo.findById(spaceId)
|
||||
.switchIfEmpty(Mono.error(IllegalArgumentException("Space not found for id: $spaceId")))
|
||||
.flatMap { space ->
|
||||
if (space.users.none { it.id.toString() == user.id }) {
|
||||
return@flatMap Mono.error<SpaceInvite>(IllegalArgumentException("User does not have access to this Space"))
|
||||
}
|
||||
|
||||
val invite = SpaceInvite(
|
||||
UUID.randomUUID().toString().split("-")[0],
|
||||
user,
|
||||
LocalDateTime.now().plusHours(1),
|
||||
|
||||
)
|
||||
space.invites.add(invite)
|
||||
|
||||
// Сохраняем изменения и возвращаем созданное приглашение
|
||||
spaceRepo.save(space).thenReturn(invite)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun acceptInvite(code: String): Mono<Space> {
|
||||
return ReactiveSecurityContextHolder.getContext()
|
||||
.map { it.authentication }
|
||||
.flatMap { authentication ->
|
||||
val username = authentication.name
|
||||
userService.getByUsername(username)
|
||||
.switchIfEmpty(Mono.error(IllegalArgumentException("User not found for username: $username")))
|
||||
.flatMap { user ->
|
||||
spaceRepo.findSpaceByInvites(code)
|
||||
.switchIfEmpty(Mono.error(IllegalArgumentException("Space with invite code: $code not found")))
|
||||
.flatMap { space ->
|
||||
val invite = space.invites.find { it.code == code }
|
||||
|
||||
// Проверяем, есть ли инвайт и не истек ли он
|
||||
if (invite == null || invite.activeTill.isBefore(LocalDateTime.now())) {
|
||||
return@flatMap Mono.error<Space>(IllegalArgumentException("Invite is invalid or expired"))
|
||||
}
|
||||
|
||||
// Проверяем, не является ли пользователь уже участником
|
||||
if (space.users.any { it.id == user.id }) {
|
||||
return@flatMap Mono.error<Space>(IllegalArgumentException("User is already a member of this Space"))
|
||||
}
|
||||
|
||||
// Добавляем пользователя и удаляем использованный инвайт
|
||||
space.users.add(user)
|
||||
space.invites.remove(invite)
|
||||
|
||||
spaceRepo.save(space)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun leaveSpace(spaceId: String): Mono<Void> {
|
||||
return ReactiveSecurityContextHolder.getContext()
|
||||
.map { it.authentication }
|
||||
.flatMap { authentication ->
|
||||
val username = authentication.name
|
||||
userService.getByUsername(username)
|
||||
.switchIfEmpty(Mono.error(IllegalArgumentException("User not found for username: $username")))
|
||||
.flatMap { user ->
|
||||
spaceRepo.findById(spaceId)
|
||||
.switchIfEmpty(Mono.error(IllegalArgumentException("Space not found for id: $spaceId")))
|
||||
.flatMap { space ->
|
||||
if (space.users.none { it.id.toString() == user.id }) {
|
||||
return@flatMap Mono.error<Void>(IllegalArgumentException("User does not have access to this Space"))
|
||||
}
|
||||
// Удаляем пользователя из массива
|
||||
space.users.removeIf { it.id == user.id }
|
||||
// Сохраняем изменения
|
||||
spaceRepo.save(space).then() // .then() для Mono<Void>
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun kickMember(spaceId: String, kickedUsername: String): Mono<Void> {
|
||||
return ReactiveSecurityContextHolder.getContext()
|
||||
.map { it.authentication }
|
||||
.flatMap { authentication ->
|
||||
val username = authentication.name
|
||||
// Получаем текущего пользователя
|
||||
userService.getByUsername(username)
|
||||
.switchIfEmpty(Mono.error(IllegalArgumentException("User not found for username: $username")))
|
||||
.flatMap { user ->
|
||||
// Получаем пользователя, которого нужно исключить
|
||||
userService.getByUsername(kickedUsername)
|
||||
.switchIfEmpty(Mono.error(IllegalArgumentException("User not found for username: $kickedUsername")))
|
||||
.flatMap { kickedUser ->
|
||||
// Получаем пространство
|
||||
spaceRepo.findById(spaceId)
|
||||
.switchIfEmpty(Mono.error(IllegalArgumentException("Space not found for id: $spaceId")))
|
||||
.flatMap { space ->
|
||||
// Проверяем, является ли текущий пользователь владельцем
|
||||
if (space.owner?.id != user.id) {
|
||||
return@flatMap Mono.error<Void>(IllegalArgumentException("Only owners allowed for this action"))
|
||||
}
|
||||
|
||||
// Проверяем, что пользователь, которого нужно исключить, присутствует в списке пользователей
|
||||
val userToKick = space.users.find { it.username == kickedUsername }
|
||||
if (userToKick != null) {
|
||||
// Удаляем пользователя из пространства
|
||||
space.users.removeIf { it.username == kickedUsername }
|
||||
// Сохраняем изменения
|
||||
return@flatMap spaceRepo.save(space).then()
|
||||
} else {
|
||||
return@flatMap Mono.error<Void>(IllegalArgumentException("User not found in this space"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fun regenSpaces(): Mono<List<Space>> {
|
||||
// return spaceRepo.findAll()
|
||||
// .flatMap { space ->
|
||||
// userService.getUsers()
|
||||
// .flatMap { users ->
|
||||
// if (users.isEmpty()) {
|
||||
// return@flatMap Mono.error<Space>(IllegalStateException("No users found"))
|
||||
// }
|
||||
// val updatedSpace = space.copy(owner = users.first()) // Создаем копию (если `Space` data class)
|
||||
// spaceRepo.save(updatedSpace)
|
||||
// }
|
||||
// }
|
||||
// .collectList()
|
||||
// }
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user