add categories thought spaces

This commit is contained in:
xds
2025-02-17 18:31:46 +03:00
parent d680345a9f
commit 0c445a5141
8 changed files with 91 additions and 33 deletions

View File

@@ -92,12 +92,12 @@ class BudgetController(
fun setWarnHide(@PathVariable id: String, @PathVariable warnId: String): Mono<Warn> { fun setWarnHide(@PathVariable id: String, @PathVariable warnId: String): Mono<Warn> {
return financialService.hideWarn(warnId) return financialService.hideWarn(warnId)
} }
//
// @GetMapping("/regencats") @GetMapping("/regencats")
// fun regenCats(): Mono<Void> { fun regenCats(): Mono<Void> {
// return financialService.regenCats() return financialService.regenCats()
// } }
//
// @GetMapping("/regenSpaces") // @GetMapping("/regenSpaces")
// fun regenSpaces(): Mono<Void> { // fun regenSpaces(): Mono<Void> {
// return financialService.regenBudgets() // return financialService.regenBudgets()

View File

@@ -25,6 +25,12 @@ class SpaceController(
) { ) {
data class SpaceCreateDTO(
val name: String,
val description: String,
val createCategories: Boolean,
)
@GetMapping @GetMapping
fun getSpaces(): Mono<List<Space>> { fun getSpaces(): Mono<List<Space>> {
return spaceService.getSpaces() return spaceService.getSpaces()
@@ -32,8 +38,8 @@ class SpaceController(
@PostMapping @PostMapping
fun createSpace(@RequestBody space: Space): Mono<Space> { fun createSpace(@RequestBody space: SpaceCreateDTO): Mono<Space> {
return spaceService.createSpace(space) return spaceService.createSpace(Space(name=space.name, description = space.description), space.createCategories)
} }
@@ -45,7 +51,10 @@ class SpaceController(
@DeleteMapping("/{spaceId}") @DeleteMapping("/{spaceId}")
fun deleteSpace(@PathVariable spaceId: String): Mono<Void> { fun deleteSpace(@PathVariable spaceId: String): Mono<Void> {
return spaceService.deleteSpace(spaceId) return spaceService.isValidRequest(spaceId).flatMap {
spaceService.deleteSpace(it)
}
} }
@PostMapping("/{spaceId}/invite") @PostMapping("/{spaceId}/invite")

View File

@@ -25,4 +25,7 @@ interface BudgetRepo: ReactiveMongoRepository<Budget, String> {
@Query("{ 'space': { '\$ref': 'spaces','\$id': ?0 } }") @Query("{ 'space': { '\$ref': 'spaces','\$id': ?0 } }")
fun findBySpaceId(spaceId: ObjectId, sort: Sort): Flux<Budget> fun findBySpaceId(spaceId: ObjectId, sort: Sort): Flux<Budget>
@Query("{ 'space': { '\$ref': 'spaces','\$id': ?0 } }")
fun findBySpaceId(spaceId: ObjectId): Flux<Budget>
} }

View File

@@ -1,8 +1,13 @@
package space.luminic.budgerapp.repos package space.luminic.budgerapp.repos
import org.bson.types.ObjectId
import org.springframework.data.domain.Sort
import org.springframework.data.mongodb.repository.Query
import org.springframework.data.mongodb.repository.ReactiveMongoRepository import org.springframework.data.mongodb.repository.ReactiveMongoRepository
import org.springframework.stereotype.Repository import org.springframework.stereotype.Repository
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.Category
@Repository @Repository
@@ -10,7 +15,8 @@ interface CategoryRepo : ReactiveMongoRepository<Category, String> {
fun findByName(name: String): Mono<Category> fun findByName(name: String): Mono<Category>
@Query("{ 'space': { '\$ref': 'spaces','\$id': ?0 } }")
fun findBySpaceId(spaceId: ObjectId): Flux<Category>
} }

View File

@@ -1,8 +1,12 @@
package space.luminic.budgerapp.repos package space.luminic.budgerapp.repos
import org.bson.types.ObjectId
import org.springframework.data.mongodb.repository.Query
import org.springframework.data.mongodb.repository.ReactiveMongoRepository import org.springframework.data.mongodb.repository.ReactiveMongoRepository
import org.springframework.stereotype.Repository import org.springframework.stereotype.Repository
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.Transaction import space.luminic.budgerapp.models.Transaction
@@ -15,4 +19,7 @@ interface TransactionRepo: ReactiveMongoRepository<Transaction, String> {
// fun findByOldId(transactionId: Int): Optional<Transaction> // fun findByOldId(transactionId: Int): Optional<Transaction>
fun findByParentId(parentId: String): Mono<Transaction> fun findByParentId(parentId: String): Mono<Transaction>
@Query("{ 'space': { '\$ref': 'spaces','\$id': ?0 } }")
fun findBySpaceId(spaceId: ObjectId): Flux<Transaction>
} }

View File

@@ -46,6 +46,8 @@ class CategoryService(
return categoryRepo.findById(id) return categoryRepo.findById(id)
} }
// @Cacheable("categories") // @Cacheable("categories")
fun getCategories(spaceId: String, type: String? = null, sortBy: String, direction: String): Mono<List<Category>> { fun getCategories(spaceId: String, type: String? = null, sortBy: String, direction: String): Mono<List<Category>> {
val matchCriteria = mutableListOf<Criteria>() val matchCriteria = mutableListOf<Criteria>()

View File

@@ -318,16 +318,15 @@ class FinancialService(
fun regenCats(): Mono<Void> { fun regenCats(): Mono<Void> {
return categoryRepo.findAll()// Получаем список категорий return categoryRepo.findBySpaceId(ObjectId("67b352b13384483a1c2282ed"))
.flatMap { cat -> .flatMap { cat ->
spaceService.getSpace("67af3c0f652da946a7dd9931") // Получаем space // if (cat.space?.id == "67b352b13384483a1c2282ed") {
.map { space -> categoryRepo.deleteById(cat.id!!) // Возвращаем `Mono<Void>`
cat.space = space // Привязываем пространство к категории // } else {
cat // Mono.empty() // Если не удаляем, возвращаем пустой `Mono`
} // }
} }
.flatMap { updatedCategory -> categoryRepo.save(updatedCategory) } // Сохраняем в БД .then() // Убедимся, что все операции завершены
.then() // Завершаем Mono<Void>
} }
@CacheEvict(cacheNames = ["budgets", "budgetsList"], allEntries = true) @CacheEvict(cacheNames = ["budgets", "budgetsList"], allEntries = true)

View File

@@ -1,17 +1,15 @@
package space.luminic.budgerapp.services package space.luminic.budgerapp.services
import org.bson.types.ObjectId import org.bson.types.ObjectId
import org.springframework.data.domain.Sort import org.springframework.data.mongodb.core.ReactiveMongoTemplate
import org.springframework.data.domain.Sort.Direction 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.Mono import reactor.core.publisher.Mono
import space.luminic.budgerapp.models.Category
import space.luminic.budgerapp.models.Space import space.luminic.budgerapp.models.Space
import space.luminic.budgerapp.models.SpaceInvite import space.luminic.budgerapp.models.SpaceInvite
import space.luminic.budgerapp.models.Transaction import space.luminic.budgerapp.repos.*
import space.luminic.budgerapp.repos.BudgetRepo
import space.luminic.budgerapp.repos.SpaceRepo
import space.luminic.budgerapp.repos.UserRepo
import java.time.LocalDateTime import java.time.LocalDateTime
import java.util.UUID import java.util.UUID
@@ -20,7 +18,11 @@ 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 userRepo: UserRepo,
private val reactiveMongoTemplate: ReactiveMongoTemplate,
private val categoryRepo: CategoryRepo,
private val recurrentRepo: RecurrentRepo,
private val transactionRepo: TransactionRepo
) { ) {
fun isValidRequest(spaceId: String): Mono<Space> { fun isValidRequest(spaceId: String): Mono<Space> {
@@ -66,7 +68,7 @@ class SpaceService(
.switchIfEmpty(Mono.error(IllegalArgumentException("SpaceId not found for spaceId: $spaceId"))) .switchIfEmpty(Mono.error(IllegalArgumentException("SpaceId not found for spaceId: $spaceId")))
} }
fun createSpace(space: Space): Mono<Space> { fun createSpace(space: Space, createCategories: Boolean): Mono<Space> {
return ReactiveSecurityContextHolder.getContext() return ReactiveSecurityContextHolder.getContext()
.map { it.authentication } .map { it.authentication }
.flatMap { authentication -> .flatMap { authentication ->
@@ -76,20 +78,50 @@ class SpaceService(
.flatMap { user -> .flatMap { user ->
space.owner = user space.owner = user
space.users.add(user) space.users.add(user)
spaceRepo.save(space) spaceRepo.save(space).flatMap { savedSpace ->
if (!createCategories) {
return@flatMap Mono.just(savedSpace) // Если не нужно создавать категории, просто возвращаем пространство
}
reactiveMongoTemplate.find(Query(), Category::class.java, "categories-etalon")
.map { category ->
category.copy(
id = null,
space = savedSpace
) // Создаем новую копию без id (чтобы создать новый документ)
}
.flatMap { categoryRepo.save(it) }
.then(Mono.just(savedSpace)) // После сохранения всех категорий, возвращаем пространство
}
} }
} }
} }
fun deleteSpace(spaceId: String): Mono<Void> { fun deleteSpace(space: Space): Mono<Void> {
return budgetRepo.findBySpaceId(ObjectId(spaceId), Sort.by(Direction.DESC, "dateFrom")) val objectId = ObjectId(space.id)
.flatMap { budget ->
budgetRepo.delete(budget) // Удаляем все бюджеты, связанные с этим Space return Mono.`when`(
} budgetRepo.findBySpaceId(objectId)
.then(spaceRepo.deleteById(spaceId)) // Затем удаляем сам Space .flatMap { budgetRepo.delete(it) }
.then(),
transactionRepo.findBySpaceId(objectId)
.flatMap { transactionRepo.delete(it) }
.then(),
categoryRepo.findBySpaceId(objectId)
.flatMap { categoryRepo.delete(it) }
.then(),
recurrentRepo.findRecurrentsBySpaceId(objectId)
.flatMap { recurrentRepo.delete(it) }
.then()
).then(spaceRepo.deleteById(space.id!!)) // Исправлено: удаление по ID
} }
fun createInviteSpace(spaceId: String): Mono<SpaceInvite> { fun createInviteSpace(spaceId: String): Mono<SpaceInvite> {
return ReactiveSecurityContextHolder.getContext() return ReactiveSecurityContextHolder.getContext()
.map { it.authentication } .map { it.authentication }