init
This commit is contained in:
@@ -1,149 +1,75 @@
|
||||
package space.luminic.finance.services
|
||||
|
||||
import com.mongodb.client.model.Aggregates.sort
|
||||
import kotlinx.coroutines.reactive.awaitFirst
|
||||
import kotlinx.coroutines.reactive.awaitFirstOrNull
|
||||
import kotlinx.coroutines.reactive.awaitSingle
|
||||
import kotlinx.coroutines.reactive.awaitSingleOrNull
|
||||
import org.bson.types.ObjectId
|
||||
import org.springframework.data.domain.Sort
|
||||
import org.springframework.data.mongodb.core.ReactiveMongoTemplate
|
||||
import org.springframework.data.mongodb.core.aggregation.Aggregation.*
|
||||
import org.springframework.data.mongodb.core.aggregation.AggregationOperation
|
||||
|
||||
import org.springframework.data.mongodb.core.aggregation.ArrayOperators
|
||||
import org.springframework.data.mongodb.core.aggregation.ConvertOperators
|
||||
import org.springframework.data.mongodb.core.aggregation.VariableOperators
|
||||
import org.springframework.data.mongodb.core.query.Criteria
|
||||
import org.springframework.cache.annotation.CacheEvict
|
||||
import org.springframework.cache.annotation.Cacheable
|
||||
import org.springframework.jdbc.core.JdbcTemplate
|
||||
import org.springframework.stereotype.Service
|
||||
import org.springframework.transaction.annotation.Transactional
|
||||
import space.luminic.finance.dtos.SpaceDTO
|
||||
import space.luminic.finance.models.Budget
|
||||
import space.luminic.finance.models.NotFoundException
|
||||
import space.luminic.finance.models.Space
|
||||
import space.luminic.finance.models.User
|
||||
import space.luminic.finance.repos.SpaceRepo
|
||||
|
||||
@Service
|
||||
class SpaceServiceImpl(
|
||||
private val authService: AuthService,
|
||||
private val spaceRepo: SpaceRepo,
|
||||
private val mongoTemplate: ReactiveMongoTemplate,
|
||||
private val categoryService: CategoryService
|
||||
) : SpaceService {
|
||||
|
||||
private fun basicAggregation(user: User): List<AggregationOperation> {
|
||||
val addFieldsAsOJ = addFields()
|
||||
.addField("createdByOI")
|
||||
.withValue(ConvertOperators.valueOf("createdById").convertToObjectId())
|
||||
.addField("updatedByOI")
|
||||
.withValue(ConvertOperators.valueOf("updatedById").convertToObjectId())
|
||||
.build()
|
||||
val lookupCreatedBy = lookup("users", "createdByOI", "_id", "createdBy")
|
||||
val unwindCreatedBy = unwind("createdBy")
|
||||
|
||||
val lookupUpdatedBy = lookup("users", "updatedByOI", "_id", "updatedBy")
|
||||
val unwindUpdatedBy = unwind("updatedBy")
|
||||
|
||||
|
||||
|
||||
val matchCriteria = mutableListOf<Criteria>()
|
||||
matchCriteria.add(
|
||||
Criteria().orOperator(
|
||||
Criteria.where("ownerId").`is`(user.id),
|
||||
Criteria.where("participantsIds").`is`(user.id)
|
||||
)
|
||||
)
|
||||
matchCriteria.add(Criteria.where("isDeleted").`is`(false))
|
||||
val matchStage = match(Criteria().andOperator(*matchCriteria.toTypedArray()))
|
||||
|
||||
return listOf(addFieldsAsOJ, lookupCreatedBy, unwindCreatedBy, lookupUpdatedBy, unwindUpdatedBy, matchStage)
|
||||
override fun checkSpace(spaceId: Int): Space {
|
||||
return getSpace(spaceId)
|
||||
}
|
||||
|
||||
private fun ownerAndParticipantsLookups(): List<AggregationOperation>{
|
||||
val addOwnerAsOJ = addFields()
|
||||
.addField("ownerIdAsObjectId")
|
||||
.withValue(ConvertOperators.valueOf("ownerId").convertToObjectId())
|
||||
.addField("participantsIdsAsObjectId")
|
||||
.withValue(
|
||||
VariableOperators.Map.itemsOf("participantsIds")
|
||||
.`as`("id")
|
||||
.andApply(
|
||||
ConvertOperators.valueOf("$\$id").convertToObjectId()
|
||||
)
|
||||
)
|
||||
.build()
|
||||
val lookupOwner = lookup("users", "ownerIdAsObjectId", "_id", "owner")
|
||||
val unwindOwner = unwind("owner")
|
||||
val lookupUsers = lookup("users", "participantsIdsAsObjectId", "_id", "participants")
|
||||
return listOf(addOwnerAsOJ, lookupOwner, unwindOwner, lookupUsers)
|
||||
// @Cacheable(cacheNames = ["spaces"])
|
||||
override fun getSpaces(): List<Space> {
|
||||
val user = authService.getSecurityUserId()
|
||||
val spaces = spaceRepo.findSpacesAvailableForUser(user)
|
||||
return spaces
|
||||
}
|
||||
|
||||
override suspend fun checkSpace(spaceId: String): Space {
|
||||
override fun getSpace(id: Int): Space {
|
||||
val user = authService.getSecurityUserId()
|
||||
val space = spaceRepo.findSpaceById(id, user) ?: throw NotFoundException("Space with id $id not found")
|
||||
return space
|
||||
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun createSpace(space: SpaceDTO.CreateSpaceDTO): Int {
|
||||
val user = authService.getSecurityUser()
|
||||
val space = getSpace(spaceId)
|
||||
|
||||
// Проверяем доступ пользователя к пространству
|
||||
return if (space.participants!!.none { it.id.toString() == user.id }) {
|
||||
throw IllegalArgumentException("User does not have access to this Space")
|
||||
} else space
|
||||
}
|
||||
|
||||
override suspend fun getSpaces(): List<Space> {
|
||||
val user = authService.getSecurityUser()
|
||||
val basicAggregation = basicAggregation(user)
|
||||
val ownerAndParticipantsLookup = ownerAndParticipantsLookups()
|
||||
|
||||
val sort = sort(Sort.by(Sort.Direction.DESC, "createdAt"))
|
||||
val aggregation = newAggregation(
|
||||
*basicAggregation.toTypedArray(),
|
||||
*ownerAndParticipantsLookup.toTypedArray(),
|
||||
sort,
|
||||
)
|
||||
return mongoTemplate.aggregate(aggregation, "spaces", Space::class.java).collectList().awaitSingle()
|
||||
}
|
||||
|
||||
override suspend fun getSpace(id: String): Space {
|
||||
val user = authService.getSecurityUser()
|
||||
val basicAggregation = basicAggregation(user)
|
||||
val ownerAndParticipantsLookup = ownerAndParticipantsLookups()
|
||||
|
||||
val aggregation = newAggregation(
|
||||
*basicAggregation.toTypedArray(),
|
||||
*ownerAndParticipantsLookup.toTypedArray(),
|
||||
)
|
||||
return mongoTemplate.aggregate(aggregation, "spaces", Space::class.java).awaitFirstOrNull()
|
||||
?: throw NotFoundException("Space not found")
|
||||
|
||||
}
|
||||
|
||||
override suspend fun createSpace(space: SpaceDTO.CreateSpaceDTO): Space {
|
||||
val owner = authService.getSecurityUser()
|
||||
val createdSpace = Space(
|
||||
val creatingSpace = Space(
|
||||
name = space.name,
|
||||
ownerId = owner.id!!,
|
||||
|
||||
participantsIds = listOf(owner.id!!),
|
||||
|
||||
|
||||
)
|
||||
createdSpace.owner = owner
|
||||
createdSpace.participants?.toMutableList()?.add(owner)
|
||||
val savedSpace = spaceRepo.save(createdSpace).awaitSingle()
|
||||
owner = user,
|
||||
participants = setOf(user)
|
||||
)
|
||||
val userId = authService.getSecurityUserId()
|
||||
val savedSpace = spaceRepo.create(creatingSpace, userId)
|
||||
if (space.createBasicCategories) {
|
||||
categoryService.createEtalonCategoriesForSpace(savedSpace)
|
||||
}
|
||||
return savedSpace
|
||||
}
|
||||
|
||||
override suspend fun updateSpace(spaceId: String, space: SpaceDTO.UpdateSpaceDTO): Space {
|
||||
val existingSpace = spaceRepo.findById(spaceId).awaitFirstOrNull() ?: throw NotFoundException("Space not found")
|
||||
val updatedSpace = existingSpace.copy(
|
||||
@Transactional
|
||||
override fun updateSpace(
|
||||
spaceId: Int,
|
||||
space: SpaceDTO.UpdateSpaceDTO
|
||||
): Int {
|
||||
val userId = authService.getSecurityUserId()
|
||||
val existingSpace = getSpace(spaceId)
|
||||
val updatedSpace = Space(
|
||||
id = existingSpace.id,
|
||||
name = space.name,
|
||||
)
|
||||
updatedSpace.owner = existingSpace.owner
|
||||
updatedSpace.participants = existingSpace.participants
|
||||
return spaceRepo.save(updatedSpace).awaitFirst()
|
||||
owner = existingSpace.owner,
|
||||
participants = existingSpace.participants,
|
||||
isDeleted = existingSpace.isDeleted,
|
||||
createdBy = existingSpace.createdBy,
|
||||
createdAt = existingSpace.createdAt,
|
||||
)
|
||||
return spaceRepo.update(updatedSpace, userId)
|
||||
}
|
||||
|
||||
override suspend fun deleteSpace(spaceId: String) {
|
||||
val space = spaceRepo.findById(spaceId).awaitFirstOrNull() ?: throw NotFoundException("Space not found")
|
||||
space.isDeleted = true
|
||||
spaceRepo.save(space).awaitFirst()
|
||||
@Transactional
|
||||
override fun deleteSpace(spaceId: Int) {
|
||||
spaceRepo.delete(spaceId)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user