Add calendar, SKIP and fix some bugs
This commit is contained in:
@@ -0,0 +1,41 @@
|
|||||||
|
package de.financer.dto;
|
||||||
|
|
||||||
|
import de.financer.model.RecurringTransaction;
|
||||||
|
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
|
||||||
|
public class RecurringTransactionDueInRangeResponseDto {
|
||||||
|
private LocalDate date;
|
||||||
|
private Iterable<RecurringTransaction> recurringTransactions;
|
||||||
|
|
||||||
|
public RecurringTransactionDueInRangeResponseDto() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public RecurringTransactionDueInRangeResponseDto(LocalDate date, Iterable<RecurringTransaction> recurringTransactions) {
|
||||||
|
this.date = date;
|
||||||
|
this.recurringTransactions = recurringTransactions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDate getDate() {
|
||||||
|
return date;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDate(LocalDate date) {
|
||||||
|
this.date = date;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Iterable<RecurringTransaction> getRecurringTransactions() {
|
||||||
|
return recurringTransactions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRecurringTransactions(Iterable<RecurringTransaction> recurringTransactions) {
|
||||||
|
this.recurringTransactions = recurringTransactions;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return ReflectionToStringBuilder.toString(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -53,7 +53,14 @@ public enum HolidayWeekendType {
|
|||||||
* X' -> Earlier, effective due date of action
|
* X' -> Earlier, effective due date of action
|
||||||
* </pre>
|
* </pre>
|
||||||
*/
|
*/
|
||||||
PREVIOUS_WORKDAY;
|
PREVIOUS_WORKDAY,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Indicates that the action should be skipped on the particular occurrence
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
SKIP;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method validates whether the given string represents a valid holiday weekend type.
|
* This method validates whether the given string represents a valid holiday weekend type.
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<packaging.type>jar</packaging.type>
|
<packaging.type>jar</packaging.type>
|
||||||
<activeProfiles>hsqldb,dev</activeProfiles>
|
<activeProfiles>postgres,dev</activeProfiles>
|
||||||
<deploymentProfile>mk</deploymentProfile>
|
<deploymentProfile>mk</deploymentProfile>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ L_PAREN : '(' ;
|
|||||||
R_PAREN : ')' ;
|
R_PAREN : ')' ;
|
||||||
IDENTIFIER : [a-zA-Z]+ ;
|
IDENTIFIER : [a-zA-Z]+ ;
|
||||||
INT_VALUE : [0-9]+ ;
|
INT_VALUE : [0-9]+ ;
|
||||||
STRING_VALUE : '\'' [a-zA-Z0-9- ]+ '\'' ;
|
STRING_VALUE : '\'' [a-zA-Z0-9\-/ ]+ '\'' ;
|
||||||
DATE_VALUE : [0-9-]+ ;
|
DATE_VALUE : [0-9-]+ ;
|
||||||
|
|
||||||
NEWLINE : ('\r'? '\n' | '\r')+ ;
|
NEWLINE : ('\r'? '\n' | '\r')+ ;
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
package de.financer.controller;
|
package de.financer.controller;
|
||||||
|
|
||||||
import de.financer.ResponseReason;
|
import de.financer.ResponseReason;
|
||||||
|
import de.financer.dto.RecurringTransactionDueInRangeResponseDto;
|
||||||
import de.financer.model.RecurringTransaction;
|
import de.financer.model.RecurringTransaction;
|
||||||
import de.financer.service.RecurringTransactionService;
|
import de.financer.service.RecurringTransactionService;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
@@ -114,4 +116,22 @@ public class RecurringTransactionController {
|
|||||||
|
|
||||||
return responseReason.toResponseEntity();
|
return responseReason.toResponseEntity();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("getAllDueInRange")
|
||||||
|
public Iterable<RecurringTransactionDueInRangeResponseDto> getAllDueInRange(String start, String end) {
|
||||||
|
if (LOGGER.isDebugEnabled()) {
|
||||||
|
LOGGER.debug(String
|
||||||
|
.format("/recurringTransactions/getAllDueInRange got parameters: %s, %s",
|
||||||
|
start, end));
|
||||||
|
}
|
||||||
|
|
||||||
|
final Iterable<RecurringTransactionDueInRangeResponseDto> dueInRange = this.recurringTransactionService.getAllDueInRange(start, end);
|
||||||
|
|
||||||
|
if (LOGGER.isDebugEnabled()) {
|
||||||
|
LOGGER.debug(String
|
||||||
|
.format("/recurringTransactions/getAllDueInRange returns with %s", dueInRange));
|
||||||
|
}
|
||||||
|
|
||||||
|
return dueInRange;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,11 @@ package de.financer.service;
|
|||||||
import de.financer.ResponseReason;
|
import de.financer.ResponseReason;
|
||||||
import de.financer.config.FinancerConfig;
|
import de.financer.config.FinancerConfig;
|
||||||
import de.financer.dba.RecurringTransactionRepository;
|
import de.financer.dba.RecurringTransactionRepository;
|
||||||
import de.financer.model.*;
|
import de.financer.dto.RecurringTransactionDueInRangeResponseDto;
|
||||||
|
import de.financer.model.Account;
|
||||||
|
import de.financer.model.HolidayWeekendType;
|
||||||
|
import de.financer.model.IntervalType;
|
||||||
|
import de.financer.model.RecurringTransaction;
|
||||||
import org.apache.commons.collections4.IterableUtils;
|
import org.apache.commons.collections4.IterableUtils;
|
||||||
import org.apache.commons.lang3.BooleanUtils;
|
import org.apache.commons.lang3.BooleanUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
@@ -17,9 +21,12 @@ import org.springframework.transaction.annotation.Propagation;
|
|||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
|
import java.time.Period;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.time.format.DateTimeParseException;
|
import java.time.format.DateTimeParseException;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@@ -144,8 +151,19 @@ public class RecurringTransactionService {
|
|||||||
// If so the recurring transaction is due today
|
// If so the recurring transaction is due today
|
||||||
.anyMatch((d) -> d.equals(now));
|
.anyMatch((d) -> d.equals(now));
|
||||||
final boolean weekend = this.ruleService.isWeekend(now);
|
final boolean weekend = this.ruleService.isWeekend(now);
|
||||||
boolean defer = false;
|
|
||||||
|
|
||||||
|
// If a recurring transaction has holiday weekend type SKIP and today is either a weekend day or a holiday that
|
||||||
|
// transaction cannot be due today
|
||||||
|
if (recurringTransaction.getHolidayWeekendType() == HolidayWeekendType.SKIP && (holiday || weekend)) {
|
||||||
|
LOGGER.debug(String
|
||||||
|
.format("Recurring transaction %s not due today because it has HWT %s and today is(holiday=%s or weekend=%s)",
|
||||||
|
ReflectionToStringBuilder.toString(recurringTransaction), recurringTransaction
|
||||||
|
.getHolidayWeekendType(), holiday, weekend));
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean defer = false;
|
||||||
|
|
||||||
if (holiday || weekend) {
|
if (holiday || weekend) {
|
||||||
defer = recurringTransaction.getHolidayWeekendType() == HolidayWeekendType.NEXT_WORKDAY
|
defer = recurringTransaction.getHolidayWeekendType() == HolidayWeekendType.NEXT_WORKDAY
|
||||||
@@ -174,7 +192,7 @@ public class RecurringTransactionService {
|
|||||||
* @return <code>true</code> if the recurring transaction is due today, <code>false</code> otherwise
|
* @return <code>true</code> if the recurring transaction is due today, <code>false</code> otherwise
|
||||||
*/
|
*/
|
||||||
private boolean checkRecurringTransactionDuePast(RecurringTransaction recurringTransaction, LocalDate now) {
|
private boolean checkRecurringTransactionDuePast(RecurringTransaction recurringTransaction, LocalDate now) {
|
||||||
// Recurring transactions with holiday weekend type SAME_DAY or PREVIOUS_WORKDAY can't be due in the past
|
// Recurring transactions with holiday weekend type SAME_DAY, SKIP or PREVIOUS_WORKDAY can't be due in the past
|
||||||
if (!HolidayWeekendType.NEXT_WORKDAY.equals(recurringTransaction.getHolidayWeekendType())) {
|
if (!HolidayWeekendType.NEXT_WORKDAY.equals(recurringTransaction.getHolidayWeekendType())) {
|
||||||
LOGGER.debug(String.format("Recurring transaction %s has HWT %s and thus cannot be due in the past",
|
LOGGER.debug(String.format("Recurring transaction %s has HWT %s and thus cannot be due in the past",
|
||||||
ReflectionToStringBuilder.toString(recurringTransaction),
|
ReflectionToStringBuilder.toString(recurringTransaction),
|
||||||
@@ -255,7 +273,7 @@ public class RecurringTransactionService {
|
|||||||
* @return <code>true</code> if the recurring transaction is due today, <code>false</code> otherwise
|
* @return <code>true</code> if the recurring transaction is due today, <code>false</code> otherwise
|
||||||
*/
|
*/
|
||||||
private boolean checkRecurringTransactionDueFuture(RecurringTransaction recurringTransaction, LocalDate now) {
|
private boolean checkRecurringTransactionDueFuture(RecurringTransaction recurringTransaction, LocalDate now) {
|
||||||
// Recurring transactions with holiday weekend type SAME_DAY or PREVIOUS_WORKDAY can't be due in the future
|
// Recurring transactions with holiday weekend type SAME_DAY, SKIP or PREVIOUS_WORKDAY can't be due in the future
|
||||||
if (!HolidayWeekendType.PREVIOUS_WORKDAY.equals(recurringTransaction.getHolidayWeekendType())) {
|
if (!HolidayWeekendType.PREVIOUS_WORKDAY.equals(recurringTransaction.getHolidayWeekendType())) {
|
||||||
LOGGER.debug(String.format("Recurring transaction %s has HWT %s and thus cannot be due in the future",
|
LOGGER.debug(String.format("Recurring transaction %s has HWT %s and thus cannot be due in the future",
|
||||||
ReflectionToStringBuilder.toString(recurringTransaction),
|
ReflectionToStringBuilder.toString(recurringTransaction),
|
||||||
@@ -267,12 +285,12 @@ public class RecurringTransactionService {
|
|||||||
// If today is a weekend day or holiday the recurring transaction cannot be due today, because the
|
// If today is a weekend day or holiday the recurring transaction cannot be due today, because the
|
||||||
// holiday weekend type says PREVIOUS_WORKDAY.
|
// holiday weekend type says PREVIOUS_WORKDAY.
|
||||||
if (this.ruleService.isHoliday(now) || this.ruleService.isWeekend(now)) {
|
if (this.ruleService.isHoliday(now) || this.ruleService.isWeekend(now)) {
|
||||||
LOGGER.debug(String.format("Recurring transaction %s has HWT %s and today is either a holiday or weekend," +
|
LOGGER.debug(String.format("Recurring transaction %s has HWT %s and today is either a holiday or weekend," +
|
||||||
" thus it cannot be due in the future",
|
" thus it cannot be due in the future",
|
||||||
ReflectionToStringBuilder.toString(recurringTransaction),
|
ReflectionToStringBuilder.toString(recurringTransaction),
|
||||||
recurringTransaction.getHolidayWeekendType()));
|
recurringTransaction.getHolidayWeekendType()));
|
||||||
|
|
||||||
return false; // early return
|
return false; // early return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -313,7 +331,6 @@ public class RecurringTransactionService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Transactional(propagation = Propagation.REQUIRED)
|
@Transactional(propagation = Propagation.REQUIRED)
|
||||||
public ResponseReason createRecurringTransaction(String fromAccountKey, String toAccountKey, Long amount,
|
public ResponseReason createRecurringTransaction(String fromAccountKey, String toAccountKey, Long amount,
|
||||||
String description, String holidayWeekendType,
|
String description, String holidayWeekendType,
|
||||||
@@ -512,4 +529,26 @@ public class RecurringTransactionService {
|
|||||||
|
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method calculates all {@link RecurringTransaction}s due in the given date range.
|
||||||
|
*
|
||||||
|
* @param start the start of the range, inclusive
|
||||||
|
* @param end the end of the range, inclusive
|
||||||
|
*
|
||||||
|
* @return a list of date->recurring transactions due mappings
|
||||||
|
*/
|
||||||
|
public Iterable<RecurringTransactionDueInRangeResponseDto> getAllDueInRange(String start, String end) {
|
||||||
|
final List<RecurringTransactionDueInRangeResponseDto> dueInRange = new ArrayList<>();
|
||||||
|
final LocalDate startDate = LocalDate
|
||||||
|
.parse(start, DateTimeFormatter.ofPattern(this.financerConfig.getDateFormat()));
|
||||||
|
final LocalDate tmpEndDate = LocalDate
|
||||||
|
.parse(end, DateTimeFormatter.ofPattern(this.financerConfig.getDateFormat()));
|
||||||
|
final LocalDate endDate = tmpEndDate.plusDays(1); // Range end is always exclusive in Java API
|
||||||
|
|
||||||
|
startDate.datesUntil(endDate, Period.ofDays(1)).forEach(d -> dueInRange
|
||||||
|
.add(new RecurringTransactionDueInRangeResponseDto(d, this.getAllDueToday(d))));
|
||||||
|
|
||||||
|
return dueInRange;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ public class RuleService implements InitializingBean {
|
|||||||
* <p>
|
* <p>
|
||||||
* The multiplier controls whether the current amount of the given from account is increased or decreased depending
|
* The multiplier controls whether the current amount of the given from account is increased or decreased depending
|
||||||
* on the {@link AccountType} of the given account.
|
* on the {@link AccountType} of the given account.
|
||||||
|
* </p>
|
||||||
*
|
*
|
||||||
* @param fromAccount the from account to get the multiplier for
|
* @param fromAccount the from account to get the multiplier for
|
||||||
*
|
*
|
||||||
@@ -102,6 +103,7 @@ public class RuleService implements InitializingBean {
|
|||||||
* <p>
|
* <p>
|
||||||
* The multiplier controls whether the current amount of the given to account is increased or decreased depending on
|
* The multiplier controls whether the current amount of the given to account is increased or decreased depending on
|
||||||
* the {@link AccountType} of the given account.
|
* the {@link AccountType} of the given account.
|
||||||
|
* </p>
|
||||||
*
|
*
|
||||||
* @param toAccount the to account to get the multiplier for
|
* @param toAccount the to account to get the multiplier for
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
package de.financer.calendar;
|
||||||
|
|
||||||
|
import de.financer.model.RecurringTransaction;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.temporal.ChronoField;
|
||||||
|
|
||||||
|
public class Day {
|
||||||
|
private LocalDate date;
|
||||||
|
private Iterable<RecurringTransaction> transactions;
|
||||||
|
|
||||||
|
public Day(LocalDate date) {
|
||||||
|
this.date = date;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDay() {
|
||||||
|
return this.date.get(ChronoField.DAY_OF_MONTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDate getDate() {
|
||||||
|
return this.date;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Iterable<RecurringTransaction> getTransactions() {
|
||||||
|
return transactions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isPreviousOrNextMonth(Integer offset) {
|
||||||
|
LocalDate now = LocalDate.now().plusMonths(offset);
|
||||||
|
|
||||||
|
return !now.getMonth().equals(this.date.getMonth());
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isToday() {
|
||||||
|
return LocalDate.now().equals(this.date);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTransactions(Iterable<RecurringTransaction> transactions) {
|
||||||
|
this.transactions = transactions;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Day{" +
|
||||||
|
"date=" + date +
|
||||||
|
", transactions=" + transactions +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package de.financer.calendar;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class Week {
|
||||||
|
private int weekNumber;
|
||||||
|
private List<Day> days;
|
||||||
|
|
||||||
|
public int getWeekNumber() {
|
||||||
|
return weekNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWeekNumber(int weekNumber) {
|
||||||
|
this.weekNumber = weekNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Day> getDays() {
|
||||||
|
return days;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDays(List<Day> days) {
|
||||||
|
this.days = days;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Week{" +
|
||||||
|
"weekNumber=" + weekNumber +
|
||||||
|
", days=" + days +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
|
|||||||
import org.springframework.context.annotation.ComponentScan;
|
import org.springframework.context.annotation.ComponentScan;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
import java.time.DayOfWeek;
|
||||||
import java.util.Currency;
|
import java.util.Currency;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@@ -19,6 +20,7 @@ public class FinancerConfig {
|
|||||||
private String version;
|
private String version;
|
||||||
private String currencyCode;
|
private String currencyCode;
|
||||||
private Currency currency;
|
private Currency currency;
|
||||||
|
private DayOfWeek firstDayOfWeek;
|
||||||
|
|
||||||
public String getServerUrl() {
|
public String getServerUrl() {
|
||||||
return serverUrl;
|
return serverUrl;
|
||||||
@@ -53,4 +55,12 @@ public class FinancerConfig {
|
|||||||
public Currency getCurrency() {
|
public Currency getCurrency() {
|
||||||
return currency;
|
return currency;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DayOfWeek getFirstDayOfWeek() {
|
||||||
|
return firstDayOfWeek;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFirstDayOfWeek(String firstDayOfWeek) {
|
||||||
|
this.firstDayOfWeek = DayOfWeek.valueOf(firstDayOfWeek);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,146 @@
|
|||||||
|
package de.financer.controller;
|
||||||
|
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import de.financer.calendar.Day;
|
||||||
|
import de.financer.calendar.Week;
|
||||||
|
import de.financer.config.FinancerConfig;
|
||||||
|
import de.financer.dto.RecurringTransactionDueInRangeResponseDto;
|
||||||
|
import de.financer.dto.SearchTransactionsResponseDto;
|
||||||
|
import de.financer.template.FinancerRestTemplate;
|
||||||
|
import de.financer.template.exception.FinancerRestException;
|
||||||
|
import de.financer.util.ControllerUtils;
|
||||||
|
import org.apache.commons.collections4.IterableUtils;
|
||||||
|
import org.apache.commons.lang3.math.NumberUtils;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.core.ParameterizedTypeReference;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.util.UriComponentsBuilder;
|
||||||
|
|
||||||
|
import java.time.DayOfWeek;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.format.TextStyle;
|
||||||
|
import java.time.temporal.TemporalField;
|
||||||
|
import java.time.temporal.WeekFields;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
public class CalendarController {
|
||||||
|
@Autowired
|
||||||
|
private FinancerConfig financerConfig;
|
||||||
|
|
||||||
|
@GetMapping("/recurringTransactionCalendar")
|
||||||
|
public String recurringTransactionCalendar(Model model, String offset) {
|
||||||
|
Integer offsetNumber = null;
|
||||||
|
|
||||||
|
if (!NumberUtils.isCreatable(offset)) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
offsetNumber = Integer.valueOf(offset);
|
||||||
|
|
||||||
|
// 1. Add days for calendar headings
|
||||||
|
model.addAttribute("firstWeekDay", this.financerConfig.getFirstDayOfWeek());
|
||||||
|
model.addAttribute("secondWeekDay", this.financerConfig.getFirstDayOfWeek().plus(1));
|
||||||
|
model.addAttribute("thirdWeekDay", this.financerConfig.getFirstDayOfWeek().plus(2));
|
||||||
|
model.addAttribute("fourthWeekDay", this.financerConfig.getFirstDayOfWeek().plus(3));
|
||||||
|
model.addAttribute("fifthWeekDay", this.financerConfig.getFirstDayOfWeek().plus(4));
|
||||||
|
model.addAttribute("sixthWeekDay", this.financerConfig.getFirstDayOfWeek().plus(5));
|
||||||
|
model.addAttribute("seventhWeekDay", this.financerConfig.getFirstDayOfWeek().plus(6));
|
||||||
|
|
||||||
|
// 2. Calculate the days in the calendar
|
||||||
|
DayOfWeek firstDayOfWeek = this.financerConfig.getFirstDayOfWeek();
|
||||||
|
int tmpLastDayOfWeek = firstDayOfWeek.getValue() - 1;
|
||||||
|
DayOfWeek lastOfWeek = DayOfWeek.of(tmpLastDayOfWeek == 0 ? 7 : tmpLastDayOfWeek);
|
||||||
|
|
||||||
|
LocalDate today = LocalDate.now().plusMonths(offsetNumber);
|
||||||
|
LocalDate firstOfMonth = today.withDayOfMonth(1);
|
||||||
|
LocalDate start = null;
|
||||||
|
|
||||||
|
model.addAttribute("today", today);
|
||||||
|
|
||||||
|
if (firstOfMonth.getDayOfWeek() == firstDayOfWeek) {
|
||||||
|
// nothing to do, first is firstDayOfWeek
|
||||||
|
start = firstOfMonth;
|
||||||
|
}
|
||||||
|
// walk back till we have firstDayOfWeek
|
||||||
|
else {
|
||||||
|
LocalDate tmp = firstOfMonth;
|
||||||
|
|
||||||
|
while ((tmp = tmp.minusDays(1)).getDayOfWeek() != firstDayOfWeek) {
|
||||||
|
// Just spinning
|
||||||
|
}
|
||||||
|
|
||||||
|
start = tmp; // last firstDayOfWeek of last month
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Day> days = new ArrayList<>();
|
||||||
|
LocalDate end = today.plusMonths(1).withDayOfMonth(1);
|
||||||
|
|
||||||
|
// Go till first lastOfWeek in next month, but only if the last day of the current month is
|
||||||
|
// not lastOfWeek
|
||||||
|
if (end.minusDays(1).getDayOfWeek() != lastOfWeek) {
|
||||||
|
|
||||||
|
while (end.getDayOfWeek() != lastOfWeek) {
|
||||||
|
end = end.plusDays(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
end = end.plusDays(1); // because datesUntil parameter is exclusive
|
||||||
|
}
|
||||||
|
|
||||||
|
start.datesUntil(end).forEach((ld) -> days.add(new Day(ld)));
|
||||||
|
|
||||||
|
// 3. Get the recurring transactions due at the calculated days from the server
|
||||||
|
final String rangeStart = ControllerUtils.formatDate(this.financerConfig, days.get(0).getDate());
|
||||||
|
final String rangeEnd = ControllerUtils.formatDate(this.financerConfig, days.get(days.size() - 1).getDate());
|
||||||
|
|
||||||
|
try {
|
||||||
|
final UriComponentsBuilder transactionBuilder = UriComponentsBuilder
|
||||||
|
.fromHttpUrl(ControllerUtils.buildUrl(this.financerConfig, Function.RT_GET_ALL_DUE_IN_RANGE));
|
||||||
|
|
||||||
|
transactionBuilder.queryParam("start", rangeStart);
|
||||||
|
transactionBuilder.queryParam("end", rangeEnd);
|
||||||
|
|
||||||
|
final Iterable<RecurringTransactionDueInRangeResponseDto> trxs = FinancerRestTemplate.exchangeGet(transactionBuilder,
|
||||||
|
new ParameterizedTypeReference<Iterable<RecurringTransactionDueInRangeResponseDto>>() {
|
||||||
|
});
|
||||||
|
|
||||||
|
// 3a. Match days and recurring transactions from server
|
||||||
|
IterableUtils.toList(trxs).stream().forEach(trx -> days.stream()
|
||||||
|
.filter(d -> d.getDate().equals(trx.getDate()))
|
||||||
|
.findFirst()
|
||||||
|
.get()
|
||||||
|
.setTransactions(trx.getRecurringTransactions()));
|
||||||
|
}
|
||||||
|
catch(FinancerRestException e) {
|
||||||
|
// TODO
|
||||||
|
model.addAttribute("errorMessage", e.getResponseReason().name());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Build the actual weeks from the data calculated before
|
||||||
|
List<Week> weeks = Lists.partition(days, 7).stream().map(l -> {
|
||||||
|
Week w = new Week();
|
||||||
|
|
||||||
|
LocalDate firstOfWeek = l.get(0).getDate();
|
||||||
|
TemporalField woy = WeekFields.of(Locale.getDefault()).weekOfWeekBasedYear(); // Not sure about using Default locale, but well ...
|
||||||
|
|
||||||
|
w.setWeekNumber(firstOfWeek.get(woy));
|
||||||
|
w.setDays(l);
|
||||||
|
|
||||||
|
return w;
|
||||||
|
}).collect(Collectors.toList());
|
||||||
|
|
||||||
|
model.addAttribute("weeks", weeks);
|
||||||
|
model.addAttribute("offset", offsetNumber);
|
||||||
|
|
||||||
|
ControllerUtils.addVersionAttribute(model, this.financerConfig);
|
||||||
|
ControllerUtils.addCurrencySymbol(model, this.financerConfig);
|
||||||
|
|
||||||
|
return "recurringTransaction/calendar";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -30,6 +30,7 @@ public enum Function {
|
|||||||
RT_CREATE_RECURRING_TRANSACTION("recurringTransactions/createRecurringTransaction"),
|
RT_CREATE_RECURRING_TRANSACTION("recurringTransactions/createRecurringTransaction"),
|
||||||
RT_DELETE_RECURRING_TRANSACTION("recurringTransactions/deleteRecurringTransaction"),
|
RT_DELETE_RECURRING_TRANSACTION("recurringTransactions/deleteRecurringTransaction"),
|
||||||
RT_CREATE_TRANSACTION("recurringTransactions/createTransaction"),
|
RT_CREATE_TRANSACTION("recurringTransactions/createTransaction"),
|
||||||
|
RT_GET_ALL_DUE_IN_RANGE("recurringTransactions/getAllDueInRange"),
|
||||||
|
|
||||||
P_GET_CURRENT_EXPENSE_PERIOD("periods/getCurrentExpensePeriod"),
|
P_GET_CURRENT_EXPENSE_PERIOD("periods/getCurrentExpensePeriod"),
|
||||||
P_CLOSE_CURRENT_EXPENSE_PERIOD("periods/closeCurrentExpensePeriod"),
|
P_CLOSE_CURRENT_EXPENSE_PERIOD("periods/closeCurrentExpensePeriod"),
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
package de.financer.controller;
|
package de.financer.controller;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
import de.financer.ResponseReason;
|
import de.financer.ResponseReason;
|
||||||
|
import de.financer.calendar.Day;
|
||||||
|
import de.financer.calendar.Week;
|
||||||
import de.financer.config.FinancerConfig;
|
import de.financer.config.FinancerConfig;
|
||||||
import de.financer.model.*;
|
import de.financer.model.*;
|
||||||
import de.financer.template.*;
|
import de.financer.template.*;
|
||||||
@@ -15,8 +18,15 @@ import org.springframework.web.bind.annotation.GetMapping;
|
|||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.util.UriComponentsBuilder;
|
import org.springframework.web.util.UriComponentsBuilder;
|
||||||
|
|
||||||
|
import java.time.DayOfWeek;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.temporal.Temporal;
|
||||||
|
import java.time.temporal.TemporalField;
|
||||||
|
import java.time.temporal.WeekFields;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
@@ -257,5 +267,4 @@ public class RecurringTransactionController {
|
|||||||
|
|
||||||
return "redirect:/accountOverview";
|
return "redirect:/accountOverview";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import de.financer.form.NewTransactionForm;
|
|||||||
import de.financer.model.Account;
|
import de.financer.model.Account;
|
||||||
import de.financer.template.exception.FinancerRestException;
|
import de.financer.template.exception.FinancerRestException;
|
||||||
import de.financer.util.ControllerUtils;
|
import de.financer.util.ControllerUtils;
|
||||||
|
import org.apache.commons.collections4.IterableUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.core.ParameterizedTypeReference;
|
import org.springframework.core.ParameterizedTypeReference;
|
||||||
@@ -21,6 +22,7 @@ import org.springframework.web.bind.annotation.PostMapping;
|
|||||||
import org.springframework.web.util.UriComponentsBuilder;
|
import org.springframework.web.util.UriComponentsBuilder;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Base64;
|
import java.util.Base64;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
@@ -56,10 +58,12 @@ public class TransactionController {
|
|||||||
|
|
||||||
|
|
||||||
model.addAttribute("transactions", trxs);
|
model.addAttribute("transactions", trxs);
|
||||||
|
model.addAttribute("transactionCount", IterableUtils.size(trxs));
|
||||||
}
|
}
|
||||||
catch(FinancerRestException e) {
|
catch(FinancerRestException e) {
|
||||||
// TODO
|
// TODO
|
||||||
model.addAttribute("errorMessage", e.getResponseReason().name());
|
model.addAttribute("errorMessage", e.getResponseReason().name());
|
||||||
|
model.addAttribute("transactionCount", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
model.addAttribute("form", form);
|
model.addAttribute("form", form);
|
||||||
|
|||||||
@@ -97,6 +97,6 @@ public class ControllerUtils {
|
|||||||
|
|
||||||
public static void addCurrencySymbol(Model model, FinancerConfig financerConfig) {
|
public static void addCurrencySymbol(Model model, FinancerConfig financerConfig) {
|
||||||
// Add a space right in front of the currency symbol, so it's not glued to the amount
|
// Add a space right in front of the currency symbol, so it's not glued to the amount
|
||||||
model.addAttribute("currencySymbol", " " + financerConfig.getCurrency().getSymbol());
|
model.addAttribute("currencySymbol", " " + financerConfig.getCurrency().getSymbol());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,4 +35,8 @@ spring.messages.basename=i18n/message
|
|||||||
financer.currencyCode=EUR
|
financer.currencyCode=EUR
|
||||||
|
|
||||||
push-service-client.serverUrl=http://localhost:8077/push-service-server/
|
push-service-client.serverUrl=http://localhost:8077/push-service-server/
|
||||||
logging.level.de.pushservice=DEBUG
|
logging.level.de.pushservice=DEBUG
|
||||||
|
|
||||||
|
# The first day of a week in a calendar
|
||||||
|
# Possible values: MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
|
||||||
|
financer.firstDayOfWeek=MONDAY
|
||||||
@@ -10,6 +10,7 @@ financer.account-overview.available-actions.recurring-transaction-all=Show all r
|
|||||||
financer.account-overview.available-actions.create-account-group=Create new account group
|
financer.account-overview.available-actions.create-account-group=Create new account group
|
||||||
financer.account-overview.available-actions.select-chart=Generate a chart
|
financer.account-overview.available-actions.select-chart=Generate a chart
|
||||||
financer.account-overview.available-actions.close-current-period=Close the current expense period
|
financer.account-overview.available-actions.close-current-period=Close the current expense period
|
||||||
|
financer.account-overview.available-actions.recurring-transaction-calendar=Recurring transaction calendar
|
||||||
financer.account-overview.status=Status\:
|
financer.account-overview.status=Status\:
|
||||||
financer.account-overview.status.recurring-transaction-due-today=Recurring transactions due today\:
|
financer.account-overview.status.recurring-transaction-due-today=Recurring transactions due today\:
|
||||||
financer.account-overview.status.recurring-transaction-active=Active recurring transactions\:
|
financer.account-overview.status.recurring-transaction-active=Active recurring transactions\:
|
||||||
@@ -118,6 +119,7 @@ financer.transaction-list.table.recurring.yes=Yes
|
|||||||
financer.transaction-list.table.recurring.no=No
|
financer.transaction-list.table.recurring.no=No
|
||||||
financer.transaction-list.table.taxRelevant.true=Yes
|
financer.transaction-list.table.taxRelevant.true=Yes
|
||||||
financer.transaction-list.table.taxRelevant.false=No
|
financer.transaction-list.table.taxRelevant.false=No
|
||||||
|
financer.transaction-list.transaction-count=Found {0} transactions
|
||||||
|
|
||||||
financer.recurring-to-transaction-with-amount.title=financer\: create transaction from recurring with amount
|
financer.recurring-to-transaction-with-amount.title=financer\: create transaction from recurring with amount
|
||||||
financer.recurring-to-transaction-with-amount.label.amount=Amount\:
|
financer.recurring-to-transaction-with-amount.label.amount=Amount\:
|
||||||
@@ -174,6 +176,7 @@ financer.interval-type.YEARLY=Yearly
|
|||||||
financer.holiday-weekend-type.SAME_DAY=Same day
|
financer.holiday-weekend-type.SAME_DAY=Same day
|
||||||
financer.holiday-weekend-type.NEXT_WORKDAY=Next workday
|
financer.holiday-weekend-type.NEXT_WORKDAY=Next workday
|
||||||
financer.holiday-weekend-type.PREVIOUS_WORKDAY=Previous workday
|
financer.holiday-weekend-type.PREVIOUS_WORKDAY=Previous workday
|
||||||
|
financer.holiday-weekend-type.SKIP=Skip once
|
||||||
|
|
||||||
financer.account-type.BANK=Bank
|
financer.account-type.BANK=Bank
|
||||||
financer.account-type.CASH=Cash
|
financer.account-type.CASH=Cash
|
||||||
@@ -199,8 +202,10 @@ financer.heading.chart-select=financer\: select a chart to generate
|
|||||||
financer.heading.chart-config-account-group-expenses-for-period=financer\: configure account group expenses for period chart
|
financer.heading.chart-config-account-group-expenses-for-period=financer\: configure account group expenses for period chart
|
||||||
financer.heading.chart-config-account-expenses-for-period=financer\: configure account expenses for period chart
|
financer.heading.chart-config-account-expenses-for-period=financer\: configure account expenses for period chart
|
||||||
financer.heading.search-transactions=financer\: search transactions
|
financer.heading.search-transactions=financer\: search transactions
|
||||||
|
financer.heading.recurring-transaction-calendar=financer\: recurring transaction calendar
|
||||||
|
|
||||||
financer.cancel-back-to-overview=Cancel and back to overview
|
financer.cancel-back-to-overview=Cancel and back to overview
|
||||||
|
financer.back-to-overview=Back to overview
|
||||||
|
|
||||||
financer.chart.account-group-expenses-current-period.title=Expenses of the current period grouped by account group
|
financer.chart.account-group-expenses-current-period.title=Expenses of the current period grouped by account group
|
||||||
financer.chart.account-group-expenses-for-period.title=Expenses for period from {0} to {1} grouped by account group
|
financer.chart.account-group-expenses-for-period.title=Expenses for period from {0} to {1} grouped by account group
|
||||||
@@ -218,6 +223,19 @@ financer.chart.name.ACCOUNT_EXPENSES_FOR_PERIOD=Expenses for a configurable peri
|
|||||||
financer.chart.name.EXPENSE_PERIOD_TOTALS_CURRENT_YEAR=Overview about the income and expenses in the current year (bar chart)
|
financer.chart.name.EXPENSE_PERIOD_TOTALS_CURRENT_YEAR=Overview about the income and expenses in the current year (bar chart)
|
||||||
financer.chart.name.EXPENSE_PERIOD_TOTALS_FOR_YEAR=Overview about the income and expenses for a configurable year (bar chart)
|
financer.chart.name.EXPENSE_PERIOD_TOTALS_FOR_YEAR=Overview about the income and expenses for a configurable year (bar chart)
|
||||||
|
|
||||||
|
financer.recurring-transaction-calendar.title=financer\: recurring transaction calendar
|
||||||
|
financer.calendar.calendarweek=CW
|
||||||
|
financer.calendar.weekdays.MONDAY=Monday
|
||||||
|
financer.calendar.weekdays.TUESDAY=Tuesday
|
||||||
|
financer.calendar.weekdays.WEDNESDAY=Wednesday
|
||||||
|
financer.calendar.weekdays.THURSDAY=Thursday
|
||||||
|
financer.calendar.weekdays.FRIDAY=Friday
|
||||||
|
financer.calendar.weekdays.SATURDAY=Saturday
|
||||||
|
financer.calendar.weekdays.SUNDAY=Sunday
|
||||||
|
financer.calendar.previous=Previous month
|
||||||
|
financer.calendar.next=Next month
|
||||||
|
financer.calendar.current=Current month
|
||||||
|
|
||||||
financer.error-message.UNKNOWN_ERROR=An unknown error occurred!
|
financer.error-message.UNKNOWN_ERROR=An unknown error occurred!
|
||||||
financer.error-message.INVALID_ACCOUNT_TYPE=The selected account type is not valid!
|
financer.error-message.INVALID_ACCOUNT_TYPE=The selected account type is not valid!
|
||||||
financer.error-message.FROM_ACCOUNT_NOT_FOUND=The specified from account has not been found!
|
financer.error-message.FROM_ACCOUNT_NOT_FOUND=The specified from account has not been found!
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ financer.account-overview.available-actions.recurring-transaction-all=Zeige alle
|
|||||||
financer.account-overview.available-actions.create-account-group=Neue Konto-Gruppe erstellen
|
financer.account-overview.available-actions.create-account-group=Neue Konto-Gruppe erstellen
|
||||||
financer.account-overview.available-actions.select-chart=Ein Diagramm erzeugen
|
financer.account-overview.available-actions.select-chart=Ein Diagramm erzeugen
|
||||||
financer.account-overview.available-actions.close-current-period=Aktuelle Periode schlie\u00DFen
|
financer.account-overview.available-actions.close-current-period=Aktuelle Periode schlie\u00DFen
|
||||||
|
financer.account-overview.available-actions.recurring-transaction-calendar=Kalender wiederkehrende Buchung
|
||||||
financer.account-overview.status=Status\:
|
financer.account-overview.status=Status\:
|
||||||
financer.account-overview.status.recurring-transaction-due-today=Wiederkehrende Buchungen heute f\u00E4llig\:
|
financer.account-overview.status.recurring-transaction-due-today=Wiederkehrende Buchungen heute f\u00E4llig\:
|
||||||
financer.account-overview.status.recurring-transaction-active=Aktive wiederkehrende Buchungen\:
|
financer.account-overview.status.recurring-transaction-active=Aktive wiederkehrende Buchungen\:
|
||||||
@@ -118,6 +119,7 @@ financer.transaction-list.table.recurring.yes=Ja
|
|||||||
financer.transaction-list.table.recurring.no=Nein
|
financer.transaction-list.table.recurring.no=Nein
|
||||||
financer.transaction-list.table.taxRelevant.true=Ja
|
financer.transaction-list.table.taxRelevant.true=Ja
|
||||||
financer.transaction-list.table.taxRelevant.false=Nein
|
financer.transaction-list.table.taxRelevant.false=Nein
|
||||||
|
financer.transaction-list.transaction-count={0} Buchungen gefunden
|
||||||
|
|
||||||
financer.recurring-to-transaction-with-amount.title=financer\: Buchung mit Betrag aus wiederkehrender Buchung erstellen
|
financer.recurring-to-transaction-with-amount.title=financer\: Buchung mit Betrag aus wiederkehrender Buchung erstellen
|
||||||
financer.recurring-to-transaction-with-amount.label.amount=Betrag\:
|
financer.recurring-to-transaction-with-amount.label.amount=Betrag\:
|
||||||
@@ -174,6 +176,7 @@ financer.interval-type.YEARLY=J\u00E4hrlich
|
|||||||
financer.holiday-weekend-type.SAME_DAY=Gleicher Tag
|
financer.holiday-weekend-type.SAME_DAY=Gleicher Tag
|
||||||
financer.holiday-weekend-type.NEXT_WORKDAY=N\u00E4chster Werktag
|
financer.holiday-weekend-type.NEXT_WORKDAY=N\u00E4chster Werktag
|
||||||
financer.holiday-weekend-type.PREVIOUS_WORKDAY=Vorheriger Werktag
|
financer.holiday-weekend-type.PREVIOUS_WORKDAY=Vorheriger Werktag
|
||||||
|
financer.holiday-weekend-type.SKIP=Einmalig \u00FCberspringen
|
||||||
|
|
||||||
financer.account-type.BANK=Bank
|
financer.account-type.BANK=Bank
|
||||||
financer.account-type.CASH=Bar
|
financer.account-type.CASH=Bar
|
||||||
@@ -198,8 +201,10 @@ financer.heading.recurring-to-transaction-with-amount=financer\: Buchung mit Bet
|
|||||||
financer.heading.chart-select=financer\: Ein Diagramm zum Erzeugen ausw\u00E4hlen
|
financer.heading.chart-select=financer\: Ein Diagramm zum Erzeugen ausw\u00E4hlen
|
||||||
financer.heading.chart-config-account-group-expenses-for-period=financer\: Konfigurieren von Ausgaben f\u00FCr Periode gruppiert nach Konto-Gruppe Diagramm
|
financer.heading.chart-config-account-group-expenses-for-period=financer\: Konfigurieren von Ausgaben f\u00FCr Periode gruppiert nach Konto-Gruppe Diagramm
|
||||||
financer.heading.search-transactions=financer\: Buchungen suchen
|
financer.heading.search-transactions=financer\: Buchungen suchen
|
||||||
|
financer.heading.recurring-transaction-calendar=financer\: Kalender wiederkehrende Buchung
|
||||||
|
|
||||||
financer.cancel-back-to-overview=Abbrechen und zur \u00DCbersicht
|
financer.cancel-back-to-overview=Abbrechen und zur\u00FCck zur \u00DCbersicht
|
||||||
|
financer.back-to-overview=Zur\u00FCck zur \u00DCbersicht
|
||||||
|
|
||||||
financer.chart.account-group-expenses-current-period.title=Ausgaben in der aktuellen Periode gruppiert nach Konto-Gruppe
|
financer.chart.account-group-expenses-current-period.title=Ausgaben in der aktuellen Periode gruppiert nach Konto-Gruppe
|
||||||
financer.chart.account-group-expenses-for-period.title=Ausgaben in der Periode vom {0} bis {1} gruppiert nach Konto-Gruppe
|
financer.chart.account-group-expenses-for-period.title=Ausgaben in der Periode vom {0} bis {1} gruppiert nach Konto-Gruppe
|
||||||
@@ -217,6 +222,19 @@ financer.chart.name.ACCOUNT_EXPENSES_FOR_PERIOD=Ausgaben f\u00FCr eine konfiguri
|
|||||||
financer.chart.name.EXPENSE_PERIOD_TOTALS_CURRENT_YEAR=\u00DCbersicht über das Einkommen und die Ausgaben im laufenden Jahr (Balkendiagramm)
|
financer.chart.name.EXPENSE_PERIOD_TOTALS_CURRENT_YEAR=\u00DCbersicht über das Einkommen und die Ausgaben im laufenden Jahr (Balkendiagramm)
|
||||||
financer.chart.name.EXPENSE_PERIOD_TOTALS_FOR_YEAR=\u00DCbersicht über das Einkommen und die Ausgaben für ein konfigurierbares Jahr (Balkendiagramm)
|
financer.chart.name.EXPENSE_PERIOD_TOTALS_FOR_YEAR=\u00DCbersicht über das Einkommen und die Ausgaben für ein konfigurierbares Jahr (Balkendiagramm)
|
||||||
|
|
||||||
|
financer.recurring-transaction-calendar.title=financer\: Kalender wiederkehrende Buchung
|
||||||
|
financer.calendar.calendarweek=KW
|
||||||
|
financer.calendar.weekdays.MONDAY=Montag
|
||||||
|
financer.calendar.weekdays.TUESDAY=Dienstag
|
||||||
|
financer.calendar.weekdays.WEDNESDAY=Mittwoch
|
||||||
|
financer.calendar.weekdays.THURSDAY=Donnerstag
|
||||||
|
financer.calendar.weekdays.FRIDAY=Freitag
|
||||||
|
financer.calendar.weekdays.SATURDAY=Samstag
|
||||||
|
financer.calendar.weekdays.SUNDAY=Sonntag
|
||||||
|
financer.calendar.previous=Letzter Monat
|
||||||
|
financer.calendar.next=N\u00E4chster Monat
|
||||||
|
financer.calendar.current=Aktueller Monat
|
||||||
|
|
||||||
financer.error-message.UNKNOWN_ERROR=Ein unbekannter Fehler ist aufgetreten!
|
financer.error-message.UNKNOWN_ERROR=Ein unbekannter Fehler ist aufgetreten!
|
||||||
financer.error-message.INVALID_ACCOUNT_TYPE=Der ausgew\u00E4hlte Kontotyp ist ung\u00FCltig!
|
financer.error-message.INVALID_ACCOUNT_TYPE=Der ausgew\u00E4hlte Kontotyp ist ung\u00FCltig!
|
||||||
financer.error-message.FROM_ACCOUNT_NOT_FOUND=Das ausgew\u00E4hlte Von-Konto wurde nicht gefunden!
|
financer.error-message.FROM_ACCOUNT_NOT_FOUND=Das ausgew\u00E4hlte Von-Konto wurde nicht gefunden!
|
||||||
|
|||||||
@@ -1,3 +1,10 @@
|
|||||||
|
v32 -> v33:
|
||||||
|
- Introduce Holiday/Weekend Type SKIP to skip an occurrence of a recurring transaction once, if the due date is either a
|
||||||
|
holiday or a weekend day
|
||||||
|
- Implement a calendar for recurring transactions
|
||||||
|
- Add result count to transaction search
|
||||||
|
- Fix a bug in the parsing of FQL
|
||||||
|
|
||||||
v31 -> v32:
|
v31 -> v32:
|
||||||
- Integrate new push-service release with VAPID support for Chrome based browsers
|
- Integrate new push-service release with VAPID support for Chrome based browsers
|
||||||
|
|
||||||
@@ -26,13 +33,13 @@ v26 -> v27:
|
|||||||
usage)
|
usage)
|
||||||
|
|
||||||
v25 -> v26:
|
v25 -> v26:
|
||||||
- Close of the current expense period now creates null statistic entries for accounts that have not been used in
|
- Closing the current expense period now creates null statistic entries for accounts that have not been used in
|
||||||
bookings in the period to close. This way the average spending better reflects the period average
|
bookings in the period to close. This way the average spending better reflects the period average
|
||||||
- Introduce period type GRAND TOTAL, that denotes a continuous, cumulative period, starting with the inception of the
|
- Introduce period type GRAND TOTAL, that denotes a continuous, cumulative period, starting with the inception of the
|
||||||
financer app, without an end
|
financer app, without an end
|
||||||
- Introduce period type EXPENSE YEAR, that acts as a group for all expense periods in a year. This may not be a
|
- Introduce period type EXPENSE YEAR, that acts as a group for all expense periods in a year. This may not be a
|
||||||
calendar year, if e.g. the EXPENSE periods do not start at the first of every month. This includes all periods that
|
calendar year, if e.g. the EXPENSE periods do not start at the first of every month. This includes all periods that
|
||||||
start the in the year. This is a preparation for extended reports and year-based booking
|
start in the year
|
||||||
- Transactions with a date in the past are now assigned to the proper EXPENSE and EXPENSE YEAR periods
|
- Transactions with a date in the past are now assigned to the proper EXPENSE and EXPENSE YEAR periods
|
||||||
- Add a fav icon
|
- Add a fav icon
|
||||||
|
|
||||||
@@ -80,4 +87,4 @@ v16 -> v17:
|
|||||||
- Add this changelog to the footer
|
- Add this changelog to the footer
|
||||||
- Locale of the recurring transaction reminder email is now configurable
|
- Locale of the recurring transaction reminder email is now configurable
|
||||||
- Recurring transaction indicator in transaction overview (account details) is now properly translated
|
- Recurring transaction indicator in transaction overview (account details) is now properly translated
|
||||||
- Add chart report to visualize the expenses of the current/a configurable period grouped by account
|
- Add chart report to visualize the expenses of the current/a configurable period grouped by account
|
||||||
|
|||||||
@@ -93,7 +93,8 @@ tr:hover {
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
#status-container > span, div {
|
#status-container > span,
|
||||||
|
#status-container > div {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,7 +136,8 @@ input[type=submit] {
|
|||||||
margin-top: 1em;
|
margin-top: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
#footer-container > hr, div {
|
#footer-container > hr,
|
||||||
|
#footer-container > div {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -203,4 +205,112 @@ input[type=submit] {
|
|||||||
|
|
||||||
#search-transactions-fql-detail > * {
|
#search-transactions-fql-detail > * {
|
||||||
font-size: 0.7em;
|
font-size: 0.7em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cal {
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 1.5em;
|
||||||
|
margin-bottom: 1.5em;
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cal th {
|
||||||
|
border-bottom: 1px solid #ddd;
|
||||||
|
border-right: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cal th:nth-last-child(1) {
|
||||||
|
border-right: 0px solid #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cal-control-con {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cal-control-con-table {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cal-control-con-table > tbody > tr > * {
|
||||||
|
width: 33%;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cal-control-con-table > tbody > tr:hover {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cal-day-previous {
|
||||||
|
background-color: #F0EEEE;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cal-day-con {
|
||||||
|
display: inline-block;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cal-week-row:hover {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cal-header-row:hover {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cal-calendarweek {
|
||||||
|
text-align: center;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cal-calendarweek-con-content {
|
||||||
|
margin-top: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cal-day-con-content-con-text {
|
||||||
|
margin-left: 0.5em;
|
||||||
|
margin-right: 0.5em;
|
||||||
|
margin-top: 0.3em;
|
||||||
|
margin-bottom: 0.3em;
|
||||||
|
background-color: #e9f9f9;
|
||||||
|
border: 1px;
|
||||||
|
border-style: solid;
|
||||||
|
border-color: #b9dFdF;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding-left: 1em;
|
||||||
|
padding-right: 1em;
|
||||||
|
color: #000000;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
#transaction-list-container-count-con-text {
|
||||||
|
margin-bottom: 0px;
|
||||||
|
margin-top: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#transaction-table {
|
||||||
|
margin-top: 0.2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cal-day-con-number-con-text {
|
||||||
|
margin: 0.5em;
|
||||||
|
color: #444242;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cal-day {
|
||||||
|
vertical-align: top;
|
||||||
|
border-bottom: 1px solid #ddd;
|
||||||
|
border-right: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cal-calendarweek {
|
||||||
|
border-right: 1px solid #ddd;
|
||||||
|
border-bottom: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cal-week-row td:nth-last-child(1) {
|
||||||
|
border-right: 0px solid #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cal-day-con-today {
|
||||||
|
background-color: #f5e5b8;
|
||||||
}
|
}
|
||||||
@@ -199,6 +199,4 @@
|
|||||||
====================
|
====================
|
||||||
This chapter lists planned features. The list is in no particular order:
|
This chapter lists planned features. The list is in no particular order:
|
||||||
- Transaction import from online banking (file based)
|
- Transaction import from online banking (file based)
|
||||||
- Extended reports, e.g. forecasting based on recurring transactions and average spending
|
- Extended reports, e.g. forecasting based on recurring transactions and average spending
|
||||||
- Receivable account type
|
|
||||||
- Edit masks for accounts, transactions, recurring transactions
|
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div id="balance-container">
|
<div id="balance-container">
|
||||||
<span th:text="#{financer.account-details.details.balance}"/>
|
<span th:text="#{financer.account-details.details.balance}"/>
|
||||||
<span th:text="${#numbers.formatDecimal(account.currentBalance/100D, 1, 'DEFAULT', 2, 'DEFAULT') + currencySymbol}"/>
|
<span th:utext="${#numbers.formatDecimal(account.currentBalance/100D, 1, 'DEFAULT', 2, 'DEFAULT') + currencySymbol}"/>
|
||||||
</div>
|
</div>
|
||||||
<div id="group-container" th:if="${account.accountGroup != null}">
|
<div id="group-container" th:if="${account.accountGroup != null}">
|
||||||
<span th:text="#{financer.account-details.details.group}"/>
|
<span th:text="#{financer.account-details.details.group}"/>
|
||||||
|
|||||||
@@ -17,12 +17,12 @@
|
|||||||
<span th:text="#{financer.account-overview.status}"/>
|
<span th:text="#{financer.account-overview.status}"/>
|
||||||
<div th:title="#{financer.account-overview.tooltip.status.current-assets}">
|
<div th:title="#{financer.account-overview.tooltip.status.current-assets}">
|
||||||
<span th:text="#{financer.account-overview.status.current-assets}"/>
|
<span th:text="#{financer.account-overview.status.current-assets}"/>
|
||||||
<span th:text="${#numbers.formatDecimal(currentAssets/100D, 1, 'DEFAULT', 2, 'DEFAULT') + currencySymbol}"/>
|
<span th:utext="${#numbers.formatDecimal(currentAssets/100D, 1, 'DEFAULT', 2, 'DEFAULT') + currencySymbol}"/>
|
||||||
</div>
|
</div>
|
||||||
<div th:title="#{'financer.account-overview.tooltip.status.current-expenses'(${#temporals.format(periodStart)})}">
|
<div th:title="#{'financer.account-overview.tooltip.status.current-expenses'(${#temporals.format(periodStart)})}">
|
||||||
<span th:text="#{financer.account-overview.status.current-expenses}"/>
|
<span th:text="#{financer.account-overview.status.current-expenses}"/>
|
||||||
<a th:href="@{/getAccountGroupExpensesCurrentPeriod}">
|
<a th:href="@{/getAccountGroupExpensesCurrentPeriod}">
|
||||||
<span th:text="${#numbers.formatDecimal(currentExpenses/100D, 1, 'DEFAULT', 2, 'DEFAULT') + currencySymbol}" />
|
<span th:utext="${#numbers.formatDecimal(currentExpenses/100D, 1, 'DEFAULT', 2, 'DEFAULT') + currencySymbol}" />
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
@@ -58,6 +58,8 @@
|
|||||||
th:text="#{financer.account-overview.available-actions.create-recurring-transaction}"/>
|
th:text="#{financer.account-overview.available-actions.create-recurring-transaction}"/>
|
||||||
<a th:href="@{/recurringTransactionAll}"
|
<a th:href="@{/recurringTransactionAll}"
|
||||||
th:text="#{financer.account-overview.available-actions.recurring-transaction-all}"/>
|
th:text="#{financer.account-overview.available-actions.recurring-transaction-all}"/>
|
||||||
|
<a th:href="@{'/recurringTransactionCalendar?offset=0'}"
|
||||||
|
th:text="#{financer.account-overview.available-actions.recurring-transaction-calendar}"/>
|
||||||
</div>
|
</div>
|
||||||
<div id="action-container-sub-period">
|
<div id="action-container-sub-period">
|
||||||
<a th:href="@{/closePeriod}"
|
<a th:href="@{/closePeriod}"
|
||||||
@@ -91,14 +93,14 @@
|
|||||||
<td>
|
<td>
|
||||||
<a th:href="@{/accountDetails(key=${acc.key})}" th:text="${acc.key}"/>
|
<a th:href="@{/accountDetails(key=${acc.key})}" th:text="${acc.key}"/>
|
||||||
</td>
|
</td>
|
||||||
<td th:text="${#numbers.formatDecimal(acc.currentBalance/100D, 1, 'DEFAULT', 2, 'DEFAULT') + currencySymbol}"/>
|
<td th:utext="${#numbers.formatDecimal(acc.currentBalance/100D, 1, 'DEFAULT', 2, 'DEFAULT') + currencySymbol}"/>
|
||||||
<td class="hideable-column"
|
<td class="hideable-column"
|
||||||
th:if="${acc.spendingCurrentExpensePeriod != null}"
|
th:if="${acc.spendingCurrentExpensePeriod != null}"
|
||||||
th:text="${#numbers.formatDecimal(acc.spendingCurrentExpensePeriod/100D, 1, 'DEFAULT', 2, 'DEFAULT') + currencySymbol}"
|
th:utext="${#numbers.formatDecimal(acc.spendingCurrentExpensePeriod/100D, 1, 'DEFAULT', 2, 'DEFAULT') + currencySymbol}"
|
||||||
th:classappend="${acc.spendingCurrentExpensePeriod > acc.averageSpendingExpensePeriod} ? overspend"/>
|
th:classappend="${acc.spendingCurrentExpensePeriod > acc.averageSpendingExpensePeriod} ? overspend"/>
|
||||||
<td class="hideable-column"
|
<td class="hideable-column"
|
||||||
th:if="${acc.averageSpendingExpensePeriod != null}"
|
th:if="${acc.averageSpendingExpensePeriod != null}"
|
||||||
th:text="${#numbers.formatDecimal(acc.averageSpendingExpensePeriod/100D, 1, 'DEFAULT', 2, 'DEFAULT') + currencySymbol}"/>
|
th:utext="${#numbers.formatDecimal(acc.averageSpendingExpensePeriod/100D, 1, 'DEFAULT', 2, 'DEFAULT') + currencySymbol}"/>
|
||||||
<td class="hideable-column" th:if="${acc.spendingCurrentExpensePeriod == null}">-</td>
|
<td class="hideable-column" th:if="${acc.spendingCurrentExpensePeriod == null}">-</td>
|
||||||
<td class="hideable-column" th:if="${acc.averageSpendingExpensePeriod == null}">-</td>
|
<td class="hideable-column" th:if="${acc.averageSpendingExpensePeriod == null}">-</td>
|
||||||
<td class="hideable-column" th:text="${acc.accountGroup?.name}"/>
|
<td class="hideable-column" th:text="${acc.accountGroup?.name}"/>
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html xmlns:th="http://www.thymeleaf.org">
|
||||||
|
<head>
|
||||||
|
<title th:text="#{financer.recurring-transaction-calendar.title}"/>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<link rel="stylesheet" th:href="@{/css/main.css}">
|
||||||
|
<link rel="shortcut icon" th:href="@{/favicon.ico}"/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1 th:text="#{financer.heading.recurring-transaction-calendar} + ' — ' + ${#temporals.monthName(today)} + ' ' + ${#temporals.year(today)}"/>
|
||||||
|
<span class="errorMessage" th:if="${errorMessage != null}" th:text="#{'financer.error-message.' + ${errorMessage}}"/>
|
||||||
|
<a th:href="@{/accountOverview}" th:text="#{financer.back-to-overview}"/>
|
||||||
|
<div id="calendar-container" th:fragment="recurring-transaction-calendar">
|
||||||
|
<table id="cal">
|
||||||
|
<tr id="cal-header-row">
|
||||||
|
<th class="header-col" th:text="#{'financer.calendar.calendarweek'}"/>
|
||||||
|
<th class="header-col" th:text="#{'financer.calendar.weekdays.' + ${firstWeekDay}}"/>
|
||||||
|
<th class="header-col" th:text="#{'financer.calendar.weekdays.' + ${secondWeekDay}}"/>
|
||||||
|
<th class="header-col" th:text="#{'financer.calendar.weekdays.' + ${thirdWeekDay}}"/>
|
||||||
|
<th class="header-col" th:text="#{'financer.calendar.weekdays.' + ${fourthWeekDay}}"/>
|
||||||
|
<th class="header-col" th:text="#{'financer.calendar.weekdays.' + ${fifthWeekDay}}"/>
|
||||||
|
<th class="header-col" th:text="#{'financer.calendar.weekdays.' + ${sixthWeekDay}}"/>
|
||||||
|
<th class="header-col" th:text="#{'financer.calendar.weekdays.' + ${seventhWeekDay}}"/>
|
||||||
|
</tr>
|
||||||
|
<tr class="cal-week-row" th:each="week : ${weeks}">
|
||||||
|
<td class="cal-calendarweek">
|
||||||
|
<div class="cal-calendarweek-con">
|
||||||
|
<p class="cal-calendarweek-con-content" th:text="${week.weekNumber}"/>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td th:class="${day.isPreviousOrNextMonth(offset) ? 'cal-day-previous cal-day' : 'cal-day'}" th:each="day : ${week.days}">
|
||||||
|
<div th:class="${day.today ? 'cal-day-con cal-day-con-today' : 'cal-day-con'}">
|
||||||
|
<div class="cal-day-con-number-con">
|
||||||
|
<p class="cal-day-con-number-con-text" th:text="${day.day}"/>
|
||||||
|
</div>
|
||||||
|
<div th:if="${!day.isPreviousOrNextMonth(offset)}" class="cal-day-con-content">
|
||||||
|
<div class="cal-day-con-content-con" th:each="transaction : ${day.transactions}">
|
||||||
|
<p class="cal-day-con-content-con-text" th:utext="${transaction.description + ' — ' + #numbers.formatDecimal(transaction.amount/100D, 1, 'DEFAULT', 2, 'DEFAULT') + currencySymbol}" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</table>
|
||||||
|
<div id="cal-control-con">
|
||||||
|
<table id="cal-control-con-table">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<a id="cal-control-con-prev" th:href="@{'/recurringTransactionCalendar?offset=' + ${offset-1} + ''}" th:text="#{financer.calendar.previous}" />
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a id="cal-control-con-curr" th:href="@{'/recurringTransactionCalendar?offset=0'}" th:text="#{financer.calendar.current}" />
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a id="cal-control-con-next" th:href="@{'/recurringTransactionCalendar?offset=' + ${offset+1} + ''}" th:text="#{financer.calendar.next}" />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div th:replace="includes/footer :: footer"/>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -16,12 +16,12 @@
|
|||||||
<label for="selectFromAccount" th:text="#{financer.recurring-transaction-new.label.from-account}"/>
|
<label for="selectFromAccount" th:text="#{financer.recurring-transaction-new.label.from-account}"/>
|
||||||
<select id="selectFromAccount" th:field="*{fromAccountKey}">
|
<select id="selectFromAccount" th:field="*{fromAccountKey}">
|
||||||
<option th:each="acc : ${fromAccounts}" th:value="${acc.key}"
|
<option th:each="acc : ${fromAccounts}" th:value="${acc.key}"
|
||||||
th:text="#{'financer.recurring-transaction-new.account-type.' + ${acc.type}(${acc.key},${#numbers.formatDecimal(acc.currentBalance/100D, 1, 'DEFAULT', 2, 'DEFAULT')},${currencySymbol})}"/>
|
th:utext="#{'financer.recurring-transaction-new.account-type.' + ${acc.type}(${acc.key},${#numbers.formatDecimal(acc.currentBalance/100D, 1, 'DEFAULT', 2, 'DEFAULT')},${currencySymbol})}"/>
|
||||||
</select>
|
</select>
|
||||||
<label for="selectToAccount" th:text="#{financer.recurring-transaction-new.label.to-account}"/>
|
<label for="selectToAccount" th:text="#{financer.recurring-transaction-new.label.to-account}"/>
|
||||||
<select id="selectToAccount" th:field="*{toAccountKey}">
|
<select id="selectToAccount" th:field="*{toAccountKey}">
|
||||||
<option th:each="acc : ${toAccounts}" th:value="${acc.key}"
|
<option th:each="acc : ${toAccounts}" th:value="${acc.key}"
|
||||||
th:text="#{'financer.recurring-transaction-new.account-type.' + ${acc.type}(${acc.key},${#numbers.formatDecimal(acc.currentBalance/100D, 1, 'DEFAULT', 2, 'DEFAULT')},${currencySymbol})}"/>
|
th:utext="#{'financer.recurring-transaction-new.account-type.' + ${acc.type}(${acc.key},${#numbers.formatDecimal(acc.currentBalance/100D, 1, 'DEFAULT', 2, 'DEFAULT')},${currencySymbol})}"/>
|
||||||
</select>
|
</select>
|
||||||
<label for="inputAmount" th:text="#{financer.recurring-transaction-new.label.amount}"/>
|
<label for="inputAmount" th:text="#{financer.recurring-transaction-new.label.amount}"/>
|
||||||
<input type="text" id="inputAmount" th:field="*{amount}"/>
|
<input type="text" id="inputAmount" th:field="*{amount}"/>
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
</td>
|
</td>
|
||||||
<td th:text="${#temporals.format(rt.firstOccurrence)}"/>
|
<td th:text="${#temporals.format(rt.firstOccurrence)}"/>
|
||||||
<td th:text="${#temporals.format(rt.lastOccurrence)}"/>
|
<td th:text="${#temporals.format(rt.lastOccurrence)}"/>
|
||||||
<td th:text="${#numbers.formatDecimal(rt.amount/100D, 1, 'DEFAULT', 2, 'DEFAULT') + currencySymbol}"/>
|
<td th:utext="${#numbers.formatDecimal(rt.amount/100D, 1, 'DEFAULT', 2, 'DEFAULT') + currencySymbol}"/>
|
||||||
<td th:text="${rt.description}"/>
|
<td th:text="${rt.description}"/>
|
||||||
<td th:text="#{'financer.interval-type.' + ${rt.intervalType}}"/>
|
<td th:text="#{'financer.interval-type.' + ${rt.intervalType}}"/>
|
||||||
<td th:text="#{'financer.holiday-weekend-type.' + ${rt.holidayWeekendType}}"/>
|
<td th:text="#{'financer.holiday-weekend-type.' + ${rt.holidayWeekendType}}"/>
|
||||||
|
|||||||
@@ -16,12 +16,12 @@
|
|||||||
<label for="selectFromAccount" th:text="#{financer.transaction-new.label.from-account}"/>
|
<label for="selectFromAccount" th:text="#{financer.transaction-new.label.from-account}"/>
|
||||||
<select id="selectFromAccount" th:field="*{fromAccountKey}">
|
<select id="selectFromAccount" th:field="*{fromAccountKey}">
|
||||||
<option th:each="acc : ${fromAccounts}" th:value="${acc.key}"
|
<option th:each="acc : ${fromAccounts}" th:value="${acc.key}"
|
||||||
th:text="#{'financer.transaction-new.account-type.' + ${acc.type}(${acc.key},${#numbers.formatDecimal(acc.currentBalance/100D, 1, 'DEFAULT', 2, 'DEFAULT')},${currencySymbol})}"/>
|
th:utext="#{'financer.transaction-new.account-type.' + ${acc.type}(${acc.key},${#numbers.formatDecimal(acc.currentBalance/100D, 1, 'DEFAULT', 2, 'DEFAULT')},${currencySymbol})}"/>
|
||||||
</select>
|
</select>
|
||||||
<label for="selectToAccount" th:text="#{financer.transaction-new.label.to-account}"/>
|
<label for="selectToAccount" th:text="#{financer.transaction-new.label.to-account}"/>
|
||||||
<select id="selectToAccount" th:field="*{toAccountKey}">
|
<select id="selectToAccount" th:field="*{toAccountKey}">
|
||||||
<option th:each="acc : ${toAccounts}" th:value="${acc.key}"
|
<option th:each="acc : ${toAccounts}" th:value="${acc.key}"
|
||||||
th:text="#{'financer.transaction-new.account-type.' + ${acc.type}(${acc.key},${#numbers.formatDecimal(acc.currentBalance/100D, 1, 'DEFAULT', 2, 'DEFAULT')},${currencySymbol})}"/>
|
th:utext="#{'financer.transaction-new.account-type.' + ${acc.type}(${acc.key},${#numbers.formatDecimal(acc.currentBalance/100D, 1, 'DEFAULT', 2, 'DEFAULT')},${currencySymbol})}"/>
|
||||||
</select>
|
</select>
|
||||||
<label for="inputAmount" th:text="#{financer.transaction-new.label.amount}"/>
|
<label for="inputAmount" th:text="#{financer.transaction-new.label.amount}"/>
|
||||||
<input type="text" id="inputAmount" th:field="*{amount}"/>
|
<input type="text" id="inputAmount" th:field="*{amount}"/>
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
<div id="transaction-list-container" th:fragment="transaction-list">
|
<div id="transaction-list-container" th:fragment="transaction-list">
|
||||||
|
<div id="transaction-list-container-count-con" th:if="${transactionCount != null}">
|
||||||
|
<p id="transaction-list-container-count-con-text" th:text="#{'financer.transaction-list.transaction-count'(${transactionCount})}"/>
|
||||||
|
</div>
|
||||||
<table id="transaction-table">
|
<table id="transaction-table">
|
||||||
<tr>
|
<tr>
|
||||||
<th class="hideable-column" th:text="#{financer.transaction-list.table-header.id}"/>
|
<th class="hideable-column" th:text="#{financer.transaction-list.table-header.id}"/>
|
||||||
@@ -16,7 +19,7 @@
|
|||||||
<td th:text="${transaction.fromAccount.key}" />
|
<td th:text="${transaction.fromAccount.key}" />
|
||||||
<td th:text="${transaction.toAccount.key}" />
|
<td th:text="${transaction.toAccount.key}" />
|
||||||
<td th:text="${#temporals.format(transaction.date)}" />
|
<td th:text="${#temporals.format(transaction.date)}" />
|
||||||
<td th:text="${#numbers.formatDecimal(transaction.amount/100D, 1, 'DEFAULT', 2, 'DEFAULT') + currencySymbol}"/>
|
<td th:utext="${#numbers.formatDecimal(transaction.amount/100D, 1, 'DEFAULT', 2, 'DEFAULT') + currencySymbol}"/>
|
||||||
<td th:text="${transaction.description}" />
|
<td th:text="${transaction.description}" />
|
||||||
<td th:if="${transaction.recurring}" th:text="#{financer.transaction-list.table.recurring.yes}" />
|
<td th:if="${transaction.recurring}" th:text="#{financer.transaction-list.table.recurring.yes}" />
|
||||||
<td th:if="${!transaction.recurring}" th:text="#{financer.transaction-list.table.recurring.no}" />
|
<td th:if="${!transaction.recurring}" th:text="#{financer.transaction-list.table.recurring.no}" />
|
||||||
|
|||||||
32
pom.xml
32
pom.xml
@@ -30,8 +30,6 @@
|
|||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
<module>financer-server</module>
|
|
||||||
<module>financer-web-client</module>
|
|
||||||
<module>financer-common</module>
|
<module>financer-common</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
@@ -90,7 +88,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>de.77zzcx7.push-service</groupId>
|
<groupId>de.77zzcx7.push-service</groupId>
|
||||||
<artifactId>push-service-client-lib</artifactId>
|
<artifactId>push-service-client-lib</artifactId>
|
||||||
<version>3</version>
|
<version>4-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</dependencyManagement>
|
</dependencyManagement>
|
||||||
@@ -122,5 +120,33 @@
|
|||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
</profile>
|
</profile>
|
||||||
|
|
||||||
|
<profile>
|
||||||
|
<id>all</id>
|
||||||
|
<modules>
|
||||||
|
<module>financer-common</module>
|
||||||
|
<module>financer-server</module>
|
||||||
|
<module>financer-web-client</module>
|
||||||
|
</modules>
|
||||||
|
<activation>
|
||||||
|
<activeByDefault>true</activeByDefault>
|
||||||
|
</activation>
|
||||||
|
</profile>
|
||||||
|
|
||||||
|
<profile>
|
||||||
|
<id>web-client</id>
|
||||||
|
<modules>
|
||||||
|
<module>financer-common</module>
|
||||||
|
<module>financer-web-client</module>
|
||||||
|
</modules>
|
||||||
|
</profile>
|
||||||
|
|
||||||
|
<profile>
|
||||||
|
<id>server</id>
|
||||||
|
<modules>
|
||||||
|
<module>financer-common</module>
|
||||||
|
<module>financer-server</module>
|
||||||
|
</modules>
|
||||||
|
</profile>
|
||||||
</profiles>
|
</profiles>
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
Reference in New Issue
Block a user