Add account balance endpoint

This commit is contained in:
Billy Brawner 2019-06-01 14:46:04 -07:00
parent 81cb8cd680
commit 0bb80d1162
5 changed files with 27 additions and 9 deletions

View file

@ -3,7 +3,6 @@ package com.wbrawner.budgetserver.account
import com.wbrawner.budgetserver.category.Category
import com.wbrawner.budgetserver.transaction.Transaction
import com.wbrawner.budgetserver.user.User
import com.wbrawner.budgetserver.user.UserResponse
import java.util.*
import javax.persistence.*
@ -12,6 +11,7 @@ data class Account(
@Id @GeneratedValue(strategy = GenerationType.AUTO) val id: Long? = null,
val name: String = "",
val description: String? = null,
val currencyCode: String? = null,
@OneToMany(mappedBy = "account") val transactions: Set<Transaction> = TreeSet(),
@OneToMany(mappedBy = "account") val categories: Set<Category> = TreeSet(),
@ManyToMany val users: Set<User> = mutableSetOf(),
@ -25,3 +25,5 @@ data class UpdateAccountRequest(val name: String?, val description: String?, val
data class AccountResponse(val id: Long, val name: String, val description: String?, val users: List<Long>) {
constructor(account: Account) : this(account.id!!, account.name, account.description, account.users.map { it.id!! })
}
data class AccountBalanceResponse(val id: Long, val balance: Long)

View file

@ -1,6 +1,7 @@
package com.wbrawner.budgetserver.account
import com.wbrawner.budgetserver.getCurrentUser
import com.wbrawner.budgetserver.transaction.TransactionRepository
import com.wbrawner.budgetserver.user.UserRepository
import io.swagger.annotations.Api
import io.swagger.annotations.ApiOperation
@ -15,7 +16,11 @@ import javax.transaction.Transactional
@RestController
@RequestMapping("/accounts")
@Api(value = "Accounts", tags = ["Accounts"], authorizations = [Authorization("basic")])
class AccountController @Autowired constructor(private val accountRepository: AccountRepository, private val userRepository: UserRepository) {
class AccountController @Autowired constructor(
private val accountRepository: AccountRepository,
private val transactionRepository: TransactionRepository,
private val userRepository: UserRepository
) {
@Transactional
@GetMapping("", produces = [MediaType.APPLICATION_JSON_VALUE])
@ApiOperation(value = "getAccounts", nickname = "getAccounts", tags = ["Accounts"])
@ -36,6 +41,16 @@ class AccountController @Autowired constructor(private val accountRepository: Ac
ResponseEntity.ok(AccountResponse(it))
} ?: ResponseEntity.notFound().build()
@Transactional
@GetMapping("/{id}/balance", produces = [MediaType.APPLICATION_JSON_VALUE])
@ApiOperation(value = "getAccountBalance", nickname = "getAccountBalance", tags = ["Accounts"])
fun getAccountBalance(@PathVariable id: Long): ResponseEntity<AccountBalanceResponse> =
accountRepository.findByUsersContainsAndId(getCurrentUser()!!, id)
.orElse(null)
?.let {
ResponseEntity.ok(AccountBalanceResponse(it.id!!, transactionRepository.sumBalanceByAccount(it)))
} ?: ResponseEntity.notFound().build()
@PostMapping("/new", consumes = [MediaType.APPLICATION_JSON_VALUE], produces = [MediaType.APPLICATION_JSON_VALUE])
@ApiOperation(value = "newAccount", nickname = "newAccount", tags = ["Accounts"])
fun newAccount(@RequestBody request: NewAccountRequest): ResponseEntity<AccountResponse> {

View file

@ -11,7 +11,6 @@ import org.springframework.security.config.annotation.authentication.builders.Au
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity
import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration
import org.springframework.security.config.annotation.web.builders.HttpSecurity
import org.springframework.security.config.annotation.web.builders.WebSecurity
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
@ -52,10 +51,6 @@ constructor(
auth!!.authenticationProvider(authenticationProvider)
}
override fun configure(web: WebSecurity?) {
web?.ignoring()?.antMatchers("/v2/api-docs")
}
@Throws(Exception::class)
public override fun configure(http: HttpSecurity) {
http.authorizeRequests()

View file

@ -3,6 +3,7 @@ package com.wbrawner.budgetserver.transaction
import com.wbrawner.budgetserver.account.Account
import com.wbrawner.budgetserver.category.Category
import org.springframework.data.domain.Pageable
import org.springframework.data.jpa.repository.Query
import org.springframework.data.repository.PagingAndSortingRepository
import java.util.*
@ -10,4 +11,9 @@ interface TransactionRepository: PagingAndSortingRepository<Transaction, Long> {
fun findAllByAccount(account: Account, pageable: Pageable): List<Transaction>
fun findByAccountAndId(account: Account, id: Long): Optional<Transaction>
fun findAllByAccountAndCategory(account: Account, category: Category): List<Transaction>
@Query(
nativeQuery = true,
value = "SELECT (COALESCE((SELECT SUM(amount) from transaction WHERE is_expense = 0), 0)) - (COALESCE((SELECT SUM(amount) from transaction WHERE is_expense = 1), 0));"
)
fun sumBalanceByAccount(account: Account): Long
}

View file

@ -1,6 +1,6 @@
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:mysql://localhost:3306/budget
spring.datasource.username=budget
spring.datasource.password=budget
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.profiles.active=dev
spring.profiles.active=prod