Add basic logging
Add basic logging of exceptions, warnings, info and debug statements. The implementation used is Logback.
This commit is contained in:
@@ -1,6 +1,8 @@
|
|||||||
package de.financer.config;
|
package de.financer.config;
|
||||||
|
|
||||||
import de.jollyday.HolidayCalendar;
|
import de.jollyday.HolidayCalendar;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
@@ -12,6 +14,8 @@ import java.util.Optional;
|
|||||||
@Configuration
|
@Configuration
|
||||||
@ConfigurationProperties(prefix = "financer")
|
@ConfigurationProperties(prefix = "financer")
|
||||||
public class FinancerConfig {
|
public class FinancerConfig {
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(FinancerConfig.class);
|
||||||
|
|
||||||
private String countryCode;
|
private String countryCode;
|
||||||
private String state;
|
private String state;
|
||||||
private String dateFormat;
|
private String dateFormat;
|
||||||
@@ -33,8 +37,8 @@ public class FinancerConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the {@link HolidayCalendar} used to calculate the holidays. Internally uses the country code
|
* @return the {@link HolidayCalendar} used to calculate the holidays. Internally uses the country code specified
|
||||||
* specified via {@link FinancerConfig#getCountryCode}.
|
* via {@link FinancerConfig#getCountryCode}.
|
||||||
*/
|
*/
|
||||||
public HolidayCalendar getHolidayCalendar() {
|
public HolidayCalendar getHolidayCalendar() {
|
||||||
final Optional<HolidayCalendar> optionalHoliday = Arrays.asList(HolidayCalendar.values()).stream()
|
final Optional<HolidayCalendar> optionalHoliday = Arrays.asList(HolidayCalendar.values()).stream()
|
||||||
@@ -42,7 +46,10 @@ public class FinancerConfig {
|
|||||||
.findFirst();
|
.findFirst();
|
||||||
|
|
||||||
if (!optionalHoliday.isPresent()) {
|
if (!optionalHoliday.isPresent()) {
|
||||||
// TODO log info about default DE
|
LOGGER.warn(String
|
||||||
|
.format("Use Germany as fallback country for holiday calculations. Configured country code is: %s. " +
|
||||||
|
"This does not match any valid country code as specified by Jollyday",
|
||||||
|
this.countryCode));
|
||||||
}
|
}
|
||||||
|
|
||||||
return optionalHoliday.orElse(HolidayCalendar.GERMANY);
|
return optionalHoliday.orElse(HolidayCalendar.GERMANY);
|
||||||
@@ -57,12 +64,11 @@ public class FinancerConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the date format used in e.g. the
|
* @return the date format used in e.g. the {@link de.financer.service.TransactionService#createTransaction(String,
|
||||||
* {@link de.financer.service.TransactionService#createTransaction(String, String, Long, String, String)
|
* String, Long, String, String) TransactionService#createTransaction} or {@link
|
||||||
* TransactionService#createTransaction} or
|
* de.financer.service.RecurringTransactionService#createRecurringTransaction(String, String, Long, String, String,
|
||||||
* {@link de.financer.service.RecurringTransactionService#createRecurringTransaction(String, String, Long, String,
|
* String, String, String) RecurringTransactionService#createRecurringTransaction} methods. Used to parse the
|
||||||
* String, String, String, String) RecurringTransactionService#createRecurringTransaction} methods. Used to parse
|
* client-supplied date string to proper {@link java.time.LocalDate LocalDate} objects
|
||||||
* the client-supplied date string to proper {@link java.time.LocalDate LocalDate} objects
|
|
||||||
*/
|
*/
|
||||||
public String getDateFormat() {
|
public String getDateFormat() {
|
||||||
return dateFormat;
|
return dateFormat;
|
||||||
@@ -71,9 +77,10 @@ public class FinancerConfig {
|
|||||||
public void setDateFormat(String dateFormat) {
|
public void setDateFormat(String dateFormat) {
|
||||||
try {
|
try {
|
||||||
DateTimeFormatter.ofPattern(dateFormat);
|
DateTimeFormatter.ofPattern(dateFormat);
|
||||||
}
|
} catch (IllegalArgumentException e) {
|
||||||
catch (IllegalArgumentException e) {
|
LOGGER.warn(String
|
||||||
// TODO log info about default dd.MM.yyyy
|
.format("Use 'dd.MM.yyyy' as fallback for the date format because the configured format '%s' " +
|
||||||
|
"cannot be parsed!", dateFormat), e);
|
||||||
|
|
||||||
dateFormat = "dd.MM.yyyy";
|
dateFormat = "dd.MM.yyyy";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
package de.financer.controller;
|
package de.financer.controller;
|
||||||
|
|
||||||
|
import de.financer.ResponseReason;
|
||||||
import de.financer.model.Account;
|
import de.financer.model.Account;
|
||||||
import de.financer.service.AccountService;
|
import de.financer.service.AccountService;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
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.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
@@ -11,6 +14,8 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
@RequestMapping("accounts")
|
@RequestMapping("accounts")
|
||||||
public class AccountController {
|
public class AccountController {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(AccountController.class);
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private AccountService accountService;
|
private AccountService accountService;
|
||||||
|
|
||||||
@@ -36,6 +41,16 @@ public class AccountController {
|
|||||||
|
|
||||||
@RequestMapping("createAccount")
|
@RequestMapping("createAccount")
|
||||||
public ResponseEntity createAccount(String key, String type) {
|
public ResponseEntity createAccount(String key, String type) {
|
||||||
return this.accountService.createAccount(key, type).toResponseEntity();
|
if (LOGGER.isDebugEnabled()) {
|
||||||
|
LOGGER.debug(String.format("/accounts/createAccount got parameters: %s, %s", key, type));
|
||||||
|
}
|
||||||
|
|
||||||
|
final ResponseReason responseReason = this.accountService.createAccount(key, type);
|
||||||
|
|
||||||
|
if (LOGGER.isDebugEnabled()) {
|
||||||
|
LOGGER.debug(String.format("/accounts/createAccount returns with %s", responseReason.name()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return responseReason.toResponseEntity();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
package de.financer.controller;
|
package de.financer.controller;
|
||||||
|
|
||||||
|
import de.financer.ResponseReason;
|
||||||
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.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.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
@@ -13,6 +16,8 @@ import java.util.Optional;
|
|||||||
@RequestMapping("recurringTransactions")
|
@RequestMapping("recurringTransactions")
|
||||||
public class RecurringTransactionController {
|
public class RecurringTransactionController {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(RecurringTransactionController.class);
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private RecurringTransactionService recurringTransactionService;
|
private RecurringTransactionService recurringTransactionService;
|
||||||
|
|
||||||
@@ -35,17 +40,44 @@ public class RecurringTransactionController {
|
|||||||
public ResponseEntity createRecurringTransaction(String fromAccountKey, String toAccountKey, Long amount,
|
public ResponseEntity createRecurringTransaction(String fromAccountKey, String toAccountKey, Long amount,
|
||||||
String description, String holidayWeekendType,
|
String description, String holidayWeekendType,
|
||||||
String intervalType, String firstOccurrence,
|
String intervalType, String firstOccurrence,
|
||||||
String lastOccurrence) {
|
String lastOccurrence
|
||||||
return this.recurringTransactionService.createRecurringTransaction(fromAccountKey, toAccountKey, amount,
|
) {
|
||||||
description, holidayWeekendType,
|
if (LOGGER.isDebugEnabled()) {
|
||||||
intervalType, firstOccurrence,
|
LOGGER.debug(String
|
||||||
lastOccurrence)
|
.format("/recurringTransactions/createRecurringTransaction got parameters: %s, %s, %s, %s, %s, " +
|
||||||
.toResponseEntity();
|
"%s, %s, %s", fromAccountKey, toAccountKey, amount, description, holidayWeekendType,
|
||||||
|
intervalType, firstOccurrence, lastOccurrence));
|
||||||
|
}
|
||||||
|
|
||||||
|
final ResponseReason responseReason = this.recurringTransactionService
|
||||||
|
.createRecurringTransaction(fromAccountKey, toAccountKey, amount, description, holidayWeekendType,
|
||||||
|
intervalType, firstOccurrence, lastOccurrence);
|
||||||
|
|
||||||
|
if (LOGGER.isDebugEnabled()) {
|
||||||
|
LOGGER.debug(String
|
||||||
|
.format("/recurringTransactions/createRecurringTransaction returns with %s", responseReason
|
||||||
|
.name()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return responseReason.toResponseEntity();
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping("createTransaction")
|
@RequestMapping("createTransaction")
|
||||||
public ResponseEntity createTransaction(String recurringTransactionId, Long amount) {
|
public ResponseEntity createTransaction(String recurringTransactionId, Long amount) {
|
||||||
return this.recurringTransactionService.createTransaction(recurringTransactionId, Optional.ofNullable(amount))
|
if (LOGGER.isDebugEnabled()) {
|
||||||
.toResponseEntity();
|
LOGGER.debug(String
|
||||||
|
.format("/recurringTransactions/createTransaction got parameters: %s, %s",
|
||||||
|
recurringTransactionId, amount));
|
||||||
|
}
|
||||||
|
|
||||||
|
final ResponseReason responseReason = this.recurringTransactionService
|
||||||
|
.createTransaction(recurringTransactionId, Optional.ofNullable(amount));
|
||||||
|
|
||||||
|
if (LOGGER.isDebugEnabled()) {
|
||||||
|
LOGGER.debug(String
|
||||||
|
.format("/recurringTransactions/createTransaction returns with %s", responseReason.name()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return responseReason.toResponseEntity();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
package de.financer.controller;
|
package de.financer.controller;
|
||||||
|
|
||||||
|
import de.financer.ResponseReason;
|
||||||
import de.financer.model.Transaction;
|
import de.financer.model.Transaction;
|
||||||
import de.financer.service.TransactionService;
|
import de.financer.service.TransactionService;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
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.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
@@ -10,6 +13,8 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("transactions")
|
@RequestMapping("transactions")
|
||||||
public class TransactionController {
|
public class TransactionController {
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(TransactionController.class);
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private TransactionService transactionService;
|
private TransactionService transactionService;
|
||||||
|
|
||||||
@@ -25,8 +30,21 @@ public class TransactionController {
|
|||||||
|
|
||||||
@RequestMapping(value = "createTransaction")
|
@RequestMapping(value = "createTransaction")
|
||||||
public ResponseEntity createTransaction(String fromAccountKey, String toAccountKey, Long amount, String date,
|
public ResponseEntity createTransaction(String fromAccountKey, String toAccountKey, Long amount, String date,
|
||||||
String description) {
|
String description
|
||||||
return this.transactionService.createTransaction(fromAccountKey, toAccountKey, amount, date, description)
|
) {
|
||||||
.toResponseEntity();
|
if (LOGGER.isDebugEnabled()) {
|
||||||
|
LOGGER.debug(String
|
||||||
|
.format("/transactions/createTransaction got parameters: %s, %s, %s, %s, %s",
|
||||||
|
fromAccountKey, toAccountKey, amount, date, description));
|
||||||
|
}
|
||||||
|
|
||||||
|
final ResponseReason responseReason = this.transactionService
|
||||||
|
.createTransaction(fromAccountKey, toAccountKey, amount, date, description);
|
||||||
|
|
||||||
|
if (LOGGER.isDebugEnabled()) {
|
||||||
|
LOGGER.debug(String.format("/transactions/createTransaction returns with %s", responseReason.name()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return responseReason.toResponseEntity();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ import de.financer.model.Account;
|
|||||||
import de.financer.model.AccountStatus;
|
import de.financer.model.AccountStatus;
|
||||||
import de.financer.model.AccountType;
|
import de.financer.model.AccountType;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Propagation;
|
import org.springframework.transaction.annotation.Propagation;
|
||||||
@@ -16,6 +18,8 @@ import java.util.stream.Collectors;
|
|||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class AccountService {
|
public class AccountService {
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(AccountService.class);
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private AccountRepository accountRepository;
|
private AccountRepository accountRepository;
|
||||||
|
|
||||||
@@ -95,7 +99,8 @@ public class AccountService {
|
|||||||
this.accountRepository.save(account);
|
this.accountRepository.save(account);
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
// TODO log and check for unique constraint exception so we can return a more specific error
|
LOGGER.error(String.format("Could not save account %s|%s", key, type), e);
|
||||||
|
|
||||||
return ResponseReason.UNKNOWN_ERROR;
|
return ResponseReason.UNKNOWN_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ import de.financer.model.RecurringTransaction;
|
|||||||
import org.apache.commons.collections4.IterableUtils;
|
import org.apache.commons.collections4.IterableUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.commons.lang3.math.NumberUtils;
|
import org.apache.commons.lang3.math.NumberUtils;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Propagation;
|
import org.springframework.transaction.annotation.Propagation;
|
||||||
@@ -24,6 +26,7 @@ import java.util.stream.Collectors;
|
|||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class RecurringTransactionService {
|
public class RecurringTransactionService {
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(RecurringTransactionService.class);
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private RecurringTransactionRepository recurringTransactionRepository;
|
private RecurringTransactionRepository recurringTransactionRepository;
|
||||||
@@ -48,6 +51,8 @@ public class RecurringTransactionService {
|
|||||||
final Account account = this.accountService.getAccountByKey(accountKey);
|
final Account account = this.accountService.getAccountByKey(accountKey);
|
||||||
|
|
||||||
if (account == null) {
|
if (account == null) {
|
||||||
|
LOGGER.warn(String.format("Account with key %s not found!", accountKey));
|
||||||
|
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,8 +255,7 @@ public class RecurringTransactionService {
|
|||||||
|
|
||||||
response = ResponseReason.OK;
|
response = ResponseReason.OK;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// TODO log
|
LOGGER.error("Could not create recurring transaction!", e);
|
||||||
e.printStackTrace();
|
|
||||||
|
|
||||||
response = ResponseReason.UNKNOWN_ERROR;
|
response = ResponseReason.UNKNOWN_ERROR;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ import de.financer.model.AccountType;
|
|||||||
import de.financer.model.IntervalType;
|
import de.financer.model.IntervalType;
|
||||||
import de.jollyday.HolidayManager;
|
import de.jollyday.HolidayManager;
|
||||||
import de.jollyday.ManagerParameters;
|
import de.jollyday.ManagerParameters;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
@@ -18,13 +20,12 @@ import java.util.*;
|
|||||||
import static de.financer.model.AccountType.*;
|
import static de.financer.model.AccountType.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This service encapsulates methods that form basic logic rules.
|
* This service encapsulates methods that form basic logic rules. While most of the logic could be placed elsewhere this
|
||||||
* While most of the logic could be placed elsewhere this service provides
|
* service provides centralized access to these rules. Placing them in here also enables easy unit testing.
|
||||||
* centralized access to these rules. Placing them in here also enables easy
|
|
||||||
* unit testing.
|
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
public class RuleService implements InitializingBean {
|
public class RuleService implements InitializingBean {
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(RuleService.class);
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private FinancerConfig financerConfig;
|
private FinancerConfig financerConfig;
|
||||||
@@ -65,10 +66,11 @@ public class RuleService implements InitializingBean {
|
|||||||
/**
|
/**
|
||||||
* This method returns the multiplier for the given from account.
|
* This method returns the multiplier for the given from account.
|
||||||
* <p>
|
* <p>
|
||||||
* The multiplier controls whether the current amount of the given from account is increased or
|
* The multiplier controls whether the current amount of the given from account is increased or decreased depending
|
||||||
* decreased depending on the {@link AccountType} of the given account.
|
* on the {@link AccountType} of the given account.
|
||||||
*
|
*
|
||||||
* @param fromAccount the from account to get the multiplier for
|
* @param fromAccount the from account to get the multiplier for
|
||||||
|
*
|
||||||
* @return the multiplier, either <code>1</code> or <code>-1</code>
|
* @return the multiplier, either <code>1</code> or <code>-1</code>
|
||||||
*/
|
*/
|
||||||
public long getMultiplierFromAccount(Account fromAccount) {
|
public long getMultiplierFromAccount(Account fromAccount) {
|
||||||
@@ -89,16 +91,20 @@ public class RuleService implements InitializingBean {
|
|||||||
return 1L;
|
return 1L;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LOGGER.warn(String
|
||||||
|
.format("Unknown or invalid account type in getMultiplierFromAccount: %s", accountType.name()));
|
||||||
|
|
||||||
return 1L;
|
return 1L;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method returns the multiplier for the given to account.
|
* This method returns the multiplier for the given to account.
|
||||||
* <p>
|
* <p>
|
||||||
* The multiplier controls whether the current amount of the given to account is increased or
|
* The multiplier controls whether the current amount of the given to account is increased or decreased depending on
|
||||||
* decreased depending on the {@link AccountType} of the given account.
|
* the {@link AccountType} of the given account.
|
||||||
*
|
*
|
||||||
* @param toAccount the to account to get the multiplier for
|
* @param toAccount the to account to get the multiplier for
|
||||||
|
*
|
||||||
* @return the multiplier, either <code>1</code> or <code>-1</code>
|
* @return the multiplier, either <code>1</code> or <code>-1</code>
|
||||||
*/
|
*/
|
||||||
public long getMultiplierToAccount(Account toAccount) {
|
public long getMultiplierToAccount(Account toAccount) {
|
||||||
@@ -117,27 +123,33 @@ public class RuleService implements InitializingBean {
|
|||||||
return 1L;
|
return 1L;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LOGGER.warn(String
|
||||||
|
.format("Unknown or invalid account type in getMultiplierToAccount: %s", accountType.name()));
|
||||||
|
|
||||||
return -1L;
|
return -1L;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method validates whether the booking from <code>fromAccount</code> to <code>toAccount</code>
|
* This method validates whether the booking from <code>fromAccount</code> to <code>toAccount</code> is valid, e.g.
|
||||||
* is valid, e.g. booking directly from an {@link AccountType#INCOME INCOME} to an {@link AccountType#EXPENSE EXPENSE}
|
* booking directly from an {@link AccountType#INCOME INCOME} to an {@link AccountType#EXPENSE EXPENSE} account does
|
||||||
* account does not make sense and is declared as invalid.
|
* not make sense and is declared as invalid.
|
||||||
*
|
*
|
||||||
* @param fromAccount the account to subtract the money from
|
* @param fromAccount the account to subtract the money from
|
||||||
* @param toAccount the account to add the money to
|
* @param toAccount the account to add the money to
|
||||||
* @return <code>true</code> if the from->to relationship of the given accounts is valid, <code>false</code> otherwise
|
*
|
||||||
|
* @return <code>true</code> if the from->to relationship of the given accounts is valid, <code>false</code>
|
||||||
|
* otherwise
|
||||||
*/
|
*/
|
||||||
public boolean isValidBooking(Account fromAccount, Account toAccount) {
|
public boolean isValidBooking(Account fromAccount, Account toAccount) {
|
||||||
return this.bookingRules.get(fromAccount.getType()).contains(toAccount.getType());
|
return this.bookingRules.get(fromAccount.getType()).contains(toAccount.getType());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method gets the {@link Period} for the given {@link IntervalType},
|
* This method gets the {@link Period} for the given {@link IntervalType}, e.g. a period of three months for {@link
|
||||||
* e.g. a period of three months for {@link IntervalType#QUARTERLY}.
|
* IntervalType#QUARTERLY}.
|
||||||
*
|
*
|
||||||
* @param intervalType to get the period for
|
* @param intervalType to get the period for
|
||||||
|
*
|
||||||
* @return the period matching the interval type
|
* @return the period matching the interval type
|
||||||
*/
|
*/
|
||||||
public Period getPeriodForInterval(IntervalType intervalType) {
|
public Period getPeriodForInterval(IntervalType intervalType) {
|
||||||
@@ -148,18 +160,24 @@ public class RuleService implements InitializingBean {
|
|||||||
* This method checks whether the given date is a holiday in the configured country and state.
|
* This method checks whether the given date is a holiday in the configured country and state.
|
||||||
*
|
*
|
||||||
* @param now the date to check
|
* @param now the date to check
|
||||||
|
*
|
||||||
* @return <code>true</code> if the given date is a holiday, <code>false</code> otherwise
|
* @return <code>true</code> if the given date is a holiday, <code>false</code> otherwise
|
||||||
*/
|
*/
|
||||||
public boolean isHoliday(LocalDate now) {
|
public boolean isHoliday(LocalDate now) {
|
||||||
|
if (LOGGER.isDebugEnabled()) {
|
||||||
|
LOGGER.debug(String.format("Use state '%s' for holiday calculation", this.financerConfig.getState()));
|
||||||
|
}
|
||||||
|
|
||||||
return HolidayManager.getInstance(ManagerParameters.create(this.financerConfig.getHolidayCalendar()))
|
return HolidayManager.getInstance(ManagerParameters.create(this.financerConfig.getHolidayCalendar()))
|
||||||
.isHoliday(now, this.financerConfig.getState());
|
.isHoliday(now, this.financerConfig.getState());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method checks whether the given date is a weekend day, i.e. whether it's a
|
* This method checks whether the given date is a weekend day, i.e. whether it's a {@link DayOfWeek#SATURDAY} or
|
||||||
* {@link DayOfWeek#SATURDAY} or {@link DayOfWeek#SUNDAY}.
|
* {@link DayOfWeek#SUNDAY}.
|
||||||
*
|
*
|
||||||
* @param now the date to check
|
* @param now the date to check
|
||||||
|
*
|
||||||
* @return <code>true</code> if the given date is a weekend day, <code>false</code> otherwise
|
* @return <code>true</code> if the given date is a weekend day, <code>false</code> otherwise
|
||||||
*/
|
*/
|
||||||
public boolean isWeekend(LocalDate now) {
|
public boolean isWeekend(LocalDate now) {
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ import de.financer.dba.TransactionRepository;
|
|||||||
import de.financer.model.Account;
|
import de.financer.model.Account;
|
||||||
import de.financer.model.RecurringTransaction;
|
import de.financer.model.RecurringTransaction;
|
||||||
import de.financer.model.Transaction;
|
import de.financer.model.Transaction;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Propagation;
|
import org.springframework.transaction.annotation.Propagation;
|
||||||
@@ -18,6 +20,8 @@ import java.util.Collections;
|
|||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class TransactionService {
|
public class TransactionService {
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(TransactionService.class);
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private AccountService accountService;
|
private AccountService accountService;
|
||||||
|
|
||||||
@@ -47,6 +51,8 @@ public class TransactionService {
|
|||||||
final Account account = this.accountService.getAccountByKey(accountKey);
|
final Account account = this.accountService.getAccountByKey(accountKey);
|
||||||
|
|
||||||
if (account == null) {
|
if (account == null) {
|
||||||
|
LOGGER.warn(String.format("Account with key %s not found!", accountKey));
|
||||||
|
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,7 +95,7 @@ public class TransactionService {
|
|||||||
|
|
||||||
response = ResponseReason.OK;
|
response = ResponseReason.OK;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// TODO log
|
LOGGER.error("Could not create transaction!", e);
|
||||||
|
|
||||||
response = ResponseReason.UNKNOWN_ERROR;
|
response = ResponseReason.UNKNOWN_ERROR;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import de.financer.config.FinancerConfig;
|
|||||||
import de.financer.model.RecurringTransaction;
|
import de.financer.model.RecurringTransaction;
|
||||||
import de.financer.service.RecurringTransactionService;
|
import de.financer.service.RecurringTransactionService;
|
||||||
import org.apache.commons.collections4.IterableUtils;
|
import org.apache.commons.collections4.IterableUtils;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.mail.MailException;
|
import org.springframework.mail.MailException;
|
||||||
import org.springframework.mail.SimpleMailMessage;
|
import org.springframework.mail.SimpleMailMessage;
|
||||||
@@ -14,6 +16,8 @@ import org.springframework.stereotype.Component;
|
|||||||
@Component
|
@Component
|
||||||
public class SendRecurringTransactionReminderTask {
|
public class SendRecurringTransactionReminderTask {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(SendRecurringTransactionReminderTask.class);
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private RecurringTransactionService recurringTransactionService;
|
private RecurringTransactionService recurringTransactionService;
|
||||||
|
|
||||||
@@ -25,13 +29,23 @@ public class SendRecurringTransactionReminderTask {
|
|||||||
|
|
||||||
@Scheduled(cron = "0 30 0 * * *")
|
@Scheduled(cron = "0 30 0 * * *")
|
||||||
public void sendReminder() {
|
public void sendReminder() {
|
||||||
|
if (LOGGER.isDebugEnabled()) {
|
||||||
|
LOGGER.debug("Enter recurring transaction reminder task");
|
||||||
|
}
|
||||||
|
|
||||||
final Iterable<RecurringTransaction> recurringTransactions = this.recurringTransactionService.getAllDueToday();
|
final Iterable<RecurringTransaction> recurringTransactions = this.recurringTransactionService.getAllDueToday();
|
||||||
|
|
||||||
// If no recurring transaction is due today we don't need to send a reminder
|
// If no recurring transaction is due today we don't need to send a reminder
|
||||||
if (IterableUtils.isEmpty(recurringTransactions)) {
|
if (IterableUtils.isEmpty(recurringTransactions)) {
|
||||||
|
LOGGER.info("No recurring transactions due today!");
|
||||||
|
|
||||||
return; // early return
|
return; // early return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LOGGER.info(String
|
||||||
|
.format("%s recurring transaction are due today and are about to be included in the reminder email",
|
||||||
|
IterableUtils.size(recurringTransactions)));
|
||||||
|
|
||||||
final StringBuilder reminderBuilder = new StringBuilder();
|
final StringBuilder reminderBuilder = new StringBuilder();
|
||||||
|
|
||||||
reminderBuilder.append("The following recurring transactions are due today:")
|
reminderBuilder.append("The following recurring transactions are due today:")
|
||||||
@@ -63,7 +77,10 @@ public class SendRecurringTransactionReminderTask {
|
|||||||
try {
|
try {
|
||||||
this.mailSender.send(msg);
|
this.mailSender.send(msg);
|
||||||
} catch (MailException e) {
|
} catch (MailException e) {
|
||||||
// TODO log
|
LOGGER.error("Could not send recurring transaction email reminder!", e);
|
||||||
|
|
||||||
|
LOGGER.info("Dumb email reminder content because the sending failed");
|
||||||
|
LOGGER.info(reminderBuilder.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ info.build.group=@project.groupId@
|
|||||||
info.build.artifact=@project.artifactId@
|
info.build.artifact=@project.artifactId@
|
||||||
info.build.version=@project.version@
|
info.build.version=@project.version@
|
||||||
|
|
||||||
|
logging.level.de.financer=DEBUG
|
||||||
|
|
||||||
# Country code for holiday checks
|
# Country code for holiday checks
|
||||||
# Mostly an uppercase ISO 3166 2-letter code
|
# Mostly an uppercase ISO 3166 2-letter code
|
||||||
# For a complete list of the supported codes see https://github.com/svendiedrichsen/jollyday/blob/master/src/main/java/de/jollyday/HolidayCalendar.java
|
# For a complete list of the supported codes see https://github.com/svendiedrichsen/jollyday/blob/master/src/main/java/de/jollyday/HolidayCalendar.java
|
||||||
|
|||||||
Reference in New Issue
Block a user