This commit is contained in:
xds
2025-02-24 22:05:29 +03:00
parent b2fb6174c2
commit 35090b946d

View File

@@ -76,83 +76,100 @@ class FinancialService(
fun updateBudgetOnEdit(
oldTransaction: Transaction, newTransaction: Transaction, difference: Double
): Mono<Void> {
logger.info("updateBudgetOnEdit start ")
return Mono.zip(
logger.info("updateBudgetOnEdit start")
return Mono.zip(
findProjectedBudget(
newTransaction.space!!.id!!, budgetId = null, oldTransaction.date, oldTransaction.date
).map {
logger.info("got old budget")
it
}.switchIfEmpty(Mono.error(BudgetNotFoundException("Old budget cannot be null"))), findProjectedBudget(
newTransaction.space!!.id!!, budgetId = null, newTransaction.date, newTransaction.date
).map {
logger.info("got new budget")
it
}.switchIfEmpty(Mono.error(BudgetNotFoundException("New budget cannot be null")))
newTransaction.space?.id!!, budgetId = null, oldTransaction.date, oldTransaction.date
).switchIfEmpty(Mono.error(BudgetNotFoundException("Old budget not found"))),
findProjectedBudget(
newTransaction.space?.id!!, budgetId = null, newTransaction.date, newTransaction.date
).switchIfEmpty(Mono.error(BudgetNotFoundException("New budget not found")))
).flatMap { tuple ->
val oldBudget = tuple.t1
val newBudget = tuple.t2
val isSameBudget = oldBudget.id == newBudget.id
if (isSameBudget) {
// Если бюджеты совпадают — обновляем соответствующую категорию в новом (едином) бюджете.
val budgetCategory =
if (newTransaction.category.type.code == "EXPENSE") newBudget.categories.firstOrNull { it.category.id == newTransaction.category.id } else newBudget.incomeCategories.firstOrNull { it.category.id == newTransaction.category.id }
if (budgetCategory == null) {
return@flatMap Mono.error<Void>(RuntimeException("Budget category not found in the budget"))
updateSameBudget(oldTransaction, newTransaction, difference, newBudget)
} else {
updateDifferentBudgets(oldTransaction, newTransaction, difference, oldBudget, newBudget)
}
}.doOnSuccess { logger.info("updateBudgetOnEdit end") }
}
return@flatMap getBudgetSumsByCategory(newTransaction.category.id!!, newBudget).flatMap { sums ->
budgetCategory.currentPlanned = sums.getDouble("plannedAmount") ?: 0.0
budgetCategory.currentSpent = sums.getDouble("instantAmount") ?: 0.0
// При совпадении бюджетов разница просто корректирует лимит
if (newTransaction.type.code == "PLANNED") {
budgetCategory.currentLimit += difference
}
logger.info("updateBudgetOnEdit end")
budgetRepo.save(newBudget).then()
}
} else {
// Если бюджеты различаются — отдельно обновляем категории в старом и новом бюджетах.
val oldBudgetCategory =
oldBudget.categories.firstOrNull { it.category.id == oldTransaction.category.id }
val newBudgetCategory =
newBudget.categories.firstOrNull { it.category.id == newTransaction.category.id }
private fun updateSameBudget(
oldTransaction: Transaction, newTransaction: Transaction, difference: Double, budget: Budget
): Mono<Void> {
val oldCategory = findBudgetCategory(oldTransaction, budget)
val newCategory = findBudgetCategory(newTransaction, budget)
return if (oldCategory.category.id == newCategory.category.id) {
updateBudgetCategory(newTransaction, newCategory, budget, newTransaction.amount, difference)
.flatMap { Mono.empty() }
val oldUpdate: Mono<Void> = if (oldBudgetCategory == null) {
Mono.error(RuntimeException("Old budget category not found"))
} else {
getBudgetSumsByCategory(oldTransaction.category.id!!, oldBudget).flatMap { sums ->
oldBudgetCategory.currentPlanned = sums.getDouble("plannedAmount") ?: 0.0
oldBudgetCategory.currentSpent = sums.getDouble("instantAmount") ?: 0.0
// В старом бюджете вычитаем разницу, так как транзакция перемещается
if (oldTransaction.type.code == "PLANNED") {
oldBudgetCategory.currentLimit -= difference
logger.info("hui" + oldTransaction.category.id + " " + (-oldTransaction.amount).toString())
Mono.zip(
updateBudgetCategory(oldTransaction, oldCategory, budget, -oldTransaction.amount, -difference),
updateBudgetCategory(newTransaction, newCategory, budget, newTransaction.amount, difference)
)
.flatMap {
val t1 = it.t1
val t2 = it.t2
logger.info(t1.toString())
logger.info(t2.toString())
Mono.empty()
}
budgetRepo.save(oldBudget).then()
}
}
val newUpdate: Mono<Void> = if (newBudgetCategory == null) {
Mono.error(RuntimeException("New budget category not found"))
private fun updateDifferentBudgets(
oldTransaction: Transaction,
newTransaction: Transaction,
difference: Double,
oldBudget: Budget,
newBudget: Budget
): Mono<Void> {
val oldCategory = findBudgetCategory(oldTransaction, oldBudget)
val newCategory = findBudgetCategory(newTransaction, newBudget)
return Mono.`when`(
updateBudgetCategory(oldTransaction, oldCategory, oldBudget, -oldTransaction.amount, -difference),
updateBudgetCategory(newTransaction, newCategory, newBudget, newTransaction.amount, difference)
)
}
private fun findBudgetCategory(transaction: Transaction, budget: Budget): BudgetCategory {
return if (transaction.category.type.code == "EXPENSE") {
budget.categories.firstOrNull { it.category.id == transaction.category.id }
?: throw RuntimeException("Budget category not found for expense")
} else {
getBudgetSumsByCategory(newTransaction.category.id!!, newBudget).flatMap { sums ->
newBudgetCategory.currentPlanned = sums.getDouble("plannedAmount") ?: 0.0
newBudgetCategory.currentSpent = sums.getDouble("instantAmount") ?: 0.0
// В новом бюджете прибавляем разницу
if (newTransaction.type.code == "PLANNED") {
newBudgetCategory.currentLimit += difference
}
budgetRepo.save(newBudget).then()
budget.incomeCategories.firstOrNull { it.category.id == transaction.category.id }
?: throw RuntimeException("Budget category not found for income")
}
}
logger.info("updateBudgetOnEdit end")
return@flatMap Mono.`when`(oldUpdate, newUpdate).then()
}
private fun updateBudgetCategory(
transaction: Transaction, category: BudgetCategory, budget: Budget, tAmount: Double, difference: Double
): Mono<Double> {
return getBudgetSumsByCategory(transaction.category.id!!, budget)
.defaultIfEmpty(Document("plannedAmount", 0.0).append("instantAmount", 0.0)) // Если данных нет, заполняем 0
.flatMap { sums ->
category.currentPlanned = sums.getDouble("plannedAmount") ?: 0.0
category.currentSpent = sums.getDouble("instantAmount") ?: 0.0
if (transaction.type.code == "PLANNED") {
category.currentLimit += difference
}
budgetRepo.save(budget).thenReturn(1.0) // Дожидаемся сохранения, возвращаем 1.0
}
}
fun updateBudgetOnDelete(transaction: Transaction): Mono<Void> {
return findProjectedBudget(
transaction.space!!.id!!, budgetId = null, transaction.date, transaction.date
@@ -1227,7 +1244,9 @@ class FinancialService(
return reactiveMongoTemplate.getCollection("transactions") // Исправлено на transactions
.flatMapMany {
it.aggregate(pipeline)
val result = it.aggregate(pipeline)
logger.info("aggregate: $pipeline")
result
}.map {
logger.info("getting budget sums for category $categoryId end")
it