package space.luminic.finance.services import org.springframework.stereotype.Service import space.luminic.finance.dtos.TransactionDTO import space.luminic.finance.models.NotFoundException import space.luminic.finance.models.Transaction import space.luminic.finance.repos.TransactionRepo import space.luminic.finance.services.gpt.CategorizeService @Service class TransactionServiceImpl( private val spaceService: SpaceService, private val categoryService: CategoryService, private val transactionRepo: TransactionRepo, private val authService: AuthService, private val categorizeService: CategorizeService, ) : TransactionService { override fun getTransactions( spaceId: Int, filter: TransactionService.TransactionsFilter, sortBy: String, sortDirection: String ): List { val transactions = transactionRepo.findAllBySpaceId(spaceId, filter) return transactions } override fun getTransaction( spaceId: Int, transactionId: Int ): Transaction { spaceService.getSpace(spaceId, null) return transactionRepo.findBySpaceIdAndId(spaceId, transactionId) ?: throw NotFoundException("Transaction with id $transactionId not found") } override fun createTransaction( spaceId: Int, transaction: TransactionDTO.CreateTransactionDTO ): Int { val userId = authService.getSecurityUserId() val space = spaceService.getSpace(spaceId, null) val category = transaction.categoryId?.let { categoryService.getCategory(spaceId, it) } val transaction = Transaction( space = space, type = transaction.type, kind = transaction.kind, category = category, comment = transaction.comment, amount = transaction.amount, fees = transaction.fees, date = transaction.date, recurrentId = transaction.recurrentId, ) return transactionRepo.create(transaction, userId) } override fun batchCreate(spaceId: Int, transactions: List, createdById: Int?) { val userId = createdById ?: authService.getSecurityUserId() val space = spaceService.getSpace(spaceId, userId) val transactionsToCreate = mutableListOf() transactions.forEach { transaction -> val category = transaction.categoryId?.let { categoryService.getCategory(spaceId, it) } transactionsToCreate.add( Transaction( space = space, type = transaction.type, kind = transaction.kind, category = category, comment = transaction.comment, amount = transaction.amount, fees = transaction.fees, date = transaction.date, recurrentId = transaction.recurrentId, ) ) } transactionRepo.createBatch(transactionsToCreate, userId) } override fun updateTransaction( spaceId: Int, transactionId: Int, transaction: TransactionDTO.UpdateTransactionDTO ): Int { val space = spaceService.getSpace(spaceId, null) val existingTransaction = getTransaction(space.id!!, transactionId) val newCategory = transaction.categoryId?.let { categoryService.getCategory(spaceId, it) } val updatedTransaction = Transaction( id = existingTransaction.id, space = existingTransaction.space, parent = existingTransaction.parent, type = transaction.type, kind = transaction.kind, category = newCategory, comment = transaction.comment, amount = transaction.amount, fees = transaction.fees, date = transaction.date, isDeleted = existingTransaction.isDeleted, isDone = transaction.isDone, createdBy = existingTransaction.createdBy, createdAt = existingTransaction.createdAt, tgChatId = existingTransaction.tgChatId, tgMessageId = existingTransaction.tgMessageId, ) if ((existingTransaction.category == null && updatedTransaction.category != null) || (existingTransaction.category?.id != updatedTransaction.category?.id)) { categorizeService.notifyThatCategorySelected(updatedTransaction) } return transactionRepo.update(updatedTransaction) } override fun deleteTransaction(spaceId: Int, transactionId: Int) { val space = spaceService.getSpace(spaceId, null) getTransaction(space.id!!, transactionId) transactionRepo.delete(transactionId) } override fun deleteByRecurrentId(spaceId: Int, recurrentId: Int) { TODO("Not yet implemented") } }