From 35090b946d165f86c1813b6a2fae1a73396b647d Mon Sep 17 00:00:00 2001 From: xds Date: Mon, 24 Feb 2025 22:05:29 +0300 Subject: [PATCH] some fix --- .../budgerapp/services/FinancialService.kt | 149 ++++++++++-------- 1 file changed, 84 insertions(+), 65 deletions(-) diff --git a/src/main/kotlin/space/luminic/budgerapp/services/FinancialService.kt b/src/main/kotlin/space/luminic/budgerapp/services/FinancialService.kt index 4bbc6a1..e18ad24 100644 --- a/src/main/kotlin/space/luminic/budgerapp/services/FinancialService.kt +++ b/src/main/kotlin/space/luminic/budgerapp/services/FinancialService.kt @@ -76,83 +76,100 @@ class FinancialService( fun updateBudgetOnEdit( oldTransaction: Transaction, newTransaction: Transaction, difference: Double ): Mono { - 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(RuntimeException("Budget category not found in the budget")) - } - - 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() - } + updateSameBudget(oldTransaction, newTransaction, difference, newBudget) } else { - // Если бюджеты различаются — отдельно обновляем категории в старом и новом бюджетах. - val oldBudgetCategory = - oldBudget.categories.firstOrNull { it.category.id == oldTransaction.category.id } - val newBudgetCategory = - newBudget.categories.firstOrNull { it.category.id == newTransaction.category.id } - - val oldUpdate: Mono = 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 - } - budgetRepo.save(oldBudget).then() - } - } - - val newUpdate: Mono = if (newBudgetCategory == null) { - Mono.error(RuntimeException("New budget category not found")) - } 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() - } - } - logger.info("updateBudgetOnEdit end") - return@flatMap Mono.`when`(oldUpdate, newUpdate).then() + updateDifferentBudgets(oldTransaction, newTransaction, difference, oldBudget, newBudget) } + }.doOnSuccess { logger.info("updateBudgetOnEdit end") } + } + + private fun updateSameBudget( + oldTransaction: Transaction, newTransaction: Transaction, difference: Double, budget: Budget + ): Mono { + 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() } + + } else { + 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() + } } } + + private fun updateDifferentBudgets( + oldTransaction: Transaction, + newTransaction: Transaction, + difference: Double, + oldBudget: Budget, + newBudget: Budget + ): Mono { + 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 { + budget.incomeCategories.firstOrNull { it.category.id == transaction.category.id } + ?: throw RuntimeException("Budget category not found for income") + } + } + + private fun updateBudgetCategory( + transaction: Transaction, category: BudgetCategory, budget: Budget, tAmount: Double, difference: Double + ): Mono { + 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 { 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