+ bot + notifications

This commit is contained in:
xds
2025-04-01 15:07:50 +03:00
parent 711348b386
commit a38d5068e0
22 changed files with 603 additions and 129 deletions

View File

@@ -1,11 +1,8 @@
package space.luminic.budgerapp.services
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.toList
import kotlinx.coroutines.launch
import kotlinx.coroutines.reactive.asFlow
import kotlinx.coroutines.reactive.awaitFirstOrNull
import kotlinx.coroutines.reactive.awaitSingle
@@ -35,6 +32,7 @@ import space.luminic.budgerapp.repos.CategoryRepo
import space.luminic.budgerapp.repos.TransactionRepo
import space.luminic.budgerapp.repos.WarnRepo
import java.time.*
import java.time.format.DateTimeFormatter
import java.time.temporal.TemporalAdjusters
import java.util.*
@@ -48,7 +46,8 @@ class FinancialService(
val reactiveMongoTemplate: ReactiveMongoTemplate,
private val categoryRepo: CategoryRepo,
val transactionsMapper: TransactionsMapper,
val budgetMapper: BudgetMapper
val budgetMapper: BudgetMapper,
private val subscriptionService: SubscriptionService
) {
private val logger = LoggerFactory.getLogger(FinancialService::class.java)
@@ -846,25 +845,45 @@ class FinancialService(
}
private val scope = CoroutineScope(Dispatchers.IO + SupervisorJob())
suspend fun createTransaction(space: Space, transaction: Transaction): Transaction {
val securityContextHolder = ReactiveSecurityContextHolder.getContext().awaitSingle()
val user = userService.getByUserNameWoPass(securityContextHolder.authentication.name)
if (space.users.none { it.id.toString() == user.id }) {
suspend fun createTransaction(space: Space, transaction: Transaction, user: User? = null): Transaction {
val author = user
?: userService.getByUserNameWoPass(
ReactiveSecurityContextHolder.getContext().awaitSingle().authentication.name
)
if (space.users.none { it.id.toString() == author.id }) {
throw IllegalArgumentException("User does not have access to this Space")
}
// Привязываем space и user к транзакции
transaction.user = user
transaction.user = author
transaction.space = space
val savedTransaction = transactionsRepo.save(transaction).awaitSingle()
updateBudgetOnCreate(savedTransaction)
scope.launch {
val dateFormatter = DateTimeFormatter.ofPattern("dd.MM.yyyy")
val transactionType = if (transaction.type.code == "INSTANT") "текущую" else "плановую"
subscriptionService.sendToSpaceOwner(
space.owner!!.id!!, PushMessage(
title = "Новая транзакция в пространстве ${space.name}!",
body = "Пользователь ${author.username} создал $transactionType транзакцию на сумму ${transaction.amount.toInt()} с комментарием ${transaction.comment} с датой ${
dateFormatter.format(
transaction.date
)
}",
url = "https://luminic.space/"
)
)
}
return savedTransaction
}
@CacheEvict(cacheNames = ["transactions", "budgets"], allEntries = true)
suspend fun editTransaction(transaction: Transaction): Transaction {
suspend fun editTransaction(transaction: Transaction, author: User): Transaction {
val oldStateOfTransaction = getTransactionById(transaction.id!!)
val changed = compareSumDateDoneIsChanged(oldStateOfTransaction, transaction)
if (!changed) {
@@ -878,8 +897,57 @@ class FinancialService(
transaction
)
}
val space = transaction.space
val savedTransaction = transactionsRepo.save(transaction).awaitSingle()
updateBudgetOnEdit(oldStateOfTransaction, savedTransaction, amountDifference)
scope.launch {
var whatChanged = "nothing"
val dateFormatter = DateTimeFormatter.ofPattern("dd.MM.yyyy")
val transactionType = if (transaction.type.code == "INSTANT") "текущую" else "плановую"
val sb = StringBuilder()
if (oldStateOfTransaction.amount != transaction.amount) {
sb.append("${oldStateOfTransaction.amount}${transaction.amount}\n")
whatChanged = "main"
}
if (oldStateOfTransaction.comment != transaction.comment) {
sb.append("${oldStateOfTransaction.comment}${transaction.comment}\n")
whatChanged = "main"
}
if (oldStateOfTransaction.date != transaction.date) {
sb.append("${dateFormatter.format(oldStateOfTransaction.date)}${dateFormatter.format(transaction.date)}\n")
whatChanged = "main"
}
if (!oldStateOfTransaction.isDone && transaction.isDone) {
whatChanged = "done_true"
}
if (oldStateOfTransaction.isDone && !transaction.isDone) {
whatChanged = "done_false"
}
val body: String = when (whatChanged) {
"main" -> {
"Пользователь ${author.username} изменил $transactionType транзакцию:\n$sb"
}
"done_true" -> {
"Пользователь ${author.username} выполнил ${transaction.comment} с суммой ${transaction.amount.toInt()}"
}
"done_false" -> {
"Пользователь ${author.username} отменил выполнение ${transaction.comment} с суммой ${transaction.amount.toInt()}"
}
else -> "Изменения не обнаружены, но что то точно изменилось"
}
subscriptionService.sendToSpaceOwner(
space?.owner!!.id!!, PushMessage(
title = "Новое действие в пространстве ${space.name}!",
body = body,
url = "https://luminic.space/"
)
)
}
return savedTransaction
}