119 lines
4.7 KiB
Kotlin
119 lines
4.7 KiB
Kotlin
package space.luminic.finance.services
|
|
|
|
import kotlinx.coroutines.reactive.awaitSingle
|
|
import org.bson.Document
|
|
import org.bson.types.ObjectId
|
|
import org.springframework.data.mongodb.core.ReactiveMongoTemplate
|
|
import org.springframework.data.mongodb.core.aggregation.Aggregation.addFields
|
|
import org.springframework.data.mongodb.core.aggregation.Aggregation.lookup
|
|
import org.springframework.data.mongodb.core.aggregation.Aggregation.match
|
|
import org.springframework.data.mongodb.core.aggregation.Aggregation.newAggregation
|
|
import org.springframework.data.mongodb.core.aggregation.Aggregation.unwind
|
|
import org.springframework.data.mongodb.core.aggregation.AggregationOperation
|
|
import org.springframework.data.mongodb.core.aggregation.ConvertOperators
|
|
import org.springframework.data.mongodb.core.aggregation.LookupOperation
|
|
import org.springframework.data.mongodb.core.query.Criteria
|
|
import org.springframework.stereotype.Service
|
|
import space.luminic.finance.dtos.AccountDTO
|
|
import space.luminic.finance.models.Account
|
|
import space.luminic.finance.models.Transaction
|
|
import space.luminic.finance.repos.AccountRepo
|
|
|
|
@Service
|
|
class AccountServiceImpl(
|
|
private val accountRepo: AccountRepo,
|
|
private val mongoTemplate: ReactiveMongoTemplate,
|
|
private val spaceService: SpaceService,
|
|
private val transactionService: TransactionService
|
|
): AccountService {
|
|
|
|
private fun basicAggregation(spaceId: String): List<AggregationOperation> {
|
|
val addFieldsAsOJ = addFields()
|
|
.addField("createdByOI")
|
|
.withValue(ConvertOperators.valueOf("createdById").convertToObjectId())
|
|
.addField("updatedByOI")
|
|
.withValue(ConvertOperators.valueOf("updatedById").convertToObjectId())
|
|
.build()
|
|
val lookupCreatedBy = lookup("users", "createdByOI", "_id", "createdBy")
|
|
val unwindCreatedBy = unwind("createdBy")
|
|
|
|
val lookupUpdatedBy = lookup("users", "updatedByOI", "_id", "updatedBy")
|
|
val unwindUpdatedBy = unwind("updatedBy")
|
|
|
|
val matchCriteria = mutableListOf<Criteria>()
|
|
matchCriteria.add(Criteria.where("spaceId").`is`(spaceId))
|
|
matchCriteria.add(Criteria.where("isDeleted").`is`(false))
|
|
val matchStage = match(Criteria().andOperator(*matchCriteria.toTypedArray()))
|
|
|
|
return listOf(addFieldsAsOJ, lookupCreatedBy, unwindCreatedBy, lookupUpdatedBy, unwindUpdatedBy, matchStage)
|
|
}
|
|
|
|
|
|
override suspend fun getAccounts(spaceId: String): List<Account> {
|
|
val basicAggregation = basicAggregation(spaceId)
|
|
val aggregation = newAggregation(*basicAggregation.toTypedArray())
|
|
return mongoTemplate.aggregate(aggregation, "accounts", Account::class.java)
|
|
.collectList()
|
|
.awaitSingle()
|
|
}
|
|
|
|
override suspend fun getAccount(
|
|
spaceId: String,
|
|
accountId: String
|
|
): Account {
|
|
val basicAggregation = basicAggregation(spaceId)
|
|
val matchStage = match (Criteria.where("_id").`is`(ObjectId(accountId)))
|
|
val aggregation = newAggregation(matchStage, *basicAggregation.toTypedArray())
|
|
return mongoTemplate.aggregate(aggregation, "accounts", Account::class.java)
|
|
.awaitSingle()
|
|
}
|
|
|
|
override suspend fun getAccountTransactions(
|
|
spaceId: String,
|
|
accountId: String
|
|
): List<Transaction> {
|
|
val space = spaceService.checkSpace(spaceId)
|
|
val filter = TransactionService.TransactionsFilter(
|
|
accountId = accountId,
|
|
)
|
|
return transactionService.getTransactions(spaceId, filter, "date", "ASC")
|
|
}
|
|
|
|
override suspend fun createAccount(
|
|
spaceId: String,
|
|
account: AccountDTO.CreateAccountDTO
|
|
): Account {
|
|
val createdAccount = Account(
|
|
type = account.type,
|
|
spaceId = spaceId,
|
|
name = account.name,
|
|
currencyCode = account.currencyCode,
|
|
amount = account.amount,
|
|
goalId = account.goalId,
|
|
)
|
|
return accountRepo.save(createdAccount).awaitSingle()
|
|
}
|
|
|
|
override suspend fun updateAccount(
|
|
spaceId: String,
|
|
account: AccountDTO.UpdateAccountDTO
|
|
): Account {
|
|
val existingAccount = getAccount(spaceId, account.id)
|
|
val newAccount = existingAccount.copy(
|
|
name = account.name,
|
|
type = account.type,
|
|
currencyCode = account.currencyCode,
|
|
amount = account.amount,
|
|
goalId = account.goalId,
|
|
)
|
|
return accountRepo.save(newAccount).awaitSingle()
|
|
}
|
|
|
|
override suspend fun deleteAccount(spaceId: String, accountId: String) {
|
|
val existingAccount = getAccount(spaceId, accountId)
|
|
|
|
existingAccount.isDeleted = true
|
|
accountRepo.save(existingAccount).awaitSingle()
|
|
|
|
}
|
|
} |