+ google drive
This commit is contained in:
@@ -16,4 +16,6 @@ interface TransactionRepo {
|
|||||||
|
|
||||||
fun setCategory(txId:Int, categoryId: Int)
|
fun setCategory(txId:Int, categoryId: Int)
|
||||||
|
|
||||||
|
fun findByDateAndKind(date: java.time.LocalDate, kind: Transaction.TransactionKind): List<Transaction>
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -30,6 +30,7 @@ class TransactionRepoImpl(
|
|||||||
) else null
|
) else null
|
||||||
Transaction(
|
Transaction(
|
||||||
id = rs.getInt("t_id"),
|
id = rs.getInt("t_id"),
|
||||||
|
space = Space(id = rs.getInt("t_space_id"), name = "", owner = User(0, "", "")),
|
||||||
parent = parent,
|
parent = parent,
|
||||||
type = Transaction.TransactionType.valueOf(rs.getString("t_type")),
|
type = Transaction.TransactionType.valueOf(rs.getString("t_type")),
|
||||||
kind = Transaction.TransactionKind.valueOf(rs.getString("t_kind")),
|
kind = Transaction.TransactionKind.valueOf(rs.getString("t_kind")),
|
||||||
@@ -391,4 +392,44 @@ class TransactionRepoImpl(
|
|||||||
)
|
)
|
||||||
jdbcTemplate.update(sql, params)
|
jdbcTemplate.update(sql, params)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun findByDateAndKind(date: java.time.LocalDate, kind: Transaction.TransactionKind): List<Transaction> {
|
||||||
|
val sql = """SELECT
|
||||||
|
t.id AS t_id,
|
||||||
|
t.parent_id AS t_parent_id,
|
||||||
|
t.space_id AS t_space_id,
|
||||||
|
t.type AS t_type,
|
||||||
|
t.kind AS t_kind,
|
||||||
|
t.comment AS t_comment,
|
||||||
|
t.amount AS t_amount,
|
||||||
|
t.fees AS t_fees,
|
||||||
|
t.date AS t_date,
|
||||||
|
t.is_deleted AS t_is_deleted,
|
||||||
|
t.is_done AS t_is_done,
|
||||||
|
t.created_at AS t_created_at,
|
||||||
|
t.updated_at AS t_updated_at,
|
||||||
|
t.tg_chat_id AS tg_chat_id,
|
||||||
|
t.tg_message_id AS tg_message_id,
|
||||||
|
c.id AS c_id,
|
||||||
|
c.type AS c_type,
|
||||||
|
c.name AS c_name,
|
||||||
|
c.description AS c_description,
|
||||||
|
c.icon AS c_icon,
|
||||||
|
c.is_deleted AS c_is_deleted,
|
||||||
|
c.created_at AS c_created_at,
|
||||||
|
c.updated_at AS c_updated_at,
|
||||||
|
u.id AS u_id,
|
||||||
|
u.username AS u_username,
|
||||||
|
u.first_name AS u_first_name,
|
||||||
|
t.recurrent_id AS t_recurrent_id
|
||||||
|
FROM finance.transactions t
|
||||||
|
LEFT JOIN finance.categories c ON t.category_id = c.id
|
||||||
|
JOIN finance.users u ON u.id = t.created_by_id
|
||||||
|
WHERE t.date = :date and t.kind = :kind and t.is_deleted = false""".trimMargin()
|
||||||
|
val params = mapOf(
|
||||||
|
"date" to date,
|
||||||
|
"kind" to kind.name,
|
||||||
|
)
|
||||||
|
return jdbcTemplate.query(sql, params, transactionRowMapper())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -7,6 +7,7 @@ import space.luminic.finance.models.Transaction
|
|||||||
|
|
||||||
interface NotificationService {
|
interface NotificationService {
|
||||||
fun sendDailyReminder()
|
fun sendDailyReminder()
|
||||||
|
fun sendPlannedTransactionsReminder()
|
||||||
fun sendTXNotification(action: TxActionType, space: Space, userId: Int, tx: Transaction, tx2: Transaction? = null)
|
fun sendTXNotification(action: TxActionType, space: Space, userId: Int, tx: Transaction, tx2: Transaction? = null)
|
||||||
fun sendTextMessage(chatId: Long, message: String, replyMarkup: ReplyMarkup? = null)
|
fun sendTextMessage(chatId: Long, message: String, replyMarkup: ReplyMarkup? = null)
|
||||||
fun sendMediaGroup(chatId: Long, group: MediaGroup)
|
fun sendMediaGroup(chatId: Long, group: MediaGroup)
|
||||||
|
|||||||
@@ -12,10 +12,18 @@ import org.springframework.stereotype.Service
|
|||||||
import org.springframework.context.annotation.Lazy
|
import org.springframework.context.annotation.Lazy
|
||||||
import space.luminic.finance.models.Space
|
import space.luminic.finance.models.Space
|
||||||
import space.luminic.finance.models.Transaction
|
import space.luminic.finance.models.Transaction
|
||||||
|
import space.luminic.finance.repos.SpaceRepo
|
||||||
|
import space.luminic.finance.repos.TransactionRepo
|
||||||
|
import java.time.LocalDate
|
||||||
import java.time.format.DateTimeFormatter
|
import java.time.format.DateTimeFormatter
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
class NotificationServiceImpl(private val userService: UserService, private val bot: Bot) : NotificationService {
|
class NotificationServiceImpl(
|
||||||
|
private val userService: UserService,
|
||||||
|
private val bot: Bot,
|
||||||
|
@Lazy private val transactionRepo: TransactionRepo,
|
||||||
|
@Lazy private val spaceRepo: SpaceRepo
|
||||||
|
) : NotificationService {
|
||||||
private val logger = LoggerFactory.getLogger(this.javaClass)
|
private val logger = LoggerFactory.getLogger(this.javaClass)
|
||||||
|
|
||||||
|
|
||||||
@@ -59,6 +67,31 @@ class NotificationServiceImpl(private val userService: UserService, private val
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun sendPlannedTransactionsReminder() {
|
||||||
|
val today = LocalDate.now()
|
||||||
|
val plannedTxs = transactionRepo.findByDateAndKind(today, Transaction.TransactionKind.PLANNING)
|
||||||
|
|
||||||
|
if (plannedTxs.isEmpty()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Группируем по spaceId. У нас нет Space объекта целиком в ответе findByDateAndKind,
|
||||||
|
// но есть t_space_id в маппере (хотя в модели Transaction.space может быть null).
|
||||||
|
// В RepoImpl маппер заполняет space.id
|
||||||
|
val groupedBySpace = plannedTxs.filter { it.space?.id != null }.groupBy { it.space!!.id!! }
|
||||||
|
|
||||||
|
for ((spaceId, txs) in groupedBySpace) {
|
||||||
|
// Чтобы получить владельца, нужно загрузить Space
|
||||||
|
// Используем системного пользователя или просто id для получения
|
||||||
|
val space = spaceRepo.findSpaceById(spaceId, txs.first().createdBy?.id ?: 0)
|
||||||
|
if (space?.owner?.tgId != null) {
|
||||||
|
val txList = txs.joinToString("\n") { "- ${it.comment}: ${it.amount}" }
|
||||||
|
val text = "📅 На сегодня запланированы транзакции:\n\n$txList"
|
||||||
|
sendTextMessage(space.owner.tgId!!, text, createWebAppButton(spaceId))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun sendTXNotification(
|
override fun sendTXNotification(
|
||||||
action: TxActionType,
|
action: TxActionType,
|
||||||
space: Space,
|
space: Space,
|
||||||
|
|||||||
@@ -27,6 +27,12 @@ class Scheduler(
|
|||||||
notificationService.sendDailyReminder()
|
notificationService.sendDailyReminder()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Scheduled(cron = "0 0 9 * * *")
|
||||||
|
fun sendPlannedTransactionsReminders() {
|
||||||
|
log.info("Sending planned transactions reminders")
|
||||||
|
notificationService.sendPlannedTransactionsReminder()
|
||||||
|
}
|
||||||
|
|
||||||
// @Scheduled(cron = "0 0 */3 * * *")
|
// @Scheduled(cron = "0 0 */3 * * *")
|
||||||
@Scheduled(fixedRate = 3, timeUnit =TimeUnit.HOURS)
|
@Scheduled(fixedRate = 3, timeUnit =TimeUnit.HOURS)
|
||||||
fun analyzePeriodScheduled() {
|
fun analyzePeriodScheduled() {
|
||||||
|
|||||||
Reference in New Issue
Block a user