Various fixes to improve date range of retrieved transactions and balances

Signed-off-by: Billy Brawner <billy@wbrawner.com>
This commit is contained in:
Billy Brawner 2019-09-24 18:45:46 -07:00
parent c99ef28a2a
commit e8fd71d219
4 changed files with 34 additions and 10 deletions

View file

@ -2,8 +2,17 @@ package com.wbrawner.budgetserver
import com.wbrawner.budgetserver.user.User
import org.springframework.security.core.context.SecurityContextHolder
import java.util.*
fun getCurrentUser(): User? {
val user = SecurityContextHolder.getContext().authentication.principal
return if (user is User) user else null
}
fun GregorianCalendar.setToFirstOfMonth(): GregorianCalendar = this.apply {
set(Calendar.MILLISECOND, 0)
set(Calendar.SECOND, 0)
set(Calendar.MINUTE, 0)
set(Calendar.HOUR_OF_DAY, 0)
set(Calendar.DATE, 1)
}

View file

@ -3,6 +3,7 @@ package com.wbrawner.budgetserver.category
import com.wbrawner.budgetserver.ErrorResponse
import com.wbrawner.budgetserver.budget.BudgetRepository
import com.wbrawner.budgetserver.getCurrentUser
import com.wbrawner.budgetserver.setToFirstOfMonth
import com.wbrawner.budgetserver.transaction.TransactionRepository
import io.swagger.annotations.Api
import io.swagger.annotations.ApiOperation
@ -14,6 +15,7 @@ import org.springframework.http.MediaType
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*
import java.lang.Integer.min
import java.util.*
import javax.transaction.Transactional
@RestController
@ -52,7 +54,8 @@ class CategoryController @Autowired constructor(
val category = categoryRepository.findById(id).orElse(null) ?: return ResponseEntity.notFound().build()
budgetRepository.findByUsersContainsAndCategoriesContains(getCurrentUser()!!, category).orElse(null)
?: return ResponseEntity.notFound().build()
return ResponseEntity.ok(CategoryBalanceResponse(category.id!!, transactionRepository.sumBalanceByCategoryId(category.id)))
val transactions = transactionRepository.sumBalanceByCategoryId(category.id!!)
return ResponseEntity.ok(CategoryBalanceResponse(category.id, transactions))
}
@Transactional

View file

@ -5,6 +5,7 @@ import com.wbrawner.budgetserver.budget.BudgetRepository
import com.wbrawner.budgetserver.category.Category
import com.wbrawner.budgetserver.category.CategoryRepository
import com.wbrawner.budgetserver.getCurrentUser
import com.wbrawner.budgetserver.setToFirstOfMonth
import io.swagger.annotations.Api
import io.swagger.annotations.ApiOperation
import io.swagger.annotations.Authorization
@ -16,6 +17,7 @@ import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*
import java.lang.Integer.min
import java.time.Instant
import java.util.*
import javax.transaction.Transactional
@RestController
@ -30,8 +32,10 @@ class TransactionController @Autowired constructor(
@GetMapping("", produces = [MediaType.APPLICATION_JSON_VALUE])
@ApiOperation(value = "getTransactions", nickname = "getTransactions", tags = ["Transactions"])
fun getTransactions(
@RequestParam categoryIds: Array<Long>? = null,
@RequestParam budgetIds: Array<Long>? = null,
@RequestParam("categoryId") categoryIds: Array<Long>? = null,
@RequestParam("budgetId") budgetIds: Array<Long>? = null,
@RequestParam("from") from: Date? = null,
@RequestParam("to") to: Date? = null,
@RequestParam count: Int?,
@RequestParam page: Int?
): ResponseEntity<List<TransactionResponse>> {
@ -46,7 +50,12 @@ class TransactionController @Autowired constructor(
categoryRepository.findAllByBudgetIn(budgets)
}
val pageRequest = PageRequest.of(min(0, page?.minus(1)?: 0), count?: 1000)
return ResponseEntity.ok(transactionRepository.findAllByBudgetInAndCategoryIn(budgets, categories, pageRequest).map { TransactionResponse(it) })
return ResponseEntity.ok(transactionRepository.findAllByBudgetInAndCategoryInAndDateGreaterThan(
budgets,
categories,
GregorianCalendar().setToFirstOfMonth().toInstant(),
pageRequest
).map { TransactionResponse(it) })
}
@GetMapping("/{id}", produces = [MediaType.APPLICATION_JSON_VALUE])

View file

@ -2,28 +2,31 @@ package com.wbrawner.budgetserver.transaction
import com.wbrawner.budgetserver.budget.Budget
import com.wbrawner.budgetserver.category.Category
import com.wbrawner.budgetserver.setToFirstOfMonth
import org.springframework.data.domain.Pageable
import org.springframework.data.jpa.repository.Query
import org.springframework.data.repository.PagingAndSortingRepository
import java.time.Instant
import java.util.*
interface TransactionRepository: PagingAndSortingRepository<Transaction, Long> {
fun findAllByBudget(budget: Budget, pageable: Pageable): List<Transaction>
fun findAllByBudgetIn(budgets: List<Budget>, pageable: Pageable): List<Transaction>
fun findAllByBudgetInAndDateGreaterThan(budgets: List<Budget>, start: Date, pageable: Pageable): List<Transaction>
fun findAllByBudgetInAndCategoryInAndDateGreaterThan(budgets: List<Budget>, categories: List<Category>, start: Instant, pageable: Pageable? = null): List<Transaction>
fun findAllByBudgetInAndDateGreaterThanAndDateLessThan(budgets: List<Budget>, start: Date, end: Date, pageable: Pageable): List<Transaction>
fun findByBudgetAndId(budget: Budget, id: Long): Optional<Transaction>
fun findAllByBudgetAndCategory(budget: Budget, category: Category): List<Transaction>
fun findAllByBudgetInAndCategoryIn(budgets: List<Budget>, categories: List<Category>, pageable: Pageable? = null): List<Transaction>
fun findAllByBudgetInAndCategoryIn(budgets: List<Budget>, categories: List<Category>, pageable: Pageable? = null) =
findAllByBudgetInAndCategoryInAndDateGreaterThan(budgets, categories, GregorianCalendar().setToFirstOfMonth().toInstant(), pageable)
@Query(
nativeQuery = true,
value = "SELECT (COALESCE((SELECT SUM(amount) from transaction WHERE Budget_id = :BudgetId AND expense = 0), 0)) - (COALESCE((SELECT SUM(amount) from transaction WHERE Budget_id = :BudgetId AND expense = 1), 0));"
value = "SELECT (COALESCE((SELECT SUM(amount) from transaction WHERE Budget_id = :BudgetId AND expense = 0 AND date > :start), 0)) - (COALESCE((SELECT SUM(amount) from transaction WHERE Budget_id = :BudgetId AND expense = 1 AND date > :date), 0));"
)
fun sumBalanceByBudgetId(BudgetId: Long): Long
fun sumBalanceByBudgetId(BudgetId: Long, start: Date = GregorianCalendar().setToFirstOfMonth().time): Long
@Query(
nativeQuery = true,
value = "SELECT (COALESCE((SELECT SUM(amount) from transaction WHERE category_id = :categoryId AND expense = 0), 0)) - (COALESCE((SELECT SUM(amount) from transaction WHERE category_id = :categoryId AND expense = 1), 0));"
value = "SELECT (COALESCE((SELECT SUM(amount) from transaction WHERE category_id = :categoryId AND expense = 0 AND date > :start), 0)) - (COALESCE((SELECT SUM(amount) from transaction WHERE category_id = :categoryId AND expense = 1 AND date > :start), 0));"
)
fun sumBalanceByCategoryId(categoryId: Long): Long
fun sumBalanceByCategoryId(categoryId: Long, start: Date = GregorianCalendar().setToFirstOfMonth().time): Long
}