diff --git a/src/main/kotlin/space/luminic/budgerapp/controllers/SpaceController.kt b/src/main/kotlin/space/luminic/budgerapp/controllers/SpaceController.kt index 1669407..8e67f10 100644 --- a/src/main/kotlin/space/luminic/budgerapp/controllers/SpaceController.kt +++ b/src/main/kotlin/space/luminic/budgerapp/controllers/SpaceController.kt @@ -272,7 +272,7 @@ class SpaceController( @GetMapping("/{spaceId}/recurrents") suspend fun getRecurrents(@PathVariable spaceId: String): List { spaceService.isValidRequest(spaceId) - return recurrentService.getRecurrents(spaceId).awaitSingleOrNull().orEmpty() + return recurrentService.getRecurrents(spaceId) } diff --git a/src/main/kotlin/space/luminic/budgerapp/services/FinancialService.kt b/src/main/kotlin/space/luminic/budgerapp/services/FinancialService.kt index 3b3eced..d0fd3c2 100644 --- a/src/main/kotlin/space/luminic/budgerapp/services/FinancialService.kt +++ b/src/main/kotlin/space/luminic/budgerapp/services/FinancialService.kt @@ -57,20 +57,22 @@ class FinancialService( val budget = findProjectedBudget( transaction.space!!.id!!, budgetId = null, transaction.date, transaction.date ) - val budgetCategory = budget.categories.firstOrNull { it.category.id == transaction.category.id } - ?: throw NotFoundException("Budget category not found in the budget") - if (transaction.category.type.code == "INCOME") { + if (transaction.category.type.code == "EXPENSE") { + val budgetCategory = budget.categories.firstOrNull { it.category.id == transaction.category.id } + ?: throw NotFoundException("Budget category not found in the budget") + if (transaction.category.type.code == "INCOME") { + budgetRepo.save(budget).awaitSingle() + } + val categorySums = getBudgetSumsByCategory(transaction.category.id!!, budget) + budgetCategory.currentPlanned = categorySums.getDouble("plannedAmount") + budgetCategory.currentSpent = categorySums.getDouble("instantAmount") + // При совпадении бюджетов разница просто корректирует лимит + if (transaction.type.code == "PLANNED") { + budgetCategory.currentLimit += transaction.amount + } + logger.info("updateBudgetOnCreate end") budgetRepo.save(budget).awaitSingle() } - val categorySums = getBudgetSumsByCategory(transaction.category.id!!, budget) - budgetCategory.currentPlanned = categorySums.getDouble("plannedAmount") - budgetCategory.currentSpent = categorySums.getDouble("instantAmount") - // При совпадении бюджетов разница просто корректирует лимит - if (transaction.type.code == "PLANNED") { - budgetCategory.currentLimit += transaction.amount - } - logger.info("updateBudgetOnCreate end") - budgetRepo.save(budget).awaitSingle() } @@ -147,26 +149,22 @@ class FinancialService( oldBudget: Budget, newBudget: Budget ) = coroutineScope { - val oldCategory = findBudgetCategory(oldTransaction, oldBudget) - val newCategory = findBudgetCategory(newTransaction, newBudget) +// val oldCategory = findBudgetCategory(oldTransaction, oldBudget) +// val newCategory = findBudgetCategory(newTransaction, newBudget) - if (oldCategory.category.id == newCategory.category.id) { - async { - updateBudgetCategory(oldTransaction, oldBudget, -difference) - updateBudgetCategory(newTransaction, newBudget, difference) - } - } else { - async { - updateBudgetCategory( - oldTransaction, - oldBudget, - -difference, - isCategoryChanged = true, - isOldCategory = true - ) - updateBudgetCategory(newTransaction, newBudget, difference) - } + + async { + updateBudgetCategory( + oldTransaction, + oldBudget, + -difference, + isCategoryChanged = true, + isOldCategory = true, + isNewBudget = true + ) + updateBudgetCategory(newTransaction, newBudget, difference, isNewBudget = true) } + } private suspend fun findBudgetCategory(transaction: Transaction, budget: Budget): BudgetCategory { @@ -202,7 +200,8 @@ class FinancialService( budget: Budget, difference: Double, isCategoryChanged: Boolean = false, - isOldCategory: Boolean = false + isOldCategory: Boolean = false, + isNewBudget: Boolean = false ): Double { return if (transaction.category.type.code == "EXPENSE") { val sums = getBudgetSumsByCategory(transaction.category.id!!, budget) @@ -215,6 +214,8 @@ class FinancialService( if (isOldCategory) { categoryBudget.currentLimit -= transaction.amount } else categoryBudget.currentLimit += transaction.amount + } else if (isNewBudget) { + categoryBudget.currentLimit += transaction.amount } else categoryBudget.currentLimit += difference } budgetRepo.save(budget).awaitSingle() diff --git a/src/main/kotlin/space/luminic/budgerapp/services/RecurrentService.kt b/src/main/kotlin/space/luminic/budgerapp/services/RecurrentService.kt index 1217151..abad179 100644 --- a/src/main/kotlin/space/luminic/budgerapp/services/RecurrentService.kt +++ b/src/main/kotlin/space/luminic/budgerapp/services/RecurrentService.kt @@ -36,7 +36,7 @@ class RecurrentService( private val logger = LoggerFactory.getLogger(javaClass) - fun getRecurrents(spaceId: String): Mono> { + suspend fun getRecurrents(spaceId: String): List { val lookupCategories = lookup("categories", "category.\$id", "_id", "categoryDetails") val unwindCategory = unwind("categoryDetails") @@ -48,12 +48,13 @@ class RecurrentService( val aggregation = newAggregation(lookupCategories, unwindCategory, lookupSpace, unwindSpace, matchStage, sort) // Запрос рекуррентных платежей - return reactiveMongoTemplate.aggregate(aggregation, "recurrents", Document::class.java).collectList() + return reactiveMongoTemplate.aggregate(aggregation, "recurrents", Document::class.java) + .collectList() .map { docs -> docs.map { doc -> recurrentMapper.fromDocument(doc) - }.toList() - } + } + }.awaitSingle() } @@ -82,35 +83,38 @@ class RecurrentService( val context = ReactiveSecurityContextHolder.getContext().awaitSingleOrNull() ?: throw IllegalStateException("SecurityContext is empty!") val user = userService.getByUserNameWoPass(context.authentication.name) - val recurrents = getRecurrents(space.id!!).awaitSingle() - val transactions = recurrents.map { recurrent -> - val transactionDate = when { - recurrent.atDay in budget.dateFrom.dayOfMonth..daysInCurrentMonth -> { - currentYearMonth.atDay(recurrent.atDay) - } + val recurrents = getRecurrents(space.id!!) + if (recurrents.isNotEmpty()) { + val transactions = recurrents.map { recurrent -> + val transactionDate = when { + recurrent.atDay in budget.dateFrom.dayOfMonth..daysInCurrentMonth -> { + currentYearMonth.atDay(recurrent.atDay) + } - recurrent.atDay < budget.dateFrom.dayOfMonth -> { - currentYearMonth.atDay(recurrent.atDay).plusMonths(1) - } + recurrent.atDay < budget.dateFrom.dayOfMonth -> { + currentYearMonth.atDay(recurrent.atDay).plusMonths(1) + } - else -> { - val extraDays = recurrent.atDay - daysInCurrentMonth - currentYearMonth.plusMonths(1).atDay(extraDays) + else -> { + val extraDays = recurrent.atDay - daysInCurrentMonth + currentYearMonth.plusMonths(1).atDay(extraDays) + } } + // Создаем транзакцию + Transaction( + space = space, + date = transactionDate, + amount = recurrent.amount.toDouble(), + category = recurrent.category, + isDone = false, + comment = recurrent.name, + user = user, + type = TransactionType("PLANNED", "Запланированные") + ) } - // Создаем транзакцию - Transaction( - space = space, - date = transactionDate, - amount = recurrent.amount.toDouble(), - category = recurrent.category, - isDone = false, - comment = recurrent.name, - user = user, - type = TransactionType("PLANNED", "Запланированные") - ) + transactionRepo.saveAll(transactions).awaitLast() } - transactionRepo.saveAll(transactions).awaitLast() + } diff --git a/src/main/kotlin/space/luminic/budgerapp/services/SpaceService.kt b/src/main/kotlin/space/luminic/budgerapp/services/SpaceService.kt index efc61ae..8925200 100644 --- a/src/main/kotlin/space/luminic/budgerapp/services/SpaceService.kt +++ b/src/main/kotlin/space/luminic/budgerapp/services/SpaceService.kt @@ -150,7 +150,7 @@ class SpaceService( } launch { - val recurrents = recurrentService.getRecurrents(objectId.toString()).awaitFirstOrNull().orEmpty() + val recurrents = recurrentService.getRecurrents(objectId.toString()) recurrentRepo.deleteAll(recurrents).awaitFirstOrNull() } }