Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2452e5935f |
@@ -1,19 +0,0 @@
|
||||
package space.luminic.finance.api
|
||||
|
||||
import org.springframework.web.bind.annotation.GetMapping
|
||||
import org.springframework.web.bind.annotation.PathVariable
|
||||
import org.springframework.web.bind.annotation.RequestMapping
|
||||
import org.springframework.web.bind.annotation.RestController
|
||||
import space.luminic.finance.dtos.GoalDTO
|
||||
import space.luminic.finance.mappers.GoalMapper.toDto
|
||||
import space.luminic.finance.services.GoalService
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/spaces/{spaceId}/goals")
|
||||
class GoalController(private val goalService: GoalService) {
|
||||
|
||||
@GetMapping
|
||||
fun findAll(@PathVariable spaceId: Int): List<GoalDTO> {
|
||||
return goalService.findAllBySpaceId(spaceId).map { it.toDto() }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package space.luminic.finance.api
|
||||
|
||||
import org.springframework.web.bind.annotation.GetMapping
|
||||
import org.springframework.web.bind.annotation.PathVariable
|
||||
import org.springframework.web.bind.annotation.RequestMapping
|
||||
import org.springframework.web.bind.annotation.RestController
|
||||
import space.luminic.finance.dtos.TargetDTO
|
||||
import space.luminic.finance.mappers.TargetMapper.toDto
|
||||
import space.luminic.finance.services.TargetService
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/spaces/{spaceId}/targets")
|
||||
class TargetController(private val targetService: TargetService) {
|
||||
|
||||
@GetMapping
|
||||
fun findAll(@PathVariable spaceId: Int): List<TargetDTO> {
|
||||
return targetService.findAllBySpaceId(spaceId).map { it.toDto() }
|
||||
}
|
||||
}
|
||||
@@ -1,36 +1,37 @@
|
||||
package space.luminic.finance.dtos
|
||||
|
||||
import space.luminic.finance.models.Goal
|
||||
import space.luminic.finance.models.Goal.GoalType
|
||||
import space.luminic.finance.models.Target
|
||||
import space.luminic.finance.models.Target.TargetType
|
||||
import space.luminic.finance.models.Transaction
|
||||
import java.math.BigDecimal
|
||||
import java.time.Instant
|
||||
import java.time.LocalDate
|
||||
|
||||
data class GoalDTO(
|
||||
data class TargetDTO(
|
||||
val id: Int,
|
||||
val type: GoalType,
|
||||
val type: TargetType,
|
||||
val name: String,
|
||||
val description: String? = null,
|
||||
val amount: BigDecimal,
|
||||
val currentAmount: BigDecimal,
|
||||
val date: LocalDate,
|
||||
val components: List<Goal.GoalComponent>,
|
||||
val components: List<Target.TargetComponent>,
|
||||
val transactions: List<Transaction>,
|
||||
val createdBy: UserDTO,
|
||||
val createdAt: Instant,
|
||||
val updatedBy: UserDTO? = null,
|
||||
val updatedAt: Instant? = null,
|
||||
) {
|
||||
data class CreateGoalDTO(
|
||||
val type: GoalType,
|
||||
data class CreateTargetDTO(
|
||||
val type: TargetType,
|
||||
val name: String,
|
||||
val description: String?,
|
||||
val amount: BigDecimal,
|
||||
val date: LocalDate
|
||||
)
|
||||
|
||||
data class UpdateGoalDTO(
|
||||
val type: GoalType,
|
||||
data class UpdateTargetDTO(
|
||||
val type: TargetType,
|
||||
val name: String,
|
||||
val description: String?,
|
||||
val amount: BigDecimal,
|
||||
@@ -1,22 +1,26 @@
|
||||
package space.luminic.finance.mappers
|
||||
|
||||
import space.luminic.finance.dtos.GoalDTO
|
||||
import space.luminic.finance.dtos.TargetDTO
|
||||
import space.luminic.finance.mappers.UserMapper.toDto
|
||||
import space.luminic.finance.models.Goal
|
||||
import space.luminic.finance.models.Target
|
||||
|
||||
object GoalMapper {
|
||||
object TargetMapper {
|
||||
|
||||
fun Goal.toDto() = GoalDTO(
|
||||
id = this.id ?: throw IllegalArgumentException("Goal id is not provided"),
|
||||
fun Target.toDto() = TargetDTO(
|
||||
id = this.id ?: throw IllegalArgumentException("Target id is not provided"),
|
||||
type = this.type,
|
||||
name = this.name,
|
||||
description = this.description,
|
||||
amount = this.amount,
|
||||
currentAmount = this.currentAmount,
|
||||
date = this.untilDate,
|
||||
components = this.components,
|
||||
transactions = this.transactions,
|
||||
createdBy = (this.createdBy ?: throw IllegalArgumentException("created by not provided")).toDto(),
|
||||
createdAt = this.createdAt ?: throw IllegalArgumentException("created at not provided"),
|
||||
updatedBy = this.updatedBy?.toDto(),
|
||||
updatedAt = this.updatedAt
|
||||
updatedAt = this.updatedAt,
|
||||
|
||||
|
||||
)
|
||||
}
|
||||
@@ -8,22 +8,22 @@ import java.math.BigDecimal
|
||||
import java.time.Instant
|
||||
import java.time.LocalDate
|
||||
|
||||
data class Goal(
|
||||
data class Target(
|
||||
var id: Int? = null,
|
||||
val space: Space? = null,
|
||||
val type: GoalType,
|
||||
val type: TargetType,
|
||||
val name: String,
|
||||
val description: String? = null,
|
||||
val amount: BigDecimal,
|
||||
val components: List<GoalComponent> = emptyList(),
|
||||
val components: List<TargetComponent> = emptyList(),
|
||||
val transactions: List<Transaction> = emptyList(),
|
||||
val untilDate: LocalDate,
|
||||
@CreatedBy var createdBy: User? = null,
|
||||
var createdBy: User? = null,
|
||||
|
||||
@CreatedDate var createdAt: Instant? = null,
|
||||
@LastModifiedBy var updatedBy: User? = null,
|
||||
var createdAt: Instant? = null,
|
||||
var updatedBy: User? = null,
|
||||
|
||||
@LastModifiedDate var updatedAt: Instant? = null,
|
||||
var updatedAt: Instant? = null,
|
||||
) {
|
||||
|
||||
var currentAmount: BigDecimal = {
|
||||
@@ -31,7 +31,7 @@ data class Goal(
|
||||
} as BigDecimal
|
||||
|
||||
|
||||
data class GoalComponent(
|
||||
data class TargetComponent(
|
||||
val id: Int? = null,
|
||||
val name: String,
|
||||
val amount: BigDecimal,
|
||||
@@ -39,8 +39,9 @@ data class Goal(
|
||||
val date: LocalDate = LocalDate.now(),
|
||||
)
|
||||
|
||||
enum class GoalType(val displayName: String, val icon: String) {
|
||||
enum class TargetType(val displayName: String, val icon: String) {
|
||||
AUTO("Авто", "🏎️"),
|
||||
LEISURE("Досуг", "💃"),
|
||||
VACATION("Отпуск", "🏖️"),
|
||||
GOODS("Покупка", "🛍️"),
|
||||
OTHER("Прочее", "💸")
|
||||
@@ -1,20 +0,0 @@
|
||||
package space.luminic.finance.repos
|
||||
|
||||
import space.luminic.finance.models.Goal
|
||||
|
||||
interface GoalRepo {
|
||||
|
||||
fun findAllBySpaceId(spaceId: Int) : List<Goal>
|
||||
fun findBySpaceIdAndId(spaceId: Int, id: Int) : Goal?
|
||||
fun create(goal: Goal, createdById: Int): Int
|
||||
fun update(goal: Goal, updatedById: Int)
|
||||
fun delete(spaceId: Int, id: Int)
|
||||
fun getComponents(spaceId: Int, goalId: Int): List<Goal.GoalComponent>
|
||||
fun getComponent(spaceId: Int, goalId: Int, id: Int): Goal.GoalComponent?
|
||||
fun createComponent(goalId: Int, component: Goal.GoalComponent, createdById: Int): Int
|
||||
fun updateComponent(goalId: Int, componentId: Int, component: Goal.GoalComponent, updatedById: Int)
|
||||
fun deleteComponent(goalId: Int, componentId: Int)
|
||||
|
||||
fun assignTransaction(goalId: Int, transactionId: Int)
|
||||
fun refuseTransaction(goalId: Int, transactionId: Int)
|
||||
}
|
||||
20
src/main/kotlin/space/luminic/finance/repos/TargetRepo.kt
Normal file
20
src/main/kotlin/space/luminic/finance/repos/TargetRepo.kt
Normal file
@@ -0,0 +1,20 @@
|
||||
package space.luminic.finance.repos
|
||||
|
||||
import space.luminic.finance.models.Target
|
||||
|
||||
interface TargetRepo {
|
||||
|
||||
fun findAllBySpaceId(spaceId: Int) : List<Target>
|
||||
fun findBySpaceIdAndId(spaceId: Int, id: Int) : Target?
|
||||
fun create(target: Target, createdById: Int): Int
|
||||
fun update(target: Target, updatedById: Int)
|
||||
fun delete(spaceId: Int, id: Int)
|
||||
fun getComponents(spaceId: Int, targetId: Int): List<Target.TargetComponent>
|
||||
fun getComponent(spaceId: Int, targetId: Int, id: Int): Target.TargetComponent?
|
||||
fun createComponent(targetId: Int, component: Target.TargetComponent, createdById: Int): Int
|
||||
fun updateComponent(targetId: Int, componentId: Int, component: Target.TargetComponent, updatedById: Int)
|
||||
fun deleteComponent(targetId: Int, componentId: Int)
|
||||
|
||||
fun assignTransaction(targetId: Int, transactionId: Int)
|
||||
fun refuseTransaction(targetId: Int, transactionId: Int)
|
||||
}
|
||||
@@ -3,17 +3,17 @@ package space.luminic.finance.repos
|
||||
import org.springframework.jdbc.core.RowMapper
|
||||
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate
|
||||
import org.springframework.stereotype.Repository
|
||||
import space.luminic.finance.models.Goal
|
||||
import space.luminic.finance.models.Target
|
||||
import space.luminic.finance.models.User
|
||||
|
||||
@Repository
|
||||
class GoalRepoImpl(
|
||||
class TargetRepoImpl(
|
||||
private val jdbcTemplate: NamedParameterJdbcTemplate
|
||||
) : GoalRepo {
|
||||
private val goalRowMapper = RowMapper { rs, _ ->
|
||||
Goal(
|
||||
) : TargetRepo {
|
||||
private val targetRowMapper = RowMapper { rs, _ ->
|
||||
Target(
|
||||
id = rs.getInt("g_id"),
|
||||
type = Goal.GoalType.valueOf(rs.getString("g_type")),
|
||||
type = Target.TargetType.valueOf(rs.getString("g_type")),
|
||||
name = rs.getString("g_name"),
|
||||
description = rs.getString("g_description"),
|
||||
amount = rs.getBigDecimal("g_amount"),
|
||||
@@ -30,7 +30,7 @@ class GoalRepoImpl(
|
||||
}
|
||||
|
||||
private val componentRowMapper = RowMapper { rs, _ ->
|
||||
Goal.GoalComponent(
|
||||
Target.TargetComponent(
|
||||
id = rs.getInt("gc_id"),
|
||||
name = rs.getString("gc_name"),
|
||||
amount = rs.getBigDecimal("gc_amount"),
|
||||
@@ -39,7 +39,7 @@ class GoalRepoImpl(
|
||||
)
|
||||
}
|
||||
|
||||
override fun findAllBySpaceId(spaceId: Int): List<Goal> {
|
||||
override fun findAllBySpaceId(spaceId: Int): List<Target> {
|
||||
val sql = """
|
||||
select
|
||||
g.id as g_id,
|
||||
@@ -51,7 +51,7 @@ class GoalRepoImpl(
|
||||
created_by.username as created_by_username,
|
||||
created_by.first_name as created_by_first_name,
|
||||
g.created_at as g_created_at
|
||||
from finance.goals g
|
||||
from finance.targets g
|
||||
join finance.users created_by on g.created_by_id = created_by.id
|
||||
where g.space_id = :spaceId
|
||||
|
||||
@@ -60,10 +60,10 @@ class GoalRepoImpl(
|
||||
val params = mapOf(
|
||||
"space_id" to spaceId,
|
||||
)
|
||||
return jdbcTemplate.query(sql, params, goalRowMapper)
|
||||
return jdbcTemplate.query(sql, params, targetRowMapper)
|
||||
}
|
||||
|
||||
override fun findBySpaceIdAndId(spaceId: Int, id: Int): Goal? {
|
||||
override fun findBySpaceIdAndId(spaceId: Int, id: Int): Target? {
|
||||
val sql = """
|
||||
select
|
||||
g.id as g_id,
|
||||
@@ -75,7 +75,7 @@ class GoalRepoImpl(
|
||||
created_by.username as created_by_username,
|
||||
created_by.first_name as created_by_first_name,
|
||||
g.created_at as g_created_at
|
||||
from finance.goals g
|
||||
from finance.targets g
|
||||
join finance.users created_by on g.created_by_id = created_by.id
|
||||
where g.space_id = :spaceId and g.id = :id
|
||||
|
||||
@@ -85,12 +85,12 @@ class GoalRepoImpl(
|
||||
"space_id" to spaceId,
|
||||
"id" to id,
|
||||
)
|
||||
return jdbcTemplate.query(sql, params, goalRowMapper).firstOrNull()
|
||||
return jdbcTemplate.query(sql, params, targetRowMapper).firstOrNull()
|
||||
}
|
||||
|
||||
override fun create(goal: Goal, createdById: Int): Int {
|
||||
override fun create(target: Target, createdById: Int): Int {
|
||||
val sql = """
|
||||
insert into finance.goals(
|
||||
insert into finance.targets(
|
||||
type,
|
||||
name,
|
||||
description,
|
||||
@@ -108,19 +108,19 @@ class GoalRepoImpl(
|
||||
returning id
|
||||
""".trimIndent()
|
||||
val params = mapOf(
|
||||
"type" to goal.type,
|
||||
"name" to goal.name,
|
||||
"description" to goal.description,
|
||||
"amount" to goal.amount,
|
||||
"until_date" to goal.untilDate,
|
||||
"type" to target.type,
|
||||
"name" to target.name,
|
||||
"description" to target.description,
|
||||
"amount" to target.amount,
|
||||
"until_date" to target.untilDate,
|
||||
"created_by_id" to createdById
|
||||
)
|
||||
return jdbcTemplate.queryForObject(sql, params, Int::class.java)!!
|
||||
}
|
||||
|
||||
override fun update(goal: Goal, updatedById: Int) {
|
||||
override fun update(target: Target, updatedById: Int) {
|
||||
val sql = """
|
||||
update finance.goals set
|
||||
update finance.targets set
|
||||
type = :type,
|
||||
name = :name,
|
||||
description = :description,
|
||||
@@ -131,12 +131,12 @@ class GoalRepoImpl(
|
||||
where id = :id
|
||||
""".trimIndent()
|
||||
val params = mapOf(
|
||||
"id" to goal.id,
|
||||
"type" to goal.type.name,
|
||||
"name" to goal.name,
|
||||
"description" to goal.description,
|
||||
"amount" to goal.amount,
|
||||
"until_date" to goal.untilDate,
|
||||
"id" to target.id,
|
||||
"type" to target.type.name,
|
||||
"name" to target.name,
|
||||
"description" to target.description,
|
||||
"amount" to target.amount,
|
||||
"until_date" to target.untilDate,
|
||||
"updated_by_id" to updatedById
|
||||
|
||||
)
|
||||
@@ -145,7 +145,7 @@ class GoalRepoImpl(
|
||||
|
||||
override fun delete(spaceId: Int, id: Int) {
|
||||
val sql = """
|
||||
delete from finance.goals where id = :id
|
||||
delete from finance.targets where id = :id
|
||||
|
||||
""".trimIndent()
|
||||
val params = mapOf(
|
||||
@@ -156,8 +156,8 @@ class GoalRepoImpl(
|
||||
|
||||
override fun getComponents(
|
||||
spaceId: Int,
|
||||
goalId: Int
|
||||
): List<Goal.GoalComponent> {
|
||||
targetId: Int
|
||||
): List<Target.TargetComponent> {
|
||||
val sql = """
|
||||
select
|
||||
gc.id as gc_id,
|
||||
@@ -165,11 +165,11 @@ class GoalRepoImpl(
|
||||
gc.amount as gc_amount,
|
||||
gc.is_done as gc_is_done,
|
||||
gc.date as gc_date
|
||||
from finance.goals_components gc
|
||||
where gc.goal_id = :goal_id
|
||||
from finance.targets_components gc
|
||||
where gc.target_id = :target_id
|
||||
""".trimIndent()
|
||||
val params = mapOf(
|
||||
"goal_id" to goalId
|
||||
"target_id" to targetId
|
||||
)
|
||||
return jdbcTemplate.query(sql, params, componentRowMapper)
|
||||
|
||||
@@ -177,9 +177,9 @@ class GoalRepoImpl(
|
||||
|
||||
override fun getComponent(
|
||||
spaceId: Int,
|
||||
goalId: Int,
|
||||
targetId: Int,
|
||||
id: Int
|
||||
): Goal.GoalComponent? {
|
||||
): Target.TargetComponent? {
|
||||
val sql = """
|
||||
select
|
||||
gc.id as gc_id,
|
||||
@@ -187,27 +187,27 @@ class GoalRepoImpl(
|
||||
gc.amount as gc_amount,
|
||||
gc.is_done as gc_is_done,
|
||||
gc.date as gc_date
|
||||
from finance.goals_components gc
|
||||
where gc.goal_id = :goal_id and gc.id = :id
|
||||
from finance.targets_components gc
|
||||
where gc.target_id = :target_id and gc.id = :id
|
||||
""".trimIndent()
|
||||
val params = mapOf(
|
||||
"goal_id" to goalId,
|
||||
"target_id" to targetId,
|
||||
"id" to id
|
||||
)
|
||||
return jdbcTemplate.query(sql, params, componentRowMapper).firstOrNull()
|
||||
}
|
||||
|
||||
override fun createComponent(goalId: Int, component: Goal.GoalComponent, createdById: Int): Int {
|
||||
override fun createComponent(targetId: Int, component: Target.TargetComponent, createdById: Int): Int {
|
||||
val sql = """
|
||||
insert into finance.goals_components(
|
||||
goal_id,
|
||||
insert into finance.targets_components(
|
||||
target_id,
|
||||
name,
|
||||
amount,
|
||||
is_done,
|
||||
date,
|
||||
created_by_id
|
||||
) values (
|
||||
:goal_id,
|
||||
:target_id,
|
||||
:name,
|
||||
:amount,
|
||||
:is_done,
|
||||
@@ -216,7 +216,7 @@ class GoalRepoImpl(
|
||||
returning id
|
||||
""".trimIndent()
|
||||
val params = mapOf(
|
||||
"goal_id" to goalId,
|
||||
"target_id" to targetId,
|
||||
"name" to component.name,
|
||||
"amount" to component.amount,
|
||||
"is_done" to component.isDone,
|
||||
@@ -226,17 +226,17 @@ class GoalRepoImpl(
|
||||
return jdbcTemplate.queryForObject(sql, params, Int::class.java)!!
|
||||
}
|
||||
|
||||
override fun updateComponent(goalId: Int, componentId: Int, component: Goal.GoalComponent, updatedById: Int) {
|
||||
override fun updateComponent(targetId: Int, componentId: Int, component: Target.TargetComponent, updatedById: Int) {
|
||||
val sql = """
|
||||
update finance.goals_components set
|
||||
update finance.targets_components set
|
||||
name = :name,
|
||||
amount = :amount,
|
||||
is_done = :is_done,
|
||||
updated_by_id = :updated_by_id
|
||||
where goal_id = :goalId and id = :componentId
|
||||
where target_id = :targetId and id = :componentId
|
||||
""".trimIndent()
|
||||
val params = mapOf(
|
||||
"goalId" to goalId,
|
||||
"targetId" to targetId,
|
||||
"componentId" to componentId,
|
||||
"name" to component.name,
|
||||
"amount" to component.amount,
|
||||
@@ -247,35 +247,35 @@ class GoalRepoImpl(
|
||||
jdbcTemplate.update(sql, params)
|
||||
}
|
||||
|
||||
override fun deleteComponent(goalId: Int, componentId: Int) {
|
||||
override fun deleteComponent(targetId: Int, componentId: Int) {
|
||||
val sql = """
|
||||
delete from finance.goals_components where goal_id = :goalId and id = :componentId
|
||||
delete from finance.targets_components where target_id = :targetId and id = :componentId
|
||||
""".trimIndent()
|
||||
val params = mapOf(
|
||||
"goalId" to goalId,
|
||||
"targetId" to targetId,
|
||||
"componentId" to componentId
|
||||
)
|
||||
jdbcTemplate.update(sql, params)
|
||||
}
|
||||
|
||||
override fun assignTransaction(goalId: Int, transactionId: Int) {
|
||||
override fun assignTransaction(targetId: Int, transactionId: Int) {
|
||||
val sql = """
|
||||
insert into finance.goals_transactions(goal_id, transactions_id)
|
||||
values (:goal_id, :transaction_id)
|
||||
insert into finance.targets_transactions(target_id, transactions_id)
|
||||
values (:targetId, :transaction_id)
|
||||
""".trimIndent()
|
||||
val params = mapOf(
|
||||
"goal_id" to goalId,
|
||||
"targetId" to targetId,
|
||||
"transaction_id" to transactionId
|
||||
)
|
||||
jdbcTemplate.update(sql, params)
|
||||
}
|
||||
|
||||
override fun refuseTransaction(goalId: Int, transactionId: Int) {
|
||||
override fun refuseTransaction(targetId: Int, transactionId: Int) {
|
||||
val sql = """
|
||||
delete from finance.goals_transactions where goal_id = :goalId and transactions_id = :transactionId
|
||||
delete from finance.targets_transactions where target_id = :goalId and transactions_id = :transactionId
|
||||
""".trimIndent()
|
||||
val params = mapOf(
|
||||
"goal_id" to goalId,
|
||||
"target_id" to targetId,
|
||||
"transaction_id" to transactionId
|
||||
)
|
||||
jdbcTemplate.update(sql, params)
|
||||
@@ -7,6 +7,8 @@ import space.luminic.finance.models.Category
|
||||
import space.luminic.finance.models.Transaction
|
||||
import space.luminic.finance.models.User
|
||||
import space.luminic.finance.services.TransactionService
|
||||
import java.time.LocalDate
|
||||
import java.time.LocalDateTime
|
||||
|
||||
@Repository
|
||||
class TransactionRepoImpl(
|
||||
@@ -109,6 +111,9 @@ class TransactionRepoImpl(
|
||||
filters.dateFrom?.let {
|
||||
sql += " AND t.date >= :dateFrom"
|
||||
params.put("dateFrom", it)
|
||||
} ?: {
|
||||
sql += " AND t.date >= :dateFrom"
|
||||
params.put("dateFrom", LocalDate.now().minusMonths(1))
|
||||
}
|
||||
filters.dateTo?.let {
|
||||
sql += " AND t.date <= :dateTo"
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
package space.luminic.finance.services
|
||||
|
||||
import space.luminic.finance.dtos.GoalDTO
|
||||
import space.luminic.finance.models.Goal
|
||||
|
||||
interface GoalService {
|
||||
fun findAllBySpaceId(spaceId: Int): List<Goal>
|
||||
fun findBySpaceIdAndId(spaceId: Int, id: Int): Goal
|
||||
fun create(spaceId: Int,goal: GoalDTO.CreateGoalDTO): Int
|
||||
fun update(spaceId: Int, goalId: Int, goal: GoalDTO.UpdateGoalDTO)
|
||||
fun delete(spaceId: Int, id: Int)
|
||||
|
||||
fun getComponents(spaceId: Int, goalId: Int): List<Goal.GoalComponent>
|
||||
fun getComponent(spaceId: Int, goalId: Int, id: Int): Goal.GoalComponent?
|
||||
fun createComponent(spaceId: Int, goalId: Int, component: Goal.GoalComponent): Int
|
||||
fun updateComponent(spaceId: Int, goalId: Int, component: Goal.GoalComponent)
|
||||
fun deleteComponent(spaceId: Int, goalId: Int, id: Int)
|
||||
|
||||
fun assignTransaction(spaceId: Int, goalId: Int, transactionId: Int)
|
||||
fun refuseTransaction(spaceId: Int,goalId: Int, transactionId: Int)
|
||||
|
||||
}
|
||||
@@ -1,140 +0,0 @@
|
||||
package space.luminic.finance.services
|
||||
|
||||
import org.springframework.stereotype.Service
|
||||
import space.luminic.finance.dtos.GoalDTO
|
||||
import space.luminic.finance.models.Goal
|
||||
import space.luminic.finance.models.NotFoundException
|
||||
import space.luminic.finance.repos.GoalRepo
|
||||
import space.luminic.finance.repos.SpaceRepo
|
||||
import space.luminic.finance.repos.TransactionRepo
|
||||
|
||||
@Service
|
||||
class GoalServiceImpl(
|
||||
private val goalRepo: GoalRepo,
|
||||
private val spaceRepo: SpaceRepo,
|
||||
private val authService: AuthService,
|
||||
private val transactionRepo: TransactionRepo
|
||||
) : GoalService {
|
||||
override fun findAllBySpaceId(spaceId: Int): List<Goal> {
|
||||
val userId = authService.getSecurityUserId()
|
||||
spaceRepo.findSpaceById(spaceId, userId)
|
||||
return goalRepo.findAllBySpaceId(spaceId)
|
||||
}
|
||||
|
||||
override fun findBySpaceIdAndId(spaceId: Int, id: Int): Goal {
|
||||
val userId = authService.getSecurityUserId()
|
||||
spaceRepo.findSpaceById(spaceId, userId)
|
||||
return goalRepo.findBySpaceIdAndId(spaceId, userId) ?: throw NotFoundException("Goal $id not found")
|
||||
}
|
||||
|
||||
override fun create(spaceId: Int, goal: GoalDTO.CreateGoalDTO): Int {
|
||||
val userId = authService.getSecurityUserId()
|
||||
spaceRepo.findSpaceById(spaceId, userId)
|
||||
val creatingGoal = Goal(
|
||||
type = goal.type,
|
||||
name = goal.name,
|
||||
amount = goal.amount,
|
||||
untilDate = goal.date
|
||||
)
|
||||
return goalRepo.create(creatingGoal, userId)
|
||||
}
|
||||
|
||||
override fun update(spaceId: Int, goalId: Int, goal: GoalDTO.UpdateGoalDTO) {
|
||||
val userId = authService.getSecurityUserId()
|
||||
spaceRepo.findSpaceById(spaceId, userId)
|
||||
val existingGoal =
|
||||
goalRepo.findBySpaceIdAndId(spaceId, goalId) ?: throw NotFoundException("Goal $goalId not found")
|
||||
val updatedGoal = existingGoal.copy(
|
||||
type = goal.type,
|
||||
name = goal.name,
|
||||
description = goal.description,
|
||||
amount = goal.amount,
|
||||
untilDate = goal.date
|
||||
)
|
||||
goalRepo.update(updatedGoal, userId)
|
||||
}
|
||||
|
||||
override fun delete(spaceId: Int, id: Int) {
|
||||
goalRepo.delete(spaceId, id)
|
||||
}
|
||||
|
||||
override fun getComponents(
|
||||
spaceId: Int,
|
||||
goalId: Int
|
||||
): List<Goal.GoalComponent> {
|
||||
val userId = authService.getSecurityUserId()
|
||||
spaceRepo.findSpaceById(spaceId, userId)
|
||||
goalRepo.findBySpaceIdAndId(spaceId, goalId) ?: throw NotFoundException("Goal $goalId not found")
|
||||
return goalRepo.getComponents(spaceId, goalId)
|
||||
}
|
||||
|
||||
override fun getComponent(
|
||||
spaceId: Int,
|
||||
goalId: Int,
|
||||
id: Int
|
||||
): Goal.GoalComponent? {
|
||||
val userId = authService.getSecurityUserId()
|
||||
spaceRepo.findSpaceById(spaceId, userId)
|
||||
goalRepo.findBySpaceIdAndId(spaceId, goalId) ?: throw NotFoundException("Goal $goalId not found")
|
||||
return goalRepo.getComponent(spaceId, goalId, id)
|
||||
}
|
||||
|
||||
override fun createComponent(
|
||||
spaceId: Int,
|
||||
goalId: Int,
|
||||
component: Goal.GoalComponent
|
||||
): Int {
|
||||
val userId = authService.getSecurityUserId()
|
||||
spaceRepo.findSpaceById(spaceId, userId)
|
||||
goalRepo.findBySpaceIdAndId(spaceId, goalId) ?: throw NotFoundException("Goal $goalId not found")
|
||||
return goalRepo.createComponent(goalId, component, userId)
|
||||
}
|
||||
|
||||
override fun updateComponent(
|
||||
spaceId: Int,
|
||||
goalId: Int,
|
||||
component: Goal.GoalComponent
|
||||
) {
|
||||
val userId = authService.getSecurityUserId()
|
||||
spaceRepo.findSpaceById(spaceId, userId)
|
||||
goalRepo.findBySpaceIdAndId(spaceId, goalId) ?: throw NotFoundException("Goal $goalId not found")
|
||||
val existingComponent = goalRepo.getComponent(spaceId, goalId, component.id!!)
|
||||
?: throw NotFoundException("Component $goalId not found")
|
||||
val updatedComponent = existingComponent.copy(
|
||||
name = component.name,
|
||||
amount = component.amount,
|
||||
isDone = component.isDone,
|
||||
date = component.date
|
||||
)
|
||||
goalRepo.updateComponent(goalId, updatedComponent.id!!, updatedComponent, userId)
|
||||
}
|
||||
|
||||
override fun deleteComponent(spaceId: Int, goalId: Int, id: Int) {
|
||||
val userId = authService.getSecurityUserId()
|
||||
spaceRepo.findSpaceById(spaceId, userId)
|
||||
goalRepo.findBySpaceIdAndId(spaceId, goalId) ?: throw NotFoundException("Goal $goalId not found")
|
||||
goalRepo.getComponent(spaceId, goalId, id) ?: throw NotFoundException("Component $goalId not found")
|
||||
goalRepo.deleteComponent(goalId, id)
|
||||
}
|
||||
|
||||
override fun assignTransaction(spaceId: Int, goalId: Int, transactionId: Int) {
|
||||
val userId = authService.getSecurityUserId()
|
||||
spaceRepo.findSpaceById(spaceId, userId)
|
||||
goalRepo.findBySpaceIdAndId(spaceId, goalId) ?: throw NotFoundException("Goal $goalId not found")
|
||||
transactionRepo.findBySpaceIdAndId(spaceId, transactionId) ?: throw NotFoundException(
|
||||
"Transaction $transactionId not found"
|
||||
)
|
||||
goalRepo.assignTransaction(goalId, transactionId)
|
||||
|
||||
}
|
||||
|
||||
override fun refuseTransaction(spaceId: Int, goalId: Int, transactionId: Int) {
|
||||
val userId = authService.getSecurityUserId()
|
||||
spaceRepo.findSpaceById(spaceId, userId)
|
||||
goalRepo.findBySpaceIdAndId(spaceId, goalId) ?: throw NotFoundException("Goal $goalId not found")
|
||||
transactionRepo.findBySpaceIdAndId(spaceId, transactionId) ?: throw NotFoundException(
|
||||
"Transaction $transactionId not found"
|
||||
)
|
||||
goalRepo.refuseTransaction(goalId, transactionId)
|
||||
}
|
||||
}
|
||||
@@ -110,6 +110,7 @@ class RecurrentOperationServiceImpl(
|
||||
type = if (it.category?.type == Category.CategoryType.EXPENSE) Transaction.TransactionType.EXPENSE else Transaction.TransactionType.INCOME,
|
||||
category = updatedOperation.category,
|
||||
comment = operation.name,
|
||||
amount = updatedOperation.amount,
|
||||
date = LocalDate.of(
|
||||
it.date.year,
|
||||
it.date.monthValue,
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package space.luminic.finance.services
|
||||
|
||||
import space.luminic.finance.dtos.TargetDTO
|
||||
import space.luminic.finance.models.Target
|
||||
|
||||
interface TargetService {
|
||||
fun findAllBySpaceId(spaceId: Int): List<Target>
|
||||
fun findBySpaceIdAndId(spaceId: Int, id: Int): Target
|
||||
fun create(spaceId: Int,target: TargetDTO.CreateTargetDTO): Int
|
||||
fun update(spaceId: Int, targetId: Int, target: TargetDTO.UpdateTargetDTO)
|
||||
fun delete(spaceId: Int, id: Int)
|
||||
|
||||
fun getComponents(spaceId: Int, targetId: Int): List<Target.TargetComponent>
|
||||
fun getComponent(spaceId: Int, targetId: Int, id: Int): Target.TargetComponent?
|
||||
fun createComponent(spaceId: Int, targetId: Int, component: Target.TargetComponent): Int
|
||||
fun updateComponent(spaceId: Int, targetId: Int, component: Target.TargetComponent)
|
||||
fun deleteComponent(spaceId: Int, targetId: Int, id: Int)
|
||||
|
||||
fun assignTransaction(spaceId: Int, targetId: Int, transactionId: Int)
|
||||
fun refuseTransaction(spaceId: Int,targetId: Int, transactionId: Int)
|
||||
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
package space.luminic.finance.services
|
||||
|
||||
import org.springframework.stereotype.Service
|
||||
import space.luminic.finance.dtos.TargetDTO
|
||||
import space.luminic.finance.models.Target
|
||||
import space.luminic.finance.models.NotFoundException
|
||||
import space.luminic.finance.repos.TargetRepo
|
||||
import space.luminic.finance.repos.SpaceRepo
|
||||
import space.luminic.finance.repos.TransactionRepo
|
||||
|
||||
@Service
|
||||
class TargetServiceImpl(
|
||||
private val targetRepo: TargetRepo,
|
||||
private val spaceRepo: SpaceRepo,
|
||||
private val authService: AuthService,
|
||||
private val transactionRepo: TransactionRepo
|
||||
) : TargetService {
|
||||
override fun findAllBySpaceId(spaceId: Int): List<Target> {
|
||||
val userId = authService.getSecurityUserId()
|
||||
spaceRepo.findSpaceById(spaceId, userId)
|
||||
return targetRepo.findAllBySpaceId(spaceId)
|
||||
}
|
||||
|
||||
override fun findBySpaceIdAndId(spaceId: Int, id: Int): Target {
|
||||
val userId = authService.getSecurityUserId()
|
||||
spaceRepo.findSpaceById(spaceId, userId)
|
||||
return targetRepo.findBySpaceIdAndId(spaceId, userId) ?: throw NotFoundException("Goal $id not found")
|
||||
}
|
||||
|
||||
override fun create(spaceId: Int, target: TargetDTO.CreateTargetDTO): Int {
|
||||
val userId = authService.getSecurityUserId()
|
||||
spaceRepo.findSpaceById(spaceId, userId)
|
||||
val creatingTarget = Target(
|
||||
type = target.type,
|
||||
name = target.name,
|
||||
amount = target.amount,
|
||||
untilDate = target.date
|
||||
)
|
||||
return targetRepo.create(creatingTarget, userId)
|
||||
}
|
||||
|
||||
override fun update(spaceId: Int, targetId: Int, target: TargetDTO.UpdateTargetDTO) {
|
||||
val userId = authService.getSecurityUserId()
|
||||
spaceRepo.findSpaceById(spaceId, userId)
|
||||
val existingGoal =
|
||||
targetRepo.findBySpaceIdAndId(spaceId, targetId) ?: throw NotFoundException("Goal $targetId not found")
|
||||
val updatedGoal = existingGoal.copy(
|
||||
type = target.type,
|
||||
name = target.name,
|
||||
description = target.description,
|
||||
amount = target.amount,
|
||||
untilDate = target.date
|
||||
)
|
||||
targetRepo.update(updatedGoal, userId)
|
||||
}
|
||||
|
||||
override fun delete(spaceId: Int, id: Int) {
|
||||
targetRepo.delete(spaceId, id)
|
||||
}
|
||||
|
||||
override fun getComponents(
|
||||
spaceId: Int,
|
||||
targetId: Int
|
||||
): List<Target.TargetComponent> {
|
||||
val userId = authService.getSecurityUserId()
|
||||
spaceRepo.findSpaceById(spaceId, userId)
|
||||
targetRepo.findBySpaceIdAndId(spaceId, targetId) ?: throw NotFoundException("Goal $targetId not found")
|
||||
return targetRepo.getComponents(spaceId, targetId)
|
||||
}
|
||||
|
||||
override fun getComponent(
|
||||
spaceId: Int,
|
||||
targetId: Int,
|
||||
id: Int
|
||||
): Target.TargetComponent? {
|
||||
val userId = authService.getSecurityUserId()
|
||||
spaceRepo.findSpaceById(spaceId, userId)
|
||||
targetRepo.findBySpaceIdAndId(spaceId, targetId) ?: throw NotFoundException("Target $targetId not found")
|
||||
return targetRepo.getComponent(spaceId, targetId, id)
|
||||
}
|
||||
|
||||
override fun createComponent(
|
||||
spaceId: Int,
|
||||
targetId: Int,
|
||||
component: Target.TargetComponent
|
||||
): Int {
|
||||
val userId = authService.getSecurityUserId()
|
||||
spaceRepo.findSpaceById(spaceId, userId)
|
||||
targetRepo.findBySpaceIdAndId(spaceId, targetId) ?: throw NotFoundException("Target $targetId not found")
|
||||
return targetRepo.createComponent(targetId, component, userId)
|
||||
}
|
||||
|
||||
override fun updateComponent(
|
||||
spaceId: Int,
|
||||
targetId: Int,
|
||||
component: Target.TargetComponent
|
||||
) {
|
||||
val userId = authService.getSecurityUserId()
|
||||
spaceRepo.findSpaceById(spaceId, userId)
|
||||
targetRepo.findBySpaceIdAndId(spaceId, targetId) ?: throw NotFoundException("Target $targetId not found")
|
||||
val existingComponent = targetRepo.getComponent(spaceId, targetId, component.id!!)
|
||||
?: throw NotFoundException("Component $targetId not found")
|
||||
val updatedComponent = existingComponent.copy(
|
||||
name = component.name,
|
||||
amount = component.amount,
|
||||
isDone = component.isDone,
|
||||
date = component.date
|
||||
)
|
||||
targetRepo.updateComponent(targetId, updatedComponent.id!!, updatedComponent, userId)
|
||||
}
|
||||
|
||||
override fun deleteComponent(spaceId: Int, targetId: Int, id: Int) {
|
||||
val userId = authService.getSecurityUserId()
|
||||
spaceRepo.findSpaceById(spaceId, userId)
|
||||
targetRepo.findBySpaceIdAndId(spaceId, targetId) ?: throw NotFoundException("Target $targetId not found")
|
||||
targetRepo.getComponent(spaceId, targetId, id) ?: throw NotFoundException("Component $targetId not found")
|
||||
targetRepo.deleteComponent(targetId, id)
|
||||
}
|
||||
|
||||
override fun assignTransaction(spaceId: Int, targetId: Int, transactionId: Int) {
|
||||
val userId = authService.getSecurityUserId()
|
||||
spaceRepo.findSpaceById(spaceId, userId)
|
||||
targetRepo.findBySpaceIdAndId(spaceId, targetId) ?: throw NotFoundException("Target $targetId not found")
|
||||
transactionRepo.findBySpaceIdAndId(spaceId, transactionId) ?: throw NotFoundException(
|
||||
"Transaction $transactionId not found"
|
||||
)
|
||||
targetRepo.assignTransaction(targetId, transactionId)
|
||||
|
||||
}
|
||||
|
||||
override fun refuseTransaction(spaceId: Int, targetId: Int, transactionId: Int) {
|
||||
val userId = authService.getSecurityUserId()
|
||||
spaceRepo.findSpaceById(spaceId, userId)
|
||||
targetRepo.findBySpaceIdAndId(spaceId, targetId) ?: throw NotFoundException("Target $targetId not found")
|
||||
transactionRepo.findBySpaceIdAndId(spaceId, transactionId) ?: throw NotFoundException(
|
||||
"Transaction $transactionId not found"
|
||||
)
|
||||
targetRepo.refuseTransaction(targetId, transactionId)
|
||||
}
|
||||
}
|
||||
@@ -60,7 +60,7 @@ class CategorizeService(
|
||||
listOf(
|
||||
InlineKeyboardButton.WebApp(
|
||||
"Открыть в WebApp",
|
||||
WebAppInfo("https://app.luminic.space/transactions/${tx.id}/edit")
|
||||
WebAppInfo("https://app.luminic.space/transactions/${tx.id}/edit?mode=from_bot")
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -85,7 +85,7 @@ class CategorizeService(
|
||||
listOf(
|
||||
InlineKeyboardButton.WebApp(
|
||||
"Открыть в WebApp",
|
||||
WebAppInfo("https://app.luminic.space/transactions/${tx.id}/edit")
|
||||
WebAppInfo("https://app.luminic.space/transactions/${tx.id}/edit?mode=from_bot")
|
||||
)
|
||||
)
|
||||
),
|
||||
@@ -131,7 +131,7 @@ class CategorizeService(
|
||||
listOf(
|
||||
InlineKeyboardButton.WebApp(
|
||||
"Открыть в WebApp",
|
||||
WebAppInfo("https://app.luminic.space/transactions/${tx.id}/edit")
|
||||
WebAppInfo("https://app.luminic.space/transactions/${tx.id}/edit?mode=from_bot")
|
||||
)
|
||||
)
|
||||
),
|
||||
|
||||
@@ -119,7 +119,7 @@ class BotService(
|
||||
@Bean
|
||||
fun bot(): Bot {
|
||||
val bot = com.github.kotlintelegrambot.bot {
|
||||
logLevel = LogLevel.All()
|
||||
logLevel = LogLevel.None
|
||||
token = botToken
|
||||
dispatch {
|
||||
message(Filter.Text) {
|
||||
|
||||
59
src/main/resources/db/migration/V31__.sql
Normal file
59
src/main/resources/db/migration/V31__.sql
Normal file
@@ -0,0 +1,59 @@
|
||||
DROP table if exists finance.goals cascade;
|
||||
DROP table if exists finance.goals_components cascade;
|
||||
DROP table if exists finance.goals_transactions cascade;
|
||||
|
||||
DROP table if exists finance.targets cascade;
|
||||
DROP table if exists finance.targets_components cascade;
|
||||
DROP table if exists finance.targets_transactions cascade;
|
||||
|
||||
|
||||
CREATE TABLE finance.targets
|
||||
(
|
||||
id integer generated by default as identity not null,
|
||||
space_id INTEGER,
|
||||
type SMALLINT,
|
||||
name VARCHAR(255),
|
||||
description VARCHAR(255),
|
||||
amount DECIMAL,
|
||||
until_date date,
|
||||
created_by_id INTEGER,
|
||||
created_at TIMESTAMP WITHOUT TIME ZONE,
|
||||
updated_by_id INTEGER,
|
||||
updated_at TIMESTAMP WITHOUT TIME ZONE,
|
||||
CONSTRAINT pk_targets PRIMARY KEY (id)
|
||||
);
|
||||
|
||||
|
||||
ALTER TABLE finance.targets
|
||||
ADD CONSTRAINT FK_TARGETS_ON_CREATEDBY FOREIGN KEY (created_by_id) REFERENCES finance.users (id);
|
||||
|
||||
ALTER TABLE finance.targets
|
||||
ADD CONSTRAINT FK_TARGETS_ON_SPACE FOREIGN KEY (space_id) REFERENCES finance.spaces (id);
|
||||
|
||||
ALTER TABLE finance.targets
|
||||
ADD CONSTRAINT FK_TARGETS_ON_UPDATEDBY FOREIGN KEY (updated_by_id) REFERENCES finance.users (id);
|
||||
|
||||
CREATE TABLE finance.targets_transactions
|
||||
(
|
||||
target_id INTEGER NOT NULL,
|
||||
transactions_id INTEGER NOT NULL
|
||||
);
|
||||
ALTER TABLE finance.targets_transactions
|
||||
ADD CONSTRAINT fk_targettx_on_target FOREIGN KEY (target_id) REFERENCES finance.targets (id);
|
||||
|
||||
ALTER TABLE finance.targets_transactions
|
||||
ADD CONSTRAINT fk_targettx_on_tx FOREIGN KEY (transactions_id) REFERENCES finance.transactions (id);
|
||||
|
||||
create table if not exists finance.targets_components
|
||||
(
|
||||
id INTEGER GENERATED BY DEFAULT AS IDENTITY NOT NULL,
|
||||
target_id INTEGER NOT NULL,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
amount NUMERIC NOT NULL,
|
||||
is_done BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
date TIMESTAMP WITH TIME ZONE NULL
|
||||
);
|
||||
|
||||
alter table finance.targets_components
|
||||
add constraint fk_target_on_components foreign key (target_id) references finance.targets (id);
|
||||
|
||||
Reference in New Issue
Block a user