fix recurrents
This commit is contained in:
@@ -1,21 +1,31 @@
|
||||
package space.luminic.budgerapp.services
|
||||
|
||||
|
||||
|
||||
import org.bson.Document
|
||||
import org.bson.types.ObjectId
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.springframework.cache.annotation.CacheEvict
|
||||
import org.springframework.cache.annotation.Cacheable
|
||||
import org.springframework.data.domain.Sort
|
||||
import org.springframework.data.domain.Sort.Direction
|
||||
import org.springframework.data.mongodb.core.ReactiveMongoTemplate
|
||||
import org.springframework.data.mongodb.core.aggregation.Aggregation.*
|
||||
import org.springframework.data.mongodb.core.query.Criteria
|
||||
import org.springframework.security.core.context.ReactiveSecurityContextHolder
|
||||
import org.springframework.stereotype.Service
|
||||
import reactor.core.publisher.Flux
|
||||
import reactor.core.publisher.Mono
|
||||
import space.luminic.budgerapp.models.*
|
||||
import space.luminic.budgerapp.repos.RecurrentRepo
|
||||
import space.luminic.budgerapp.repos.TransactionRepo
|
||||
import java.time.YearMonth
|
||||
import java.time.ZoneId
|
||||
|
||||
|
||||
@Service
|
||||
class RecurrentService(
|
||||
private val reactiveMongoTemplate: ReactiveMongoTemplate,
|
||||
private val recurrentRepo: RecurrentRepo,
|
||||
private val transactionRepo: TransactionRepo,
|
||||
private val userService: UserService,
|
||||
@@ -24,12 +34,42 @@ class RecurrentService(
|
||||
|
||||
private val logger = LoggerFactory.getLogger(javaClass)
|
||||
|
||||
@Cacheable("recurrentsList")
|
||||
fun getRecurrents(space: Space): Mono<List<Recurrent>> {
|
||||
|
||||
fun getRecurrents(space: Space): Mono<List<Recurrent>> {
|
||||
val lookupCategories = lookup("categories", "category.\$id", "_id", "categoryDetails")
|
||||
val unwindCategory = unwind("categoryDetails")
|
||||
|
||||
val lookupSpace = lookup("spaces", "space.\$id", "_id", "spaceDetails")
|
||||
val unwindSpace = unwind("spaceDetails")
|
||||
val matchStage = match(Criteria.where("spaceDetails._id").`is`(ObjectId(space.id)))
|
||||
|
||||
val sort =sort(Sort.by(Direction.ASC, "atDay"))
|
||||
val aggregation =
|
||||
newAggregation(lookupCategories, unwindCategory,lookupSpace, unwindSpace, matchStage, sort)
|
||||
// Запрос рекуррентных платежей
|
||||
return recurrentRepo.findRecurrentsBySpaceId(ObjectId(space.id))
|
||||
.collectList() // Преобразуем Flux<Recurrent> в Mono<List<Recurrent>>
|
||||
return reactiveMongoTemplate.aggregate(aggregation, "recurrents", Document::class.java).collectList().map { docs ->
|
||||
docs.map { doc ->
|
||||
val categoryDoc = doc.get("categoryDetails", Document::class.java)
|
||||
val categoryTypeDoc = categoryDoc.get("type", Document::class.java)
|
||||
Recurrent(
|
||||
id = doc.getObjectId("_id").toString(),
|
||||
space = space,
|
||||
atDay = doc.getInteger("atDay"),
|
||||
category = Category(
|
||||
id = categoryDoc.getObjectId("_id").toString(),
|
||||
space = space,
|
||||
type = CategoryType(categoryTypeDoc.getString("code"), categoryTypeDoc.getString("name")),
|
||||
name = categoryDoc.getString("name"),
|
||||
description = categoryDoc.getString("description"),
|
||||
icon = categoryDoc.getString("icon"),
|
||||
),
|
||||
name = doc.getString("name"),
|
||||
description = doc.getString("description"),
|
||||
amount = doc.getInteger("amount"),
|
||||
createdAt = doc.getDate("createdAt"),
|
||||
)
|
||||
}.toList()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -51,36 +91,33 @@ class RecurrentService(
|
||||
)
|
||||
}
|
||||
|
||||
@CacheEvict(cacheNames = ["recurrentsList", "recurrents"])
|
||||
fun createRecurrentsForBudget(space: Space, budget: Budget): Mono<Void> {
|
||||
val currentYearMonth = YearMonth.of(budget.dateFrom.year, budget.dateFrom.monthValue)
|
||||
val daysInCurrentMonth = currentYearMonth.lengthOfMonth()
|
||||
|
||||
val context = ReactiveSecurityContextHolder.getContext()
|
||||
.doOnNext { println("Security context: $it") }
|
||||
.switchIfEmpty(Mono.error(IllegalStateException("SecurityContext is empty!")))
|
||||
|
||||
return context
|
||||
.map {
|
||||
logger.debug(it.authentication.name)
|
||||
it.authentication
|
||||
}
|
||||
.map { it.authentication }
|
||||
.flatMap { authentication ->
|
||||
val username = authentication.name
|
||||
userService.getByUsername(username)
|
||||
.switchIfEmpty(Mono.error(IllegalArgumentException("User not found for username: $username")))
|
||||
}
|
||||
.flatMapMany { user ->
|
||||
recurrentRepo.findRecurrentsBySpaceId(ObjectId(space.id))
|
||||
getRecurrents(space) // Теперь это Mono<List<Recurrent>>
|
||||
.flatMapMany { Flux.fromIterable(it) } // Преобразуем List<Recurrent> в Flux<Recurrent>
|
||||
.map { recurrent ->
|
||||
// Определяем дату транзакции
|
||||
val transactionDate = when {
|
||||
recurrent.atDay <= daysInCurrentMonth && recurrent.atDay >= budget.dateFrom.dayOfMonth -> {
|
||||
recurrent.atDay in budget.dateFrom.dayOfMonth..daysInCurrentMonth -> {
|
||||
currentYearMonth.atDay(recurrent.atDay)
|
||||
}
|
||||
|
||||
recurrent.atDay < budget.dateFrom.dayOfMonth -> {
|
||||
currentYearMonth.atDay(recurrent.atDay).plusMonths(1)
|
||||
}
|
||||
|
||||
else -> {
|
||||
val extraDays = recurrent.atDay - daysInCurrentMonth
|
||||
currentYearMonth.plusMonths(1).atDay(extraDays)
|
||||
@@ -89,6 +126,7 @@ class RecurrentService(
|
||||
|
||||
// Создаем транзакцию
|
||||
Transaction(
|
||||
space = space,
|
||||
date = transactionDate,
|
||||
amount = recurrent.amount.toDouble(),
|
||||
category = recurrent.category,
|
||||
@@ -101,8 +139,7 @@ class RecurrentService(
|
||||
}
|
||||
.collectList() // Собираем все транзакции в список
|
||||
.flatMap { transactions ->
|
||||
transactionRepo.saveAll(transactions) // Сохраняем все транзакции разом
|
||||
.then() // Возвращаем Mono<Void>
|
||||
transactionRepo.saveAll(transactions).then() // Сохраняем все транзакции разом и возвращаем Mono<Void>
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user