#18 Period overview: improvements
This commit is contained in:
@@ -23,7 +23,7 @@ orderByExpression
|
||||
regularExpression
|
||||
: (stringExpression | intExpression | booleanExpression | dateExpression) ;
|
||||
stringExpression
|
||||
: field=IDENTIFIER operator=STRING_OPERATOR value=STRING_VALUE ;
|
||||
: field=IDENTIFIER operator=STRING_OPERATOR value=(STRING_VALUE | ACCOUNT_TYPE_VALUE) ;
|
||||
intExpression
|
||||
: field=IDENTIFIER operator=(INT_OPERATOR | STRING_OPERATOR) value=INT_VALUE ;
|
||||
|
||||
@@ -96,34 +96,34 @@ fragment K : ('K' | 'k') ;
|
||||
fragment SPACE : ' ' ;
|
||||
|
||||
// Keywords
|
||||
BETWEEN : B E T W E E N ;
|
||||
AND : A N D ;
|
||||
OR : O R ;
|
||||
ORDER_BY : O R D E R SPACE B Y ;
|
||||
DESC : D E S C ;
|
||||
ASC : A S C ;
|
||||
TRUE : T R U E ;
|
||||
FALSE : F A L S E ;
|
||||
LIKE : L I K E ;
|
||||
IN : I N ;
|
||||
COMMA : ',' ;
|
||||
BETWEEN : B E T W E E N ;
|
||||
AND : A N D ;
|
||||
OR : O R ;
|
||||
ORDER_BY : O R D E R SPACE B Y ;
|
||||
DESC : D E S C ;
|
||||
ASC : A S C ;
|
||||
TRUE : T R U E ;
|
||||
FALSE : F A L S E ;
|
||||
LIKE : L I K E ;
|
||||
IN : I N ;
|
||||
COMMA : ',' ;
|
||||
|
||||
// Constant values
|
||||
CURRENT : C U R R E N T ;
|
||||
LAST : L A S T ;
|
||||
YEAR : Y E A R ;
|
||||
GRAND_TOTAL : G R A N D '_' T O T A L ;
|
||||
CURRENT_YEAR : CURRENT '_' YEAR ;
|
||||
LAST_YEAR : LAST '_' YEAR ;
|
||||
CURRENT : C U R R E N T ;
|
||||
LAST : L A S T ;
|
||||
YEAR : Y E A R ;
|
||||
GRAND_TOTAL : G R A N D '_' T O T A L ;
|
||||
CURRENT_YEAR : CURRENT '_' YEAR ;
|
||||
LAST_YEAR : LAST '_' YEAR ;
|
||||
|
||||
STRING_OPERATOR : '=' ;
|
||||
INT_OPERATOR : '>' | '<' | '>=' | '<=' | '!=' ;
|
||||
L_PAREN : '(' ;
|
||||
R_PAREN : ')' ;
|
||||
IDENTIFIER : [a-zA-Z]+ ;
|
||||
INT_VALUE : [0-9]+ ;
|
||||
STRING_VALUE : '\'' [a-zA-Z0-9\-/.&%@$ ]+ '\'' ;
|
||||
DATE_VALUE : [0-9][0-9][0-9][0-9][-][0-9][0-9][-][0-9][0-9] ; // ANTLR does not support regex quantifiers
|
||||
STRING_OPERATOR : '=' ;
|
||||
INT_OPERATOR : '>' | '<' | '>=' | '<=' | '!=' ;
|
||||
L_PAREN : '(' ;
|
||||
R_PAREN : ')' ;
|
||||
IDENTIFIER : [a-zA-Z]+ ;
|
||||
INT_VALUE : [0-9]+ ;
|
||||
STRING_VALUE : '\'' [a-zA-Z0-9\-/.&%@$ ]+ '\'' ;
|
||||
DATE_VALUE : [0-9][0-9][0-9][0-9][-][0-9][0-9][-][0-9][0-9] ; // ANTLR does not support regex quantifiers
|
||||
|
||||
NEWLINE : ('\r'? '\n' | '\r')+ ;
|
||||
WHITESPACE : ' ' -> skip;
|
||||
NEWLINE : ('\r'? '\n' | '\r')+ ;
|
||||
WHITESPACE : ' ' -> skip;
|
||||
@@ -7,24 +7,38 @@ import de.financer.model.*;
|
||||
import java.util.Arrays;
|
||||
|
||||
public enum FieldMapping {
|
||||
AMOUNT("amount", Transaction_.AMOUNT, Transaction.class, NoopJoinHandler.class, JoinKey
|
||||
.of(Transaction.class), null, IntHandler.class),
|
||||
AMOUNT("amount", Transaction_.AMOUNT, Transaction.class, NoopJoinHandler.class,
|
||||
JoinKey.of(Transaction.class), null, IntHandler.class),
|
||||
|
||||
PERIOD("period", Period_.ID, Period.class, PeriodJoinHandler.class, JoinKey.of(Period.class), null, PeriodConstHandler.class),
|
||||
PERIOD("period", Period_.ID, Period.class, PeriodJoinHandler.class,
|
||||
JoinKey.of(Period.class), null, PeriodConstHandler.class),
|
||||
|
||||
FROM_ACCOUNT("fromAccount", Account_.KEY, Account.class, FromAccountJoinHandler.class, JoinKey
|
||||
.of(Account.class, "FROM"), null, StringHandler.class),
|
||||
/**
|
||||
* ONLY FOR INTERNAL USAGE - NOT EXPOSED TO USER
|
||||
*/
|
||||
PERIOD_ID("periodId", Period_.ID, Period.class, PeriodJoinHandler.class,
|
||||
JoinKey.of(Period.class), null, PeriodIdHandler.class),
|
||||
|
||||
TO_ACCOUNT("toAccount", Account_.KEY, Account.class, ToAccountJoinHandler.class, JoinKey
|
||||
.of(Account.class, "TO"), null, StringHandler.class),
|
||||
FROM_ACCOUNT("fromAccount", Account_.KEY, Account.class, FromAccountJoinHandler.class,
|
||||
JoinKey.of(Account.class, "FROM"), null, StringHandler.class),
|
||||
|
||||
FROM_ACCOUNT_GROUP("fromAccountGroup", AccountGroup_.NAME, AccountGroup.class,
|
||||
AccountGroupJoinHandler.class, JoinKey.of(AccountGroup.class, "FROM"), FROM_ACCOUNT, StringHandler.class),
|
||||
TO_ACCOUNT("toAccount", Account_.KEY, Account.class, ToAccountJoinHandler.class,
|
||||
JoinKey.of(Account.class, "TO"), null, StringHandler.class),
|
||||
|
||||
TO_ACCOUNT_GROUP("toAccountGroup", AccountGroup_.NAME, AccountGroup.class,
|
||||
AccountGroupJoinHandler.class, JoinKey.of(AccountGroup.class, "TO"), TO_ACCOUNT, StringHandler.class),
|
||||
FROM_ACCOUNT_GROUP("fromAccountGroup", AccountGroup_.NAME, AccountGroup.class, AccountGroupJoinHandler.class,
|
||||
JoinKey.of(AccountGroup.class, "FROM"), FROM_ACCOUNT, StringHandler.class),
|
||||
|
||||
DATE("date", Transaction_.DATE, Transaction.class, NoopJoinHandler.class, JoinKey.of(Transaction.class), null, DateHandler.class),
|
||||
TO_ACCOUNT_GROUP("toAccountGroup", AccountGroup_.NAME, AccountGroup.class, AccountGroupJoinHandler.class,
|
||||
JoinKey.of(AccountGroup.class, "TO"), TO_ACCOUNT, StringHandler.class),
|
||||
|
||||
FROM_ACCOUNT_TYPE("fromAccountType", Account_.TYPE, Account.class, FromAccountJoinHandler.class,
|
||||
JoinKey.of(Account.class, "FROM"), null, AccountTypeHandler.class),
|
||||
|
||||
TO_ACCOUNT_TYPE("toAccountType", Account_.TYPE, Account.class, ToAccountJoinHandler.class,
|
||||
JoinKey.of(Account.class, "TO"), null, AccountTypeHandler.class),
|
||||
|
||||
DATE("date", Transaction_.DATE, Transaction.class, NoopJoinHandler.class,
|
||||
JoinKey.of(Transaction.class), null, DateHandler.class),
|
||||
|
||||
RECURRING("recurring", Transaction_.RECURRING_TRANSACTION, Transaction.class, NoopJoinHandler.class,
|
||||
JoinKey.of(Transaction.class), null, NotNullSyntheticHandler.class),
|
||||
@@ -32,10 +46,11 @@ public enum FieldMapping {
|
||||
TAX_RELEVANT("taxRelevant", Transaction_.TAX_RELEVANT, Transaction.class, NoopJoinHandler.class,
|
||||
JoinKey.of(Transaction.class), null, BooleanHandler.class),
|
||||
|
||||
HAS_FILE("hasFile", File_.ID, File.class, FileJoinHandler.class, JoinKey.of(File.class), null, NotNullSyntheticHandler.class),
|
||||
HAS_FILE("hasFile", File_.ID, File.class, FileJoinHandler.class,
|
||||
JoinKey.of(File.class), null, NotNullSyntheticHandler.class),
|
||||
|
||||
DESCRIPTION("description", Transaction_.DESCRIPTION, Transaction.class, NoopJoinHandler.class, JoinKey.of(Transaction.class),
|
||||
null, StringHandler.class);
|
||||
DESCRIPTION("description", Transaction_.DESCRIPTION, Transaction.class, NoopJoinHandler.class,
|
||||
JoinKey.of(Transaction.class), null, StringHandler.class);
|
||||
|
||||
private final String fieldName;
|
||||
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
package de.financer.fql.field_handler;
|
||||
|
||||
import de.financer.fql.FQLException;
|
||||
import de.financer.fql.FieldMapping;
|
||||
import de.financer.fql.join_handler.JoinKey;
|
||||
import de.financer.model.AccountType;
|
||||
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.From;
|
||||
import javax.persistence.criteria.Predicate;
|
||||
import java.util.Map;
|
||||
|
||||
public class AccountTypeHandler implements FieldHandler<String> {
|
||||
@Override
|
||||
public Predicate apply(FieldMapping fieldMapping, Map<JoinKey, From<?, ?>> froms, CriteriaBuilder criteriaBuilder, String value) {
|
||||
return criteriaBuilder
|
||||
.equal(froms.get(fieldMapping.getJoinKey()).get(fieldMapping.getAttributeName()), toAccountType(FieldHandlerUtils.removeQuotes(value)));
|
||||
}
|
||||
|
||||
private static AccountType toAccountType(String value) {
|
||||
if (value == null) {
|
||||
throw new FQLException("NULL cannot be solved to AccountType!");
|
||||
}
|
||||
|
||||
try {
|
||||
return AccountType.valueOf(value.toUpperCase());
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
throw new FQLException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package de.financer.fql.field_handler;
|
||||
|
||||
import de.financer.fql.FQLException;
|
||||
import de.financer.fql.FieldMapping;
|
||||
import de.financer.fql.join_handler.JoinKey;
|
||||
import org.apache.commons.lang3.math.NumberUtils;
|
||||
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.From;
|
||||
import javax.persistence.criteria.Predicate;
|
||||
import java.util.Map;
|
||||
|
||||
public class PeriodIdHandler implements FieldHandler<String> {
|
||||
@Override
|
||||
public Predicate apply(FieldMapping fieldMapping, Map<JoinKey, From<?, ?>> froms, CriteriaBuilder criteriaBuilder, String value) {
|
||||
final String unquotedValue = FieldHandlerUtils.removeQuotes(value);
|
||||
|
||||
if (!NumberUtils.isCreatable(unquotedValue)) {
|
||||
throw new FQLException(String.format("Invalid value %s for field periodId - only numbers allowed!", unquotedValue));
|
||||
}
|
||||
|
||||
return criteriaBuilder.equal(froms.get(fieldMapping.getJoinKey()).get(fieldMapping.getAttributeName()), NumberUtils.toLong(unquotedValue));
|
||||
}
|
||||
}
|
||||
@@ -58,31 +58,72 @@ public class PeriodController {
|
||||
return "period/periodOverview";
|
||||
}
|
||||
|
||||
@GetMapping("/showTransactions")
|
||||
public String showTransactions(Model model, Long periodId) {
|
||||
private String showInternal(Model model, Long periodId, String fql, boolean showSum) {
|
||||
final SearchTransactionsForm form = new SearchTransactionsForm();
|
||||
|
||||
form.setFql(fql);
|
||||
|
||||
try {
|
||||
final Iterable<SearchTransactionsResponseDto> response =
|
||||
new SearchTransactionsTemplate()
|
||||
.exchangeGet(financerConfig, null, null, periodId, null,
|
||||
Order.TRANSACTIONS_BY_DATE_DESC, null, false);
|
||||
final UriComponentsBuilder transactionBuilder = UriComponentsBuilder
|
||||
.fromHttpUrl(ControllerUtils.buildUrl(this.financerConfig, Function.TR_SEARCH_BY_FQL));
|
||||
|
||||
final List<SearchTransactionsResponseDto> transactions = IterableUtils.toList(response);
|
||||
transactionBuilder.queryParam("fql", form.getFql());
|
||||
|
||||
final Iterable<SearchTransactionsResponseDto> trxs = FinancerRestTemplate.exchangeGet(transactionBuilder,
|
||||
new ParameterizedTypeReference<Iterable<SearchTransactionsResponseDto>>() {
|
||||
});
|
||||
|
||||
model.addAttribute("transactions", transactions);
|
||||
model.addAttribute("transactionCount", IterableUtils.size(transactions));
|
||||
}
|
||||
catch(FinancerRestException e) {
|
||||
model.addAttribute("transactions", trxs);
|
||||
model.addAttribute("transactionCount", IterableUtils.size(trxs));
|
||||
|
||||
if (showSum) {
|
||||
Long trxSum = IterableUtils.toList(trxs).stream().mapToLong(t -> t.getAmount()).sum();
|
||||
|
||||
model.addAttribute("transactionSum", trxSum);
|
||||
}
|
||||
} catch (FinancerRestException e) {
|
||||
model.addAttribute("errorMessage", e.getResponseReason().name());
|
||||
model.addAttribute("transactionCount", 0);
|
||||
}
|
||||
|
||||
model.addAttribute("form", new SearchTransactionsForm());
|
||||
model.addAttribute("showSum", false);
|
||||
model.addAttribute("form", form);
|
||||
model.addAttribute("showSum", showSum);
|
||||
model.addAttribute("returnTo", "/periodOverview");
|
||||
ControllerUtils.addVersionAttribute(model, this.financerConfig);
|
||||
ControllerUtils.addCurrencySymbol(model, this.financerConfig);
|
||||
ControllerUtils.addDarkMode(model, this.financerConfig);
|
||||
|
||||
return "transaction/searchTransactions";
|
||||
}
|
||||
|
||||
@GetMapping("/showAllTransactions")
|
||||
public String showAllTransactions(Model model, Long periodId) {
|
||||
final String fql = String.format("periodId = '%s' ORDER BY date DESC", periodId);
|
||||
|
||||
return showInternal(model, periodId, fql, false);
|
||||
}
|
||||
|
||||
@GetMapping("/showIncomeTransactions")
|
||||
public String showIncomeTransactions(Model model, Long periodId) {
|
||||
final String fql = String
|
||||
.format("periodId = '%s' AND (fromAccountType = 'INCOME' OR (fromAccountType = 'LIABILITY' AND (toAccountType = 'BANK' OR toAccountType = 'CASH')) OR (fromAccountType = 'START' AND (toAccountType = 'BANK' OR toAccountType = 'CASH'))) ORDER BY date DESC", periodId);
|
||||
|
||||
return showInternal(model, periodId, fql, true);
|
||||
}
|
||||
|
||||
@GetMapping("/showExpenseTransactions")
|
||||
public String showExpenseTransactions(Model model, Long periodId) {
|
||||
final String fql = String
|
||||
.format("periodId = '%s' AND (fromAccountType = 'BANK' OR fromAccountType = 'CASH') AND toAccountType = 'EXPENSE' ORDER BY date DESC", periodId);
|
||||
|
||||
return showInternal(model, periodId, fql, true);
|
||||
}
|
||||
|
||||
@GetMapping("/showLiabilityTransactions")
|
||||
public String showLiabilityTransactions(Model model, Long periodId) {
|
||||
final String fql = String
|
||||
.format("periodId = '%s' AND (fromAccountType = 'BANK' OR fromAccountType = 'CASH') AND toAccountType = 'LIABILITY' ORDER BY date DESC", periodId);
|
||||
|
||||
return showInternal(model, periodId, fql, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,6 +138,8 @@ financer.search-transactions.show-query-options.fromAccount=fromAccount\: the ke
|
||||
financer.search-transactions.show-query-options.toAccount=toAccount\: the key of the to account
|
||||
financer.search-transactions.show-query-options.fromAccountGroup=fromAccountGroup\: the name of the account group of the from account
|
||||
financer.search-transactions.show-query-options.toAccountGroup=toAccountGroup\: the name of the account group of the to account
|
||||
financer.search-transactions.show-query-options.fromAccountType=fromAccountType\: the type of the from account
|
||||
financer.search-transactions.show-query-options.toAccountType=toAccountType\: the type of the to account
|
||||
financer.search-transactions.show-query-options.date=date\: the date of the transaction in the format yyyy-mm-dd
|
||||
financer.search-transactions.show-query-options.recurring=recurring\: whether the transaction has been created from a recurring transaction
|
||||
financer.search-transactions.show-query-options.taxRelevant=taxRelevant\: whether the transaction is relevant for tax declaration
|
||||
@@ -185,7 +187,11 @@ financer.period-overview.table-header.total=Total
|
||||
financer.period-overview.table-header.assets=Assets
|
||||
financer.period-overview.table-header.transactions=Transaction count
|
||||
financer.period-overview.table-header.actions=Actions
|
||||
financer.period-overview.table.actions.showTransactions=Show transactions
|
||||
financer.period-overview.table.actions.showAllTransactions=All transactions
|
||||
financer.period-overview.table.actions.showIncomeTransactions=Income transactions
|
||||
financer.period-overview.table.actions.showExpenseTransactions=Expense transactions
|
||||
financer.period-overview.table.actions.showLiabilityTransactions=Liability transactions
|
||||
financer.period-overview.show-actions=Show...
|
||||
|
||||
financer.interval-type.DAILY=Daily
|
||||
financer.interval-type.WEEKLY=Weekly
|
||||
|
||||
@@ -138,6 +138,8 @@ financer.search-transactions.show-query-options.fromAccount=fromAccount\: der Sc
|
||||
financer.search-transactions.show-query-options.toAccount=toAccount\: der Schl\u00FCssel des An Kontos
|
||||
financer.search-transactions.show-query-options.fromAccountGroup=fromAccountGroup\: der Name der Kontogruppe des Von Kontos
|
||||
financer.search-transactions.show-query-options.toAccountGroup=toAccountGroup\: der Name der Kontogruppe des An Kontos
|
||||
financer.search-transactions.show-query-options.fromAccountType=fromAccountType\: der Typ des Von Kontos
|
||||
financer.search-transactions.show-query-options.toAccountType=toAccountType\: der Typ des An Kontos
|
||||
financer.search-transactions.show-query-options.date=date\: das Datum der Buchung im Format jjjj-mm-tt
|
||||
financer.search-transactions.show-query-options.recurring=recurring\: ob die Buchung durch eine wiederkehrende Buchung erzeugt wurde
|
||||
financer.search-transactions.show-query-options.taxRelevant=taxRelevant\: ob die Buchung als steuerrelevant markiert wurde
|
||||
@@ -185,7 +187,11 @@ financer.period-overview.table-header.total=Insgesamt
|
||||
financer.period-overview.table-header.assets=Umlaufverm\u00F6gen
|
||||
financer.period-overview.table-header.transactions=Anzahl Buchungen
|
||||
financer.period-overview.table-header.actions=Aktionen
|
||||
financer.period-overview.table.actions.showTransactions=Zeige Buchungen
|
||||
financer.period-overview.table.actions.showAllTransactions=Alle Buchungen
|
||||
financer.period-overview.table.actions.showIncomeTransactions=Einkommenbuchungen
|
||||
financer.period-overview.table.actions.showExpenseTransactions=Ausgabebuchungen
|
||||
financer.period-overview.table.actions.showLiabilityTransactions=Verbindlichkeitenbuchungen
|
||||
financer.period-overview.show-actions=Anzeigen...
|
||||
|
||||
financer.interval-type.DAILY=T\u00E4glich
|
||||
financer.interval-type.WEEKLY=W\u00F6chentlich
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
v45 -> v46:
|
||||
- #17 Add actions to the period overview
|
||||
- #18 Improve actions in the period overview
|
||||
- Introduce new FQL fields toAccountType and fromAccountType
|
||||
|
||||
v44 -> v45:
|
||||
- #5 Having no periods breaks the "expenses per period" graph on the account overview page
|
||||
|
||||
@@ -46,6 +46,14 @@
|
||||
color: var(--neutral-color);
|
||||
}
|
||||
|
||||
.expense-period-period-overview {
|
||||
padding-left: 1em;
|
||||
}
|
||||
|
||||
.expense-year-period-period-overview {
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
#period-overview-asset-container {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<body>
|
||||
<h1 th:text="#{financer.heading.period-overview}"/>
|
||||
<span class="errorMessage" th:if="${errorMessage != null}" th:text="#{'financer.error-message.' + ${errorMessage}}"/>
|
||||
<a th:href="@{/accountOverview}" th:text="#{financer.cancel-back-to-overview}"/>
|
||||
<a th:href="@{/accountOverview}" th:text="#{financer.back-to-overview}"/>
|
||||
<table id="period-overview-table">
|
||||
<tr>
|
||||
<th th:text="#{financer.period-overview.table-header.id}"/>
|
||||
@@ -28,30 +28,62 @@
|
||||
<th th:text="#{financer.period-overview.table-header.actions}"/>
|
||||
</tr>
|
||||
<tr th:each="periodOverview : ${periodOverviews}">
|
||||
<td th:text="${periodOverview.periodId}"/>
|
||||
<td th:text="#{'financer.period-type.' + ${periodOverview.periodType}}"/>
|
||||
<td th:text="${#temporals.format(periodOverview.periodStart)}"/>
|
||||
<td th:text="${#temporals.format(periodOverview.periodEnd)}"/>
|
||||
<td th:utext="${#numbers.formatDecimal(periodOverview.incomeSum/100D, 1, 'DEFAULT', 2, 'DEFAULT') + currencySymbol}"/>
|
||||
<td th:utext="${#numbers.formatDecimal(periodOverview.expenseSum/100D, 1, 'DEFAULT', 2, 'DEFAULT') + currencySymbol}"/>
|
||||
<td th:utext="${#numbers.formatDecimal(periodOverview.liabilitySum/100D, 1, 'DEFAULT', 2, 'DEFAULT') + currencySymbol}"/>
|
||||
<td th:text="${periodOverview.periodId}"
|
||||
th:classappend="${periodOverview.periodType == T(de.financer.model.PeriodType).EXPENSE_YEAR} ? expense-year-period-period-overview"/>
|
||||
<td>
|
||||
<div>
|
||||
<span th:text="#{'financer.period-type.' + ${periodOverview.periodType}}"
|
||||
th:classappend="${(periodOverview.periodType == T(de.financer.model.PeriodType).EXPENSE ? 'expense-period-period-overview' : '') +
|
||||
(periodOverview.periodType == T(de.financer.model.PeriodType).EXPENSE_YEAR ? 'expense-year-period-period-overview' : '')}"/>
|
||||
</div>
|
||||
</td>
|
||||
<td th:text="${#temporals.format(periodOverview.periodStart)}"
|
||||
th:classappend="${periodOverview.periodType == T(de.financer.model.PeriodType).EXPENSE_YEAR} ? expense-year-period-period-overview"/>
|
||||
<td th:text="${#temporals.format(periodOverview.periodEnd)}"
|
||||
th:classappend="${periodOverview.periodType == T(de.financer.model.PeriodType).EXPENSE_YEAR} ? expense-year-period-period-overview"/>
|
||||
<td th:utext="${#numbers.formatDecimal(periodOverview.incomeSum/100D, 1, 'DEFAULT', 2, 'DEFAULT') + currencySymbol}"
|
||||
th:classappend="${periodOverview.periodType == T(de.financer.model.PeriodType).EXPENSE_YEAR} ? expense-year-period-period-overview"/>
|
||||
<td th:utext="${#numbers.formatDecimal(periodOverview.expenseSum/100D, 1, 'DEFAULT', 2, 'DEFAULT') + currencySymbol}"
|
||||
th:classappend="${periodOverview.periodType == T(de.financer.model.PeriodType).EXPENSE_YEAR} ? expense-year-period-period-overview"/>
|
||||
<td th:utext="${#numbers.formatDecimal(periodOverview.liabilitySum/100D, 1, 'DEFAULT', 2, 'DEFAULT') + currencySymbol}"
|
||||
th:classappend="${periodOverview.periodType == T(de.financer.model.PeriodType).EXPENSE_YEAR} ? expense-year-period-period-overview"/>
|
||||
<td th:utext="${#numbers.formatDecimal(periodOverview.total/100D, 1, 'DEFAULT', 2, 'DEFAULT') + currencySymbol}"
|
||||
th:classappend="${periodOverview.total > periodOverview.incomeSum} ? overspend"/>
|
||||
th:classappend="${(periodOverview.total > periodOverview.incomeSum ? 'overspend' : '') +
|
||||
(periodOverview.periodType == T(de.financer.model.PeriodType).EXPENSE_YEAR ? ' expense-year-period-period-overview' : '')}"/>
|
||||
<td th:if="${periodOverview.assetsSum != null}">
|
||||
<div id="period-overview-asset-container">
|
||||
<span th:utext="${#numbers.formatDecimal(periodOverview.assetsSum/100D, 1, 'DEFAULT', 2, 'DEFAULT') + currencySymbol}"/>
|
||||
<span th:utext="${#numbers.formatDecimal(periodOverview.assetsSum/100D, 1, 'DEFAULT', 2, 'DEFAULT') + currencySymbol}"
|
||||
th:classappend="${periodOverview.periodType == T(de.financer.model.PeriodType).EXPENSE_YEAR} ? expense-year-period-period-overview"/>
|
||||
<span th:if="${periodOverview.assetTrend == T(de.financer.dto.AssetTrend).UP}" class="icon color-good"></span>
|
||||
<span th:if="${periodOverview.assetTrend == T(de.financer.dto.AssetTrend).DOWN}" class="icon color-bad"></span>
|
||||
<span th:if="${periodOverview.assetTrend == T(de.financer.dto.AssetTrend).EQUAL}" class="icon color-neutral"></span>
|
||||
</div>
|
||||
</td>
|
||||
<td th:if="${periodOverview.assetsSum == null}" />
|
||||
<td th:text="${periodOverview.transactionCount}"/>
|
||||
<td th:text="${periodOverview.transactionCount}"
|
||||
th:classappend="${periodOverview.periodType == T(de.financer.model.PeriodType).EXPENSE_YEAR} ? expense-year-period-period-overview"/>
|
||||
<td nowrap>
|
||||
<div id="period-overview-actions-container">
|
||||
<a th:href="@{/showTransactions(periodId=${periodOverview.periodId})}"
|
||||
th:text="#{financer.period-overview.table.actions.showTransactions}" />
|
||||
</div>
|
||||
<details>
|
||||
<summary th:text="#{financer.period-overview.show-actions}"/>
|
||||
<div id="period-overview-show-actions-detail-container">
|
||||
<div id="period-overview-show-actions-detail-container-show-all">
|
||||
<a th:href="@{/showAllTransactions(periodId=${periodOverview.periodId})}"
|
||||
th:text="#{financer.period-overview.table.actions.showAllTransactions}" />
|
||||
</div>
|
||||
<div id="period-overview-show-actions-detail-container-show-income">
|
||||
<a th:href="@{/showIncomeTransactions(periodId=${periodOverview.periodId})}"
|
||||
th:text="#{financer.period-overview.table.actions.showIncomeTransactions}" />
|
||||
</div>
|
||||
<div id="period-overview-show-actions-detail-container-show-expense">
|
||||
<a th:href="@{/showExpenseTransactions(periodId=${periodOverview.periodId})}"
|
||||
th:text="#{financer.period-overview.table.actions.showExpenseTransactions}" />
|
||||
</div>
|
||||
<div id="period-overview-show-actions-detail-container-show-liability">
|
||||
<a th:href="@{/showLiabilityTransactions(periodId=${periodOverview.periodId})}"
|
||||
th:text="#{financer.period-overview.table.actions.showLiabilityTransactions}" />
|
||||
</div>
|
||||
</div>
|
||||
</details>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
<body>
|
||||
<h1 th:text="#{financer.heading.search-transactions}" />
|
||||
<span class="errorMessage" th:if="${errorMessage != null}" th:text="#{'financer.error-message.' + ${errorMessage}}"/>
|
||||
<a th:href="@{/accountOverview}" th:text="#{financer.search-transactions.back-to-overview}"/>
|
||||
<a th:if="${returnTo == null}" th:href="@{/accountOverview}" th:text="#{financer.search-transactions.back-to-overview}"/>
|
||||
<a th:if="${returnTo != null}" th:href="@{${returnTo}}" th:text="#{financer.search-transactions.back-to-overview}"/>
|
||||
<form id="search-transactions-form" action="#" th:action="@{/searchTransactions}" th:object="${form}"
|
||||
method="post">
|
||||
<label for="inputFql" th:text="#{financer.search-transactions.label.fql}"/>
|
||||
@@ -30,6 +31,8 @@
|
||||
<li th:text="#{financer.search-transactions.show-query-options.toAccount}" />
|
||||
<li th:text="#{financer.search-transactions.show-query-options.fromAccountGroup}" />
|
||||
<li th:text="#{financer.search-transactions.show-query-options.toAccountGroup}" />
|
||||
<li th:text="#{financer.search-transactions.show-query-options.fromAccountType}" />
|
||||
<li th:text="#{financer.search-transactions.show-query-options.toAccountType}" />
|
||||
<li th:text="#{financer.search-transactions.show-query-options.date}" />
|
||||
<li th:text="#{financer.search-transactions.show-query-options.recurring}" />
|
||||
<li th:text="#{financer.search-transactions.show-query-options.taxRelevant}" />
|
||||
|
||||
Reference in New Issue
Block a user