diff --git a/financer-server/pom.xml b/financer-server/pom.xml index dff35ee..d6e4ab3 100644 --- a/financer-server/pom.xml +++ b/financer-server/pom.xml @@ -17,7 +17,7 @@ jar - hsqldb,dev + postgres,dev mk diff --git a/financer-server/src/main/java/de/financer/dba/TransactionRepository.java b/financer-server/src/main/java/de/financer/dba/TransactionRepository.java index 64371bd..e46644f 100644 --- a/financer-server/src/main/java/de/financer/dba/TransactionRepository.java +++ b/financer-server/src/main/java/de/financer/dba/TransactionRepository.java @@ -20,8 +20,8 @@ public interface TransactionRepository extends CrudRepository @Query("SELECT SUM(t.amount) FROM Transaction t JOIN t.periods p JOIN t.toAccount a WHERE a.type IN :expenseTypes AND p = :period") Long getExpensesForPeriod(Period period, AccountType... expenseTypes); - @Query("SELECT SUM(t.amount) FROM Transaction t JOIN t.periods p JOIN t.toAccount a WHERE a.type IN :expenseTypes GROUP BY p ORDER BY p.start ASC") - List getExpensesForAllPeriods(AccountType... expenseTypes); + @Query("SELECT SUM(t.amount) FROM Transaction t JOIN t.periods p JOIN t.toAccount a JOIN t.fromAccount f WHERE a.type IN :expenseTypes AND f.type != :startType GROUP BY p ORDER BY p.start ASC") + List getExpensesForAllPeriods(AccountType startType, 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 diff --git a/financer-server/src/main/java/de/financer/service/TransactionService.java b/financer-server/src/main/java/de/financer/service/TransactionService.java index 620ac90..8fcaf10 100644 --- a/financer-server/src/main/java/de/financer/service/TransactionService.java +++ b/financer-server/src/main/java/de/financer/service/TransactionService.java @@ -235,6 +235,13 @@ public class TransactionService { return response; } + /** + * This method calculates the expenses done in the current period; this is the sum of + * all bookings to {@link AccountType#EXPENSE EXPENSE} or {@link AccountType#LIABILITY LIABILITY} + * accounts. + * + * @return the sum of expenses - may be 0 + */ public Long getExpensesCurrentPeriod() { final Period expensePeriod = this.periodService.getCurrentExpensePeriod(); @@ -244,10 +251,25 @@ public class TransactionService { return Optional.ofNullable(expensesCurrentPeriod).orElse(Long.valueOf(0l)); } + /** + * This method gets all sums of expenses of all periods, ordered from oldest to newest. + * + * @return the sums of expenses - may be empty + * @see TransactionService#getExpensesCurrentPeriod() + */ public List getExpensesAllPeriods() { - return this.transactionRepository.getExpensesForAllPeriods(AccountType.EXPENSE, AccountType.LIABILITY); + return this.transactionRepository.getExpensesForAllPeriods(AccountType.START, AccountType.EXPENSE, AccountType.LIABILITY); } + /** + * This method gets the total values of all expense periods of the given year; that is + * the sum of all bookings for {@link AccountType#EXPENSE EXPENSE}, + * {@link AccountType#LIABILITY LIABILITY} and {@link AccountType#INCOME INCOME} accounts + * grouped by the account type and period. + * + * @param year the year to get the expense period totals for + * @return the expense period totals for the given year + */ public Iterable getExpensePeriodTotals(Integer year) { final Iterable periods = this.periodService.getAllExpensePeriodsForYear(year); diff --git a/financer-web-client/src/main/java/de/financer/chart/impl/expense/AbstractExpensesGenerator.java b/financer-web-client/src/main/java/de/financer/chart/impl/expense/AbstractExpensesGenerator.java index 893ff7f..e3ae1c0 100644 --- a/financer-web-client/src/main/java/de/financer/chart/impl/expense/AbstractExpensesGenerator.java +++ b/financer-web-client/src/main/java/de/financer/chart/impl/expense/AbstractExpensesGenerator.java @@ -1,7 +1,6 @@ package de.financer.chart.impl.expense; import de.financer.chart.AbstractChartGenerator; -import de.financer.chart.ChartDefinitions; import de.financer.config.FinancerConfig; import de.financer.util.ControllerUtils; import org.jfree.chart.ChartFactory; @@ -24,8 +23,6 @@ public abstract class AbstractExpensesGenerator extends AbstractChartGenerator v25: +- Add color column in account overview +- Fix a bug that caused the chart generation to crash +- Exclude START bookings from expense history + v23 -> v24: - Mark accounts that are overspend, meaning their spending in the current period is greater than the average spending of that account diff --git a/financer-web-client/src/main/resources/static/css/main.css b/financer-web-client/src/main/resources/static/css/main.css index 4b38df8..3965647 100644 --- a/financer-web-client/src/main/resources/static/css/main.css +++ b/financer-web-client/src/main/resources/static/css/main.css @@ -1,6 +1,13 @@ /* Variable declarations */ :root { --error-color: #D30000/*#ff6666*/; + --bank-color: #008FFB; + --cash-color: #FFCB00; + --income-color: #00A900; + --liability-color: #D36000; + --expense-color: #D30000; + --start-color: #AB005D; + --type-row-width: 5px; } /* --------------------- */ @@ -139,4 +146,45 @@ input[type=submit] { .errorMessage { color: var(--error-color); display: block; +} + +.bank-row { + background-color: var(--bank-color) !important; + width: var(--type-row-width); + padding: 0px !important +} + +.cash-row { + background-color: var(--cash-color) !important; + width: var(--type-row-width); + padding: 0px !important +} + +.income-row { + background-color: var(--income-color) !important; + width: var(--type-row-width); + padding: 0px !important +} + +.liability-row { + background-color: var(--liability-color) !important; + width: var(--type-row-width); + padding: 0px !important +} + +.expense-row { + background-color: var(--expense-color) !important; + width: var(--type-row-width); + padding: 0px !important +} + +.start-row { + background-color: var(--start-color) !important; + width: var(--type-row-width); + padding: 0px !important +} + +#type-row { + width: var(--type-row-width); + padding: 0px !important } \ No newline at end of file diff --git a/financer-web-client/src/main/resources/static/readme.txt b/financer-web-client/src/main/resources/static/readme.txt index e657b26..f109b6e 100644 --- a/financer-web-client/src/main/resources/static/readme.txt +++ b/financer-web-client/src/main/resources/static/readme.txt @@ -19,13 +19,40 @@ 1. About ======== - This is the manual for the financer application - a simple app to manage your personal finances. + This is the manual for the financer application - a simple app to support you in managing your personal finances. + + The main goal of the financer application is to keep things simple by not attempting to provide sophisticated + automation. Instead it is merely a tool that provides basic key values to support you. 2. Overview =========== 3. Architectural overview ========================= + The financer application currently consists of two components - a server and a client. They communicate via a JSON + REST API. The only available client is a web client that supports a boiled down view for mobile devices, though. + + Both client (-web-client) and server (-server) reside in dedicated Maven modules, with a common (-common) module + that holds common model classes and DTOs. Both components are layered: + + ____________ C + | Controller | L + |------------| I + | Chart | E + S ____________ |------------| N + E | Controller |<-------REST--------| Template | T + R |------------| '------------' + V | Service | + E |------------| + R | DBA | + '------------' + | + | + ,-------, + | DB | + '-------' + + Each component is contained in a distinct artifact. 4. Account types ================ @@ -115,6 +142,24 @@ 6. Account groups ================= + Account groups are a simple way to group account into topics. Imagine the following accounts: + - Rent + - Electricity + - Water + - Groceries + - Takeaway + - Coffee shop + - Cinema + - Netflix + + They could be grouped via the following three groups: + - Housing for Rent, Electricity and Water + - Food for Groceries, Takeaway and Coffee shop + - Entertainment for Cinema and Netflix + + This additional hierarchy level is actively used by reports to provide a better picture about where money is spent. + The financer application makes no hard guidelines on how to model your accounts and account groups, so you can model + them matching your needs. 7. Transactions =============== diff --git a/financer-web-client/src/main/resources/templates/account/accountOverview.html b/financer-web-client/src/main/resources/templates/account/accountOverview.html index f712038..093720e 100644 --- a/financer-web-client/src/main/resources/templates/account/accountOverview.html +++ b/financer-web-client/src/main/resources/templates/account/accountOverview.html @@ -66,6 +66,7 @@ + +
@@ -76,6 +77,12 @@
+ + + + +