Add expense period total chart
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package de.financer.controller;
|
||||
|
||||
import de.financer.ResponseReason;
|
||||
import de.financer.dto.ExpensePeriodTotal;
|
||||
import de.financer.model.Transaction;
|
||||
import de.financer.service.TransactionService;
|
||||
import org.slf4j.Logger;
|
||||
@@ -10,9 +11,6 @@ import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.net.URLDecoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("transactions")
|
||||
public class TransactionController {
|
||||
@@ -94,4 +92,20 @@ public class TransactionController {
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
@RequestMapping("getExpensePeriodTotals")
|
||||
public Iterable<ExpensePeriodTotal> getExpensePeriodTotals(Integer monthPeriodStartDay, Integer year) {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug(String.format("/transactions/getExpensePeriodTotals got parameters: %s, %s", monthPeriodStartDay, year));
|
||||
}
|
||||
|
||||
final Iterable<ExpensePeriodTotal> expensePeriodTotals = this.transactionService
|
||||
.getExpensePeriodTotals(monthPeriodStartDay, year);
|
||||
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug(String.format("/transactions/getExpensePeriodTotals returns with %s", expensePeriodTotals));
|
||||
}
|
||||
|
||||
return expensePeriodTotals;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package de.financer.dba;
|
||||
|
||||
import de.financer.dto.ExpensePeriodTotal;
|
||||
import de.financer.model.Account;
|
||||
import de.financer.model.AccountType;
|
||||
import de.financer.model.Transaction;
|
||||
@@ -9,6 +10,7 @@ import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
|
||||
@Transactional(propagation = Propagation.REQUIRED)
|
||||
public interface TransactionRepository extends CrudRepository<Transaction, Long> {
|
||||
@@ -16,4 +18,11 @@ public interface TransactionRepository extends CrudRepository<Transaction, Long>
|
||||
|
||||
@Query("SELECT SUM(t.amount) FROM Transaction t JOIN t.toAccount a WHERE t.date BETWEEN :periodStart AND :periodEnd AND a.type IN :expenseTypes")
|
||||
Long getExpensesCurrentPeriod(LocalDate periodStart, LocalDate periodEnd, AccountType... expenseTypes);
|
||||
|
||||
// The HQL contains a hack because Hibernate can't resolve the alias of the CASE column in the GROUP BY clause
|
||||
// That's why the generated alias is used directly in the HQL. It will break if the columns in the SELECT clause get reordered
|
||||
// col_0_0_ instead of periodShortCode
|
||||
// col_2_0_ instead of AccType
|
||||
@Query("SELECT new de.financer.dto.ExpensePeriodTotal(CASE WHEN EXTRACT(DAY FROM t.date) >= :startDay THEN CONCAT(CAST(EXTRACT(YEAR FROM t.date) AS string), '/', CAST(EXTRACT(MONTH FROM t.date) AS string)) ELSE CASE WHEN EXTRACT(MONTH FROM t.date) = 1 THEN CONCAT(CAST(EXTRACT(YEAR FROM t.date) - 1 AS string), '/12') ELSE CONCAT(CAST(EXTRACT(YEAR FROM t.date) AS string), '/', CAST(EXTRACT(MONTH FROM t.date) - 1 AS string)) END END AS periodShortCode, SUM(t.amount), CASE WHEN fa.type = :incomeType THEN fa.type ELSE ta.type END AS AccType) FROM Transaction t JOIN t.toAccount ta JOIN t.fromAccount fa WHERE ((ta.type IN :expenseTypes AND fa.type <> :startType) OR (fa.type = :incomeType)) AND t.date BETWEEN :lowerBound AND :upperBound GROUP BY col_0_0_, col_2_0_ ORDER BY periodShortCode, AccType ASC")
|
||||
List<ExpensePeriodTotal> getAccountExpenseTotals(int startDay, LocalDate lowerBound, LocalDate upperBound, AccountType incomeType, AccountType startType, AccountType... expenseTypes);
|
||||
}
|
||||
@@ -1,8 +1,10 @@
|
||||
package de.financer.service;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
import de.financer.ResponseReason;
|
||||
import de.financer.config.FinancerConfig;
|
||||
import de.financer.dba.TransactionRepository;
|
||||
import de.financer.dto.ExpensePeriodTotal;
|
||||
import de.financer.model.Account;
|
||||
import de.financer.model.AccountType;
|
||||
import de.financer.model.RecurringTransaction;
|
||||
@@ -21,6 +23,7 @@ import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.DateTimeParseException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Service
|
||||
@@ -239,4 +242,17 @@ public class TransactionService {
|
||||
|
||||
return Optional.ofNullable(expensesCurrentPeriod).orElse(Long.valueOf(0l));
|
||||
}
|
||||
|
||||
public Iterable<ExpensePeriodTotal> getExpensePeriodTotals(Integer monthPeriodStartDay, Integer year) {
|
||||
final List<ExpensePeriod> expensePeriods = ExpensePeriod.generateExpensePeriodsForYear(monthPeriodStartDay, year);
|
||||
|
||||
final ExpensePeriod lowerBound = Iterables.get(expensePeriods, 0);
|
||||
final ExpensePeriod upperBound = Iterables.getLast(expensePeriods);
|
||||
|
||||
final List<ExpensePeriodTotal> expensePeriodTotals = this.transactionRepository
|
||||
.getAccountExpenseTotals(monthPeriodStartDay, lowerBound.getStart(), upperBound
|
||||
.getEnd(), AccountType.INCOME, AccountType.START, AccountType.EXPENSE, AccountType.LIABILITY);
|
||||
|
||||
return expensePeriodTotals;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user