This commit is contained in:
xds
2025-02-23 12:24:34 +03:00
parent 363d926443
commit 416d818a1c
9 changed files with 129 additions and 114 deletions

View File

@@ -37,7 +37,7 @@ class AuthController(
fun getMe(@RequestHeader("Authorization") token: String): Mono<User> { fun getMe(@RequestHeader("Authorization") token: String): Mono<User> {
return authService.isTokenValid(token.removePrefix("Bearer ")) return authService.isTokenValid(token.removePrefix("Bearer "))
.flatMap { username -> .flatMap { username ->
userService.getByUserNameWoPass(username.username) userService.getByUserNameWoPass(username.username!!)
} }
} }
} }

View File

@@ -5,10 +5,8 @@ import org.springframework.http.HttpStatus
import org.springframework.http.ResponseEntity import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.* import org.springframework.web.bind.annotation.*
import org.springframework.web.client.HttpClientErrorException import org.springframework.web.client.HttpClientErrorException
import reactor.core.publisher.Flux
import reactor.core.publisher.Mono import reactor.core.publisher.Mono
import space.luminic.budgerapp.controllers.BudgetController.LimitValue import space.luminic.budgerapp.controllers.BudgetController.LimitValue
import space.luminic.budgerapp.controllers.dtos.BudgetCreationDTO
import space.luminic.budgerapp.models.* import space.luminic.budgerapp.models.*
import space.luminic.budgerapp.services.CategoryService import space.luminic.budgerapp.services.CategoryService
import space.luminic.budgerapp.services.FinancialService import space.luminic.budgerapp.services.FinancialService
@@ -103,10 +101,10 @@ class SpaceController(
@PostMapping("/{spaceId}/budgets") @PostMapping("/{spaceId}/budgets")
fun createBudget( fun createBudget(
@PathVariable spaceId: String, @PathVariable spaceId: String,
@RequestBody budgetCreationDTO: BudgetCreationDTO, @RequestBody budget: Budget
): Mono<Budget> { ): Mono<Budget> {
return spaceService.isValidRequest(spaceId).flatMap { return spaceService.isValidRequest(spaceId).flatMap {
financialService.createBudget(it, budgetCreationDTO.budget, budgetCreationDTO.createRecurrent) financialService.createBudget(it, budget)
} }
} }
@@ -304,7 +302,7 @@ class SpaceController(
} }
} }
@PostMapping("/{spaceId}/recurrent") @PostMapping("/{spaceId}/recurrents")
fun createRecurrent(@PathVariable spaceId: String, @RequestBody recurrent: Recurrent): Mono<Recurrent> { fun createRecurrent(@PathVariable spaceId: String, @RequestBody recurrent: Recurrent): Mono<Recurrent> {
return spaceService.isValidRequest(spaceId).flatMap { return spaceService.isValidRequest(spaceId).flatMap {
recurrentService.createRecurrent(it, recurrent) recurrentService.createRecurrent(it, recurrent)
@@ -312,7 +310,7 @@ class SpaceController(
} }
@PutMapping("/{spaceId}/recurrent/{id}") @PutMapping("/{spaceId}/recurrents/{id}")
fun editRecurrent( fun editRecurrent(
@PathVariable spaceId: String, @PathVariable spaceId: String,
@PathVariable id: String, @PathVariable id: String,

View File

@@ -14,7 +14,7 @@ class CategoryMapper : FromDocumentMapper {
override fun fromDocument(document: Document): Category { override fun fromDocument(document: Document): Category {
val categoryTypeDocument = document["type"] as Document val categoryTypeDocument = document["type"] as Document
val spaceDocument = document.get("spaceDetails", Document::class.java) ?: Document() val spaceDocument = document.get("spaceDetails", Document::class.java) ?: Document()
val spaceId = spaceDocument.get("_id", String::class.java)?:null val spaceId = spaceDocument.get("_id", ObjectId::class.java)?:null
val tags = document.getList("tags", Document::class.java) ?: emptyList() val tags = document.getList("tags", Document::class.java) ?: emptyList()
val categoryTags = tags.map { tag -> val categoryTags = tags.map { tag ->
@@ -22,7 +22,7 @@ class CategoryMapper : FromDocumentMapper {
}.toMutableSet() }.toMutableSet()
return Category( return Category(
id = (document["_id"] as ObjectId).toString(), id = (document["_id"] as ObjectId).toString(),
space = Space(id = spaceId), space = Space(id = spaceId.toString()),
type = CategoryType( type = CategoryType(
categoryTypeDocument["code"] as String, categoryTypeDocument["code"] as String,
categoryTypeDocument["name"] as String categoryTypeDocument["name"] as String

View File

@@ -1,19 +1,17 @@
package space.luminic.budgerapp.models package space.luminic.budgerapp.models
import com.fasterxml.jackson.annotation.JsonIgnore import com.fasterxml.jackson.annotation.JsonIgnore
import jakarta.validation.constraints.NotBlank
import org.springframework.data.annotation.Id import org.springframework.data.annotation.Id
import org.springframework.data.mongodb.core.mapping.Document import org.springframework.data.mongodb.core.mapping.Document
import java.time.LocalDate import java.time.LocalDate
import java.time.LocalDateTime import java.time.LocalDateTime
import java.util.Date
@Document("users") @Document("users")
data class User ( data class User(
@Id @Id
var id: String? = null, var id: String? = null,
@field:NotBlank val username: String, val username: String? = null,
var firstName: String, var firstName: String? = null,
var tgId: String? = null, var tgId: String? = null,
var tgUserName: String? = null, var tgUserName: String? = null,
@JsonIgnore // Скрывает пароль при сериализации @JsonIgnore // Скрывает пароль при сериализации

View File

@@ -27,7 +27,7 @@ class AuthService(
return userRepository.findByUsername(username) return userRepository.findByUsername(username)
.flatMap { user -> .flatMap { user ->
if (passwordEncoder.matches(password, user.password)) { if (passwordEncoder.matches(password, user.password)) {
val token = jwtUtil.generateToken(user.username) val token = jwtUtil.generateToken(user.username!!)
val expireAt = Date(System.currentTimeMillis() + 1000 * 60 * 60 * 24 * 10) val expireAt = Date(System.currentTimeMillis() + 1000 * 60 * 60 * 24 * 10)
tokenService.saveToken( tokenService.saveToken(
token = token, token = token,
@@ -48,7 +48,7 @@ class AuthService(
.switchIfEmpty(Mono.error(AuthException("Invalid credentials"))) .switchIfEmpty(Mono.error(AuthException("Invalid credentials")))
.flatMap { user -> .flatMap { user ->
println("here") println("here")
val token = jwtUtil.generateToken(user.username) val token = jwtUtil.generateToken(user.username!!)
val expireAt = Date(System.currentTimeMillis() + 1000 * 60 * 60 * 24 * 10) val expireAt = Date(System.currentTimeMillis() + 1000 * 60 * 60 * 24 * 10)
tokenService.saveToken( tokenService.saveToken(
token = token, token = token,

View File

@@ -17,6 +17,7 @@ import reactor.core.publisher.Flux
import reactor.core.publisher.Mono import reactor.core.publisher.Mono
import space.luminic.budgerapp.mappers.CategoryMapper import space.luminic.budgerapp.mappers.CategoryMapper
import space.luminic.budgerapp.models.* import space.luminic.budgerapp.models.*
import space.luminic.budgerapp.repos.BudgetRepo
import space.luminic.budgerapp.repos.CategoryRepo import space.luminic.budgerapp.repos.CategoryRepo
@Service @Service
@@ -24,16 +25,14 @@ class CategoryService(
private val categoryRepo: CategoryRepo, private val categoryRepo: CategoryRepo,
private val financialService: FinancialService, private val financialService: FinancialService,
private val mongoTemplate: ReactiveMongoTemplate, private val mongoTemplate: ReactiveMongoTemplate,
private val eventPublisher: ApplicationEventPublisher,
private val categoryMapper: CategoryMapper, private val categoryMapper: CategoryMapper,
private val budgetRepo: BudgetRepo,
) { ) {
private val logger = LoggerFactory.getLogger(javaClass) private val logger = LoggerFactory.getLogger(javaClass)
fun getCategory(id: String): Mono<Category> {
return categoryRepo.findById(id)
}
fun findCategory( fun findCategory(
space: Space? = null, space: Space? = null,
@@ -115,7 +114,7 @@ class CategoryService(
@Cacheable("categoryTypes") @Cacheable("categoryTypes")
fun getCategoryTypes(): List<CategoryType> { fun getCategoryTypes(): List<CategoryType> {
var types = mutableListOf<CategoryType>() val types = mutableListOf<CategoryType>()
types.add(CategoryType("EXPENSE", "Траты")) types.add(CategoryType("EXPENSE", "Траты"))
types.add(CategoryType("INCOME", "Поступления")) types.add(CategoryType("INCOME", "Поступления"))
return types return types
@@ -135,12 +134,13 @@ class CategoryService(
} }
fun deleteCategory(space: Space, categoryId: String): Mono<String> { fun deleteCategory(space: Space, categoryId: String): Mono<String> {
return findCategory(space, id = categoryId).switchIfEmpty( return findCategory(space, categoryId).switchIfEmpty(
Mono.error(IllegalArgumentException("Category with id: $categoryId not found")) Mono.error(IllegalArgumentException("Category with id: $categoryId not found"))
).flatMap { ).flatMap { categoryToDelete ->
financialService.getTransactions(space.id!!, categoryId = categoryId) financialService.getTransactions(space.id!!, categoryId = categoryId)
.flatMapMany { transactions -> .flatMapMany { transactions ->
findCategory(space, name = "Другое").switchIfEmpty( findCategory(space, name = "Другое")
.switchIfEmpty(
categoryRepo.save( categoryRepo.save(
Category( Category(
space = space, space = space,
@@ -150,15 +150,25 @@ class CategoryService(
icon = "🚮" icon = "🚮"
) )
) )
).flatMapMany { category -> )
.flatMapMany { otherCategory ->
Flux.fromIterable(transactions).flatMap { transaction -> Flux.fromIterable(transactions).flatMap { transaction ->
transaction.category = category // Присваиваем конкретный объект категории transaction.category = otherCategory
financialService.editTransaction(transaction) // Сохраняем изменения financialService.editTransaction(transaction)
} }
} }
} }
.then(categoryRepo.deleteById(categoryId)) // Удаляем старую категорию .then(
.thenReturn(categoryId) // Возвращаем удалённую категорию financialService.findProjectedBudgets(ObjectId(space.id))
.flatMapMany { budgets ->
Flux.fromIterable(budgets).flatMap { budget ->
budget.categories.removeIf { it.category.id == categoryId }
budgetRepo.save(budget)
}
}.collectList()
)
.then(categoryRepo.deleteById(categoryId)) // Удаление категории
.thenReturn(categoryId)
} }
} }

View File

@@ -1,6 +1,5 @@
package space.luminic.budgerapp.services package space.luminic.budgerapp.services
import com.mongodb.DBRef
import org.bson.BsonNull import org.bson.BsonNull
import org.bson.Document import org.bson.Document
import org.bson.types.ObjectId import org.bson.types.ObjectId
@@ -12,9 +11,7 @@ import org.springframework.data.domain.Sort.Direction
import org.springframework.data.mongodb.core.ReactiveMongoTemplate import org.springframework.data.mongodb.core.ReactiveMongoTemplate
import org.springframework.data.mongodb.core.aggregation.Aggregation.* import org.springframework.data.mongodb.core.aggregation.Aggregation.*
import org.springframework.data.mongodb.core.aggregation.DateOperators.DateToString import org.springframework.data.mongodb.core.aggregation.DateOperators.DateToString
import org.springframework.data.mongodb.core.aggregation.SortOperation
import org.springframework.data.mongodb.core.query.Criteria import org.springframework.data.mongodb.core.query.Criteria
import org.springframework.data.mongodb.core.query.Query
import org.springframework.security.core.context.ReactiveSecurityContextHolder import org.springframework.security.core.context.ReactiveSecurityContextHolder
import org.springframework.stereotype.Service import org.springframework.stereotype.Service
import reactor.core.publisher.Flux import reactor.core.publisher.Flux
@@ -36,7 +33,6 @@ class FinancialService(
val budgetRepo: BudgetRepo, val budgetRepo: BudgetRepo,
val warnRepo: WarnRepo, val warnRepo: WarnRepo,
val transactionsRepo: TransactionRepo, val transactionsRepo: TransactionRepo,
val recurrentService: RecurrentService,
val userService: UserService, val userService: UserService,
val reactiveMongoTemplate: ReactiveMongoTemplate, val reactiveMongoTemplate: ReactiveMongoTemplate,
private val categoryRepo: CategoryRepo, private val categoryRepo: CategoryRepo,
@@ -211,7 +207,6 @@ class FinancialService(
val unwindSpace = unwind("spaceDetails") val unwindSpace = unwind("spaceDetails")
val matchStage = match(Criteria.where("spaceDetails._id").`is`(spaceId)) val matchStage = match(Criteria.where("spaceDetails._id").`is`(spaceId))
// matchCriteria.add(Criteria.where("spaceDetails._id").`is`(ObjectId(spaceId))) // matchCriteria.add(Criteria.where("spaceDetails._id").`is`(ObjectId(spaceId)))
val projectStage = project("_id", "name", "dateFrom", "dateTo") // Оставляем только нужные поля
val sort = sortRequested?.let { sort(it) } ?: sort( val sort = sortRequested?.let { sort(it) } ?: sort(
Sort.by(Direction.DESC, "date").and(Sort.by(Direction.DESC, "createdAt")) Sort.by(Direction.DESC, "date").and(Sort.by(Direction.DESC, "createdAt"))
) )
@@ -229,11 +224,9 @@ class FinancialService(
spaceId: String, budgetId: String? = null, dateFrom: LocalDate? = null, dateTo: LocalDate? = null spaceId: String, budgetId: String? = null, dateFrom: LocalDate? = null, dateTo: LocalDate? = null
): Mono<Budget> { ): Mono<Budget> {
val lookupCategories = lookup("categories", "categories.category.\$id", "_id", "categoriesDetails") val lookupCategories = lookup("categories", "categories.category.\$id", "_id", "categoriesDetails")
val unwindCategories = unwind("categoriesDetails")
val lookupIncomeCategories = val lookupIncomeCategories =
lookup("categories", "incomeCategories.category.\$id", "_id", "incomeCategoriesDetails") lookup("categories", "incomeCategories.category.\$id", "_id", "incomeCategoriesDetails")
val unwindIncomeCategories = unwind("incomeCategoriesDetails")
val lookupSpace = lookup("spaces", "space.\$id", "_id", "spaceDetails") val lookupSpace = lookup("spaces", "space.\$id", "_id", "spaceDetails")
val unwindSpace = unwind("spaceDetails") val unwindSpace = unwind("spaceDetails")
val matchCriteria = mutableListOf<Criteria>() val matchCriteria = mutableListOf<Criteria>()
@@ -354,7 +347,7 @@ class FinancialService(
} }
fun createBudget(space: Space, budget: Budget, createRecurrent: Boolean): Mono<Budget> { fun createBudget(space: Space, budget: Budget): Mono<Budget> {
return Mono.zip(getBudgetByDate(budget.dateFrom, space.id!!).map { Optional.ofNullable(it) } return Mono.zip(getBudgetByDate(budget.dateFrom, space.id!!).map { Optional.ofNullable(it) }
.switchIfEmpty(Mono.just(Optional.empty())), .switchIfEmpty(Mono.just(Optional.empty())),
getBudgetByDate(budget.dateTo, space.id!!).map { Optional.ofNullable(it) } getBudgetByDate(budget.dateTo, space.id!!).map { Optional.ofNullable(it) }
@@ -367,21 +360,8 @@ class FinancialService(
return@flatMap Mono.error<Budget>(IllegalArgumentException("Бюджет с теми же датами найден")) return@flatMap Mono.error<Budget>(IllegalArgumentException("Бюджет с теми же датами найден"))
} }
// Получаем Space по spaceId
// Присваиваем Space бюджету
budget.space = space budget.space = space
// Если createRecurrent=true, создаем рекуррентные транзакции
val recurrentsCreation = if (createRecurrent) {
recurrentService.createRecurrentsForBudget(space, budget)
} else {
Mono.empty()
}
// Создаем бюджет после возможного создания рекуррентных транзакций
recurrentsCreation.then(
getCategoryTransactionPipeline( getCategoryTransactionPipeline(
space.id!!, space.id!!,
budget.dateFrom, budget.dateFrom,
@@ -395,7 +375,7 @@ class FinancialService(
// Логируем ошибку, если произошла // Логируем ошибку, если произошла
logger.error("Error during updateBudgetWarns: ${error.message}") logger.error("Error during updateBudgetWarns: ${error.message}")
}.subscribe() }.subscribe()
}).then( }.then(
getCategoryTransactionPipeline( getCategoryTransactionPipeline(
space.id!!, space.id!!,
budget.dateFrom, budget.dateFrom,
@@ -636,7 +616,7 @@ class FinancialService(
dateTo?.let { matchCriteria.add(Criteria.where("date").lt(it)) } dateTo?.let { matchCriteria.add(Criteria.where("date").lt(it)) }
transactionType?.let { matchCriteria.add(Criteria.where("type.code").`is`(it)) } transactionType?.let { matchCriteria.add(Criteria.where("type.code").`is`(it)) }
isDone?.let { matchCriteria.add(Criteria.where("isDone").`is`(it)) } isDone?.let { matchCriteria.add(Criteria.where("isDone").`is`(it)) }
categoryId?.let { matchCriteria.add(Criteria.where("categoryDetails._id").`is`(it)) } categoryId?.let { matchCriteria.add(Criteria.where("categoryDetails._id").`is`(ObjectId(it))) }
categoryType?.let { categoryType?.let {
matchCriteria.add( matchCriteria.add(
Criteria.where("categoryDetails.type.code").`is`(it) Criteria.where("categoryDetails.type.code").`is`(it)
@@ -1144,7 +1124,6 @@ class FinancialService(
private fun documentToTransactionMapper(document: Document): Transaction { private fun documentToTransactionMapper(document: Document): Transaction {
val transactionType = document["type"] as Document val transactionType = document["type"] as Document
var user: User?
val userDocument = document["userDetailed"] as Document val userDocument = document["userDetailed"] as Document
user = User( user = User(
@@ -1345,7 +1324,7 @@ class FinancialService(
fun getCategoryTransactionPipeline( fun getCategoryTransactionPipeline(
spaceId: String, dateFrom: LocalDate, dateTo: LocalDate, catType: String? = "EXPENSE" spaceId: String, dateFrom: LocalDate, dateTo: LocalDate, categoryType: String? = "EXPENSE"
): Mono<MutableList<BudgetCategory>> { ): Mono<MutableList<BudgetCategory>> {
val pipeline = listOf( val pipeline = listOf(
Document( Document(
@@ -1358,7 +1337,7 @@ class FinancialService(
"\$match", Document( "\$match", Document(
Document("spaceDetailed._id", ObjectId(spaceId)) Document("spaceDetailed._id", ObjectId(spaceId))
) )
), Document("\$match", Document("type.code", catType)), Document( ), Document("\$match", Document("type.code", categoryType)), Document(
"\$lookup", Document("from", "transactions").append( "\$lookup", Document("from", "transactions").append(
"let", Document("categoryId", "\$_id") "let", Document("categoryId", "\$_id")
).append( ).append(

View File

@@ -10,10 +10,7 @@ import org.springframework.security.core.context.ReactiveSecurityContextHolder
import org.springframework.stereotype.Service import org.springframework.stereotype.Service
import reactor.core.publisher.Flux import reactor.core.publisher.Flux
import reactor.core.publisher.Mono import reactor.core.publisher.Mono
import space.luminic.budgerapp.models.Category import space.luminic.budgerapp.models.*
import space.luminic.budgerapp.models.Space
import space.luminic.budgerapp.models.SpaceInvite
import space.luminic.budgerapp.models.Tag
import space.luminic.budgerapp.repos.* import space.luminic.budgerapp.repos.*
import java.time.LocalDateTime import java.time.LocalDateTime
import java.util.UUID import java.util.UUID
@@ -23,7 +20,6 @@ class SpaceService(
private val spaceRepo: SpaceRepo, private val spaceRepo: SpaceRepo,
private val userService: UserService, private val userService: UserService,
private val budgetRepo: BudgetRepo, private val budgetRepo: BudgetRepo,
private val userRepo: UserRepo,
private val reactiveMongoTemplate: ReactiveMongoTemplate, private val reactiveMongoTemplate: ReactiveMongoTemplate,
private val categoryRepo: CategoryRepo, private val categoryRepo: CategoryRepo,
private val recurrentRepo: RecurrentRepo, private val recurrentRepo: RecurrentRepo,
@@ -44,7 +40,7 @@ class SpaceService(
.switchIfEmpty(Mono.error(IllegalArgumentException("User not found for username: $username"))) .switchIfEmpty(Mono.error(IllegalArgumentException("User not found for username: $username")))
.flatMap { user -> .flatMap { user ->
// Получаем пространство по ID // Получаем пространство по ID
spaceRepo.findById(spaceId) getSpace(spaceId)
.switchIfEmpty(Mono.error(IllegalArgumentException("Space not found for id: $spaceId"))) .switchIfEmpty(Mono.error(IllegalArgumentException("Space not found for id: $spaceId")))
.flatMap { space -> .flatMap { space ->
// Проверяем доступ пользователя к пространству // Проверяем доступ пользователя к пространству
@@ -65,10 +61,51 @@ class SpaceService(
val username = authentication.name val username = authentication.name
userService.getByUsername(username) userService.getByUsername(username)
.switchIfEmpty(Mono.error(IllegalArgumentException("User not found for username: $username"))) .switchIfEmpty(Mono.error(IllegalArgumentException("User not found for username: $username")))
.flatMapMany { user -> .flatMap { user ->
spaceRepo.findByArrayElement(ObjectId(user.id!!)) val userId = ObjectId(user.id!!)
// Поиск пространств пользователя
// Агрегация для загрузки владельца и пользователей
val lookupOwner = lookup("users", "owner.\$id", "_id", "ownerDetails")
val unwindOwner = unwind("ownerDetails")
val lookupUsers = lookup("users", "users.\$id", "_id", "usersDetails")
// val unwindUsers = unwind("usersDetails")
val matchStage = match(Criteria.where("usersDetails._id").`is`(userId))
val aggregation = newAggregation(lookupOwner, unwindOwner, lookupUsers, matchStage)
reactiveMongoTemplate.aggregate(aggregation, "spaces", Document::class.java)
.collectList()
.map { docs ->
docs.map { doc ->
val ownerDoc = doc.get("ownerDetails", Document::class.java)
val usersDocList = doc.getList("usersDetails", Document::class.java)
Space(
id = doc.getObjectId("_id").toString(),
name = doc.getString("name"),
description = doc.getString("description"),
owner = User(
id = ownerDoc.getObjectId("_id").toString(),
username = ownerDoc.getString("username"),
firstName = ownerDoc.getString("firstName")
),
users = usersDocList.map { userDoc ->
User(
id = userDoc.getObjectId("_id").toString(),
username = userDoc.getString("username"),
firstName = userDoc.getString("firstName")
)
}.toMutableList()
)
}
}
} }
.collectList() // Возвращаем Mono<List<Space>>
} }
} }
@@ -94,12 +131,10 @@ class SpaceService(
reactiveMongoTemplate.find(Query(), Category::class.java, "categories-etalon") reactiveMongoTemplate.find(Query(), Category::class.java, "categories-etalon")
.map { category -> .map { category ->
category.copy( category.copy(id = null, space = savedSpace) // Создаем новую копию
id = null,
space = savedSpace
) // Создаем новую копию без id (чтобы создать новый документ)
} }
.flatMap { categoryRepo.save(it) } .collectList() // Собираем в список перед сохранением
.flatMap { categoryRepo.saveAll(it).collectList() } // Сохраняем и возвращаем список
.then(Mono.just(savedSpace)) // После сохранения всех категорий, возвращаем пространство .then(Mono.just(savedSpace)) // После сохранения всех категорий, возвращаем пространство
} }
} }
@@ -111,25 +146,17 @@ class SpaceService(
return Mono.`when`( return Mono.`when`(
financialService.findProjectedBudgets(objectId) financialService.findProjectedBudgets(objectId)
.flatMapMany { Flux.fromIterable(it) } .flatMap { budgetRepo.deleteAll(it) },
.flatMap { budgetRepo.deleteById(it.id!!) }
.then(),
financialService.getTransactions(objectId.toString()) financialService.getTransactions(objectId.toString())
.flatMapMany { Flux.fromIterable(it) } .flatMap { transactionRepo.deleteAll(it) },
.flatMap { transactionRepo.deleteById(it.id!!) }
.then(),
categoryService.getCategories(objectId.toString(), null, "name", "ASC") categoryService.getCategories(objectId.toString(), null, "name", "ASC")
.flatMapMany { Flux.fromIterable(it) } .flatMap { categoryRepo.deleteAll(it) },
.flatMap { categoryRepo.deleteById(it.id!!) }
.then(),
recurrentService.getRecurrents(objectId.toString()) recurrentService.getRecurrents(objectId.toString())
.flatMapMany { Flux.fromIterable(it) } .flatMap { recurrentRepo.deleteAll(it) }
.flatMap { recurrentRepo.deleteById(it.id!!) } ).then(spaceRepo.deleteById(space.id!!)) // Удаление Space после завершения всех операций
.then()
).then(spaceRepo.deleteById(space.id!!)) // Исправлено: удаление по ID
} }
@@ -331,7 +358,7 @@ class SpaceService(
return reactiveMongoTemplate.aggregate( return reactiveMongoTemplate.aggregate(
aggregation, "tags", Document::class.java aggregation, "tags", Document::class.java
) )
.collectList() // Преобразуем Flux<Transaction> в Mono<List<Transaction>> .collectList()
.map { docs -> .map { docs ->
docs.map { doc -> docs.map { doc ->
Tag( Tag(
@@ -347,7 +374,7 @@ class SpaceService(
fun regenSpaceCategory(): Mono<Category> { fun regenSpaceCategory(): Mono<Category> {
return getSpace("67af3c0f652da946a7dd9931") return getSpace("67af3c0f652da946a7dd9931")
.flatMap { space -> .flatMap { space ->
categoryService.findCategory(id= "677bc767c7857460a491bd4f") categoryService.findCategory(id = "677bc767c7857460a491bd4f")
.flatMap { category -> // заменил map на flatMap .flatMap { category -> // заменил map на flatMap
category.space = space category.space = space
category.name = "Сбережения" category.name = "Сбережения"

View File

@@ -7,6 +7,9 @@
"as": "categoryDetails" "as": "categoryDetails"
} }
}, },
{
"$unwind": "$categoryDetails"
},
{ {
"$lookup": { "$lookup": {
"from": "spaces", "from": "spaces",
@@ -15,6 +18,9 @@
"as": "spaceDetails" "as": "spaceDetails"
} }
}, },
{
"$unwind": "$spaceDetails"
},
{ {
"$lookup": { "$lookup": {
"from": "users", "from": "users",
@@ -23,16 +29,19 @@
"as": "userDetails" "as": "userDetails"
} }
}, },
{
"$unwind": "$userDetails"
},
{ {
"$match": { "$match": {
"$and": [ "$and": [
{ {
"spaceDetails._id": { "spaceDetails._id": {
"$oid": "67af52e8b0aa7b0f7f74b491" "$oid": "67af3c0f652da946a7dd9931"
} }
}, },
{ {
"type.code": "INSTANT" "categoryDetails._id": "67b83f3c1fc0575a3f0a3847"
} }
] ]
} }
@@ -42,11 +51,5 @@
"date": -1, "date": -1,
"createdAt": -1 "createdAt": -1
} }
},
{
"$skip": 0
},
{
"$limit": 10
} }
] ]