Add colors, fix bugs
This commit is contained in:
@@ -17,7 +17,7 @@
|
||||
|
||||
<properties>
|
||||
<packaging.type>jar</packaging.type>
|
||||
<activeProfiles>hsqldb,dev</activeProfiles>
|
||||
<activeProfiles>postgres,dev</activeProfiles>
|
||||
<deploymentProfile>mk</deploymentProfile>
|
||||
</properties>
|
||||
|
||||
|
||||
@@ -20,8 +20,8 @@ public interface TransactionRepository extends CrudRepository<Transaction, Long>
|
||||
@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<Long> 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<Long> 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
|
||||
|
||||
@@ -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 <code>0</code>
|
||||
*/
|
||||
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<Long> 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<ExpensePeriodTotal> getExpensePeriodTotals(Integer year) {
|
||||
final Iterable<Period> periods = this.periodService.getAllExpensePeriodsForYear(year);
|
||||
|
||||
|
||||
@@ -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<E
|
||||
final JFreeChart chart = ChartFactory
|
||||
.createPieChart(this.getMessage(parameter.getTitle(), parameter.getArgsForTitle()), dataSet);
|
||||
|
||||
chart.getCategoryPlot().setBackgroundPaint(ChartDefinitions.TRANSPARENT);
|
||||
|
||||
final NumberFormat currencyInstance = NumberFormat.getCurrencyInstance(LocaleContextHolder.getLocale());
|
||||
currencyInstance.setCurrency(this.getFinancerConfig().getCurrency());
|
||||
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
v24 -> 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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
/* --------------------- */
|
||||
|
||||
@@ -140,3 +147,44 @@ input[type=submit] {
|
||||
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
|
||||
}
|
||||
@@ -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
|
||||
===============
|
||||
|
||||
@@ -66,6 +66,7 @@
|
||||
</div>
|
||||
<table id="account-overview-table">
|
||||
<tr>
|
||||
<th id="type-row" />
|
||||
<th class="hideable-column" th:text="#{financer.account-overview.table-header.id}"/>
|
||||
<th th:text="#{financer.account-overview.table-header.key}"/>
|
||||
<th th:text="#{financer.account-overview.table-header.balance}"/>
|
||||
@@ -76,6 +77,12 @@
|
||||
<th class="hideable-column" th:text="#{financer.account-overview.table-header.status}"/>
|
||||
</tr>
|
||||
<tr th:each="acc : ${accounts}">
|
||||
<th class="bank-row" th:if="${acc.type == T(de.financer.model.AccountType).BANK}" />
|
||||
<th class="cash-row" th:if="${acc.type == T(de.financer.model.AccountType).CASH}" />
|
||||
<th class="income-row" th:if="${acc.type == T(de.financer.model.AccountType).INCOME}" />
|
||||
<th class="liability-row" th:if="${acc.type == T(de.financer.model.AccountType).LIABILITY}" />
|
||||
<th class="expense-row" th:if="${acc.type == T(de.financer.model.AccountType).EXPENSE}" />
|
||||
<th class="start-row" th:if="${acc.type == T(de.financer.model.AccountType).START}" />
|
||||
<td class="hideable-column" th:text="${acc.id}"/>
|
||||
<td>
|
||||
<a th:href="@{/accountDetails(key=${acc.key})}" th:text="${acc.key}"/>
|
||||
|
||||
Reference in New Issue
Block a user