Introduce module financer-common that hosts common code for server and (web) client
Also various fixes all over the place
This commit is contained in:
@@ -21,7 +21,6 @@ public class FinancerConfig {
|
||||
private String dateFormat;
|
||||
private Collection<String> mailRecipients;
|
||||
private String fromAddress;
|
||||
private Integer monthPeriodStartDay;
|
||||
|
||||
/**
|
||||
* @return the raw country code, mostly an uppercase ISO 3166 2-letter code
|
||||
@@ -110,32 +109,4 @@ public class FinancerConfig {
|
||||
public void setFromAddress(String fromAddress) {
|
||||
this.fromAddress = fromAddress;
|
||||
}
|
||||
|
||||
/**
|
||||
* The day of month that indicates a start of an expense period. Valid values range from 1-28. There is no special
|
||||
* handling for months with more days.
|
||||
* If the value is 15 for example an expense period is always from the 15th of the current month to the 15th of the
|
||||
* next month:
|
||||
* <ul>
|
||||
* <li>15.01.2019 - 15.02.2019</li>
|
||||
* <li>15.02.2019 - 15.03.2019</li>
|
||||
* <li>...</li>
|
||||
* </ul>
|
||||
*
|
||||
* @return the day of month indicating the start of an expense period
|
||||
*/
|
||||
public Integer getMonthPeriodStartDay() {
|
||||
return monthPeriodStartDay;
|
||||
}
|
||||
|
||||
public void setMonthPeriodStartDay(Integer monthPeriodStartDay) {
|
||||
if (monthPeriodStartDay == null) {
|
||||
throw new IllegalArgumentException("Parameter 'financer.monthPeriodStartDay' is not set!");
|
||||
}
|
||||
else if (monthPeriodStartDay < 1 || monthPeriodStartDay > 28) {
|
||||
throw new IllegalArgumentException("Parameter 'financer.monthPeriodStartDay' is out of range! Valid range from 1-28");
|
||||
}
|
||||
|
||||
this.monthPeriodStartDay = monthPeriodStartDay;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,12 +81,12 @@ public class TransactionController {
|
||||
}
|
||||
|
||||
@RequestMapping("getExpensesCurrentPeriod")
|
||||
public Long getExpensesCurrentPeriod() {
|
||||
public Long getExpensesCurrentPeriod(Integer monthPeriodStartDay) {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("/transactions/getExpensesCurrentPeriod called");
|
||||
LOGGER.debug(String.format("/transactions/getExpensesCurrentPeriod got parameters: %s", monthPeriodStartDay));
|
||||
}
|
||||
|
||||
final Long response = this.transactionService.getExpensesCurrentPeriod();
|
||||
final Long response = this.transactionService.getExpensesCurrentPeriod(monthPeriodStartDay);
|
||||
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug(String.format("/transactions/getExpensesCurrentPeriod returns with %s", response));
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
package de.financer.model;
|
||||
|
||||
import javax.persistence.*;
|
||||
|
||||
@Entity
|
||||
public class Account {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
@Column(name = "\"key\"") // we need to escape the keyword "key"
|
||||
private String key;
|
||||
@Enumerated(EnumType.STRING)
|
||||
private AccountType type;
|
||||
@Enumerated(EnumType.STRING)
|
||||
private AccountStatus status;
|
||||
private Long currentBalance;
|
||||
@ManyToOne
|
||||
private AccountGroup accountGroup;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public void setKey(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public AccountType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(AccountType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public AccountStatus getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(AccountStatus status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public Long getCurrentBalance() {
|
||||
return currentBalance;
|
||||
}
|
||||
|
||||
public void setCurrentBalance(Long currentBalance) {
|
||||
this.currentBalance = currentBalance;
|
||||
}
|
||||
|
||||
public AccountGroup getAccountGroup() {
|
||||
return accountGroup;
|
||||
}
|
||||
|
||||
public void setAccountGroup(AccountGroup accountGroup) {
|
||||
this.accountGroup = accountGroup;
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
package de.financer.model;
|
||||
|
||||
import javax.persistence.*;
|
||||
|
||||
@Entity
|
||||
public class AccountGroup {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
private String name;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
package de.financer.model;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public enum AccountStatus {
|
||||
/** Indicates that the account is open for bookings */
|
||||
OPEN,
|
||||
/** Indicates that the account is closed and bookings to it are forbidden */
|
||||
CLOSED;
|
||||
|
||||
/**
|
||||
* This method validates whether the given string represents a valid account status.
|
||||
*
|
||||
* @param status to check
|
||||
* @return whether the given status represents a valid account status
|
||||
*/
|
||||
public static boolean isValidType(String status) {
|
||||
return Arrays.stream(AccountStatus.values()).anyMatch((accountStatus) -> accountStatus.name().equals(status));
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
package de.financer.model;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public enum AccountType {
|
||||
/** Used to mark an account that acts as a source of money, e.g. monthly wage */
|
||||
INCOME,
|
||||
|
||||
/** Indicates a real account at a bank, e.g. a check payment account */
|
||||
BANK,
|
||||
|
||||
/** Marks an account as physical cash, e.g. the money currently in the purse */
|
||||
CASH,
|
||||
|
||||
/** Used to mark an account that acts as a destination of money, e.g. through buying goods */
|
||||
EXPENSE,
|
||||
|
||||
/** Marks an account as a liability from a third party, e.g. credit card or loan */
|
||||
LIABILITY,
|
||||
|
||||
/** Marks the start account that is to be used to book all the opening balances for the different accounts */
|
||||
START;
|
||||
|
||||
/**
|
||||
* This method validates whether the given string represents a valid account type.
|
||||
*
|
||||
* @param type to check
|
||||
* @return whether the given type represents a valid account type
|
||||
*/
|
||||
public static boolean isValidType(String type) {
|
||||
return Arrays.stream(AccountType.values()).anyMatch((accountType) -> accountType.name().equals(type));
|
||||
}
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
package de.financer.model;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* This enum specifies constants that control how actions should be handled that would fall on a holiday
|
||||
* or weekday (where usually are no bookings done by e.g. banks)
|
||||
*/
|
||||
public enum HolidayWeekendType {
|
||||
/** Indicates that the action should be done on the specified day regardless whether it's a holiday or a weekend */
|
||||
SAME_DAY,
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Indicates that the action should be deferred to the next workday.
|
||||
* </p>
|
||||
* <pre>
|
||||
* Example 1:
|
||||
* MO TU WE TH FR SA SO
|
||||
* H WE WE -> Holiday/WeekEnd
|
||||
* X -> Due date of action
|
||||
* X' -> Deferred, effective due date of action
|
||||
* </pre>
|
||||
* <pre>
|
||||
* Example 2:
|
||||
* TU WE TH FR SA SO MO
|
||||
* H WE WE -> Holiday/WeekEnd
|
||||
* X -> Due date of action
|
||||
* X' -> Deferred, effective due date of action
|
||||
* </pre>
|
||||
*
|
||||
*/
|
||||
NEXT_WORKDAY,
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Indicates that the action should preponed to the previous day
|
||||
* </p>
|
||||
* <pre>
|
||||
* Example 1:
|
||||
* MO TU WE TH FR SA SO
|
||||
* H WE WE -> Holiday/WeekEnd
|
||||
* X -> Due date of action
|
||||
* X' -> Earlier, effective due date of action
|
||||
* </pre>
|
||||
* <pre>
|
||||
* Example 2:
|
||||
* MO TU WE TH FR SA SO
|
||||
* H WE WE -> Holiday/WeekEnd
|
||||
* X -> Due date of action
|
||||
* X' -> Earlier, effective due date of action
|
||||
* </pre>
|
||||
*/
|
||||
PREVIOUS_WORKDAY;
|
||||
|
||||
/**
|
||||
* This method validates whether the given string represents a valid holiday weekend type.
|
||||
*
|
||||
* @param type to check
|
||||
* @return whether the given type represents a valid holiday weekend type
|
||||
*/
|
||||
public static boolean isValidType(String type) {
|
||||
return Arrays.stream(HolidayWeekendType.values()).anyMatch((holidayWeekendType) -> holidayWeekendType.name().equals(type));
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
package de.financer.model;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public enum IntervalType {
|
||||
/** Indicates that an action should be executed every day */
|
||||
DAILY,
|
||||
|
||||
/** Indicates that an action should be executed once a week */
|
||||
WEEKLY,
|
||||
|
||||
/** Indicates that an action should be executed once a month */
|
||||
MONTHLY,
|
||||
|
||||
/** Indicates that an action should be executed once a quarter */
|
||||
QUARTERLY,
|
||||
|
||||
/** Indicates that an action should be executed once a year */
|
||||
YEARLY;
|
||||
|
||||
/**
|
||||
* This method validates whether the given string represents a valid interval type.
|
||||
*
|
||||
* @param type to check
|
||||
* @return whether the given type represents a valid interval type
|
||||
*/
|
||||
public static boolean isValidType(String type) {
|
||||
return Arrays.stream(IntervalType.values()).anyMatch((intervalType) -> intervalType.name().equals(type));
|
||||
}
|
||||
}
|
||||
@@ -1,109 +0,0 @@
|
||||
package de.financer.model;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.time.LocalDate;
|
||||
|
||||
@Entity
|
||||
public class RecurringTransaction {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
@OneToOne(fetch = FetchType.EAGER)
|
||||
private Account fromAccount;
|
||||
@OneToOne(fetch = FetchType.EAGER)
|
||||
private Account toAccount;
|
||||
private String description;
|
||||
private Long amount;
|
||||
@Enumerated(EnumType.STRING)
|
||||
private IntervalType intervalType;
|
||||
private LocalDate firstOccurrence;
|
||||
private LocalDate lastOccurrence;
|
||||
@Enumerated(EnumType.STRING)
|
||||
private HolidayWeekendType holidayWeekendType;
|
||||
private boolean deleted;
|
||||
private boolean remind;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public Account getFromAccount() {
|
||||
return fromAccount;
|
||||
}
|
||||
|
||||
public void setFromAccount(Account fromAccount) {
|
||||
this.fromAccount = fromAccount;
|
||||
}
|
||||
|
||||
public Account getToAccount() {
|
||||
return toAccount;
|
||||
}
|
||||
|
||||
public void setToAccount(Account toAccount) {
|
||||
this.toAccount = toAccount;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public Long getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public void setAmount(Long amount) {
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
public HolidayWeekendType getHolidayWeekendType() {
|
||||
return holidayWeekendType;
|
||||
}
|
||||
|
||||
public void setHolidayWeekendType(HolidayWeekendType holidayWeekendType) {
|
||||
this.holidayWeekendType = holidayWeekendType;
|
||||
}
|
||||
|
||||
public LocalDate getLastOccurrence() {
|
||||
return lastOccurrence;
|
||||
}
|
||||
|
||||
public void setLastOccurrence(LocalDate lastOccurrence) {
|
||||
this.lastOccurrence = lastOccurrence;
|
||||
}
|
||||
|
||||
public LocalDate getFirstOccurrence() {
|
||||
return firstOccurrence;
|
||||
}
|
||||
|
||||
public void setFirstOccurrence(LocalDate firstOccurrence) {
|
||||
this.firstOccurrence = firstOccurrence;
|
||||
}
|
||||
|
||||
public IntervalType getIntervalType() {
|
||||
return intervalType;
|
||||
}
|
||||
|
||||
public void setIntervalType(IntervalType intervalType) {
|
||||
this.intervalType = intervalType;
|
||||
}
|
||||
|
||||
public boolean isDeleted() {
|
||||
return deleted;
|
||||
}
|
||||
|
||||
public void setDeleted(boolean deleted) {
|
||||
this.deleted = deleted;
|
||||
}
|
||||
|
||||
public boolean isRemind() {
|
||||
return remind;
|
||||
}
|
||||
|
||||
public void setRemind(boolean remind) {
|
||||
this.remind = remind;
|
||||
}
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
package de.financer.model;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.time.LocalDate;
|
||||
|
||||
@Entity
|
||||
@Table(name = "\"transaction\"")
|
||||
public class Transaction {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
@OneToOne(fetch = FetchType.EAGER)
|
||||
private Account fromAccount;
|
||||
@OneToOne(fetch = FetchType.EAGER)
|
||||
private Account toAccount;
|
||||
@Column(name = "\"date\"")
|
||||
private LocalDate date;
|
||||
private String description;
|
||||
private Long amount;
|
||||
@ManyToOne(fetch = FetchType.EAGER)
|
||||
private RecurringTransaction recurringTransaction;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public Account getFromAccount() {
|
||||
return fromAccount;
|
||||
}
|
||||
|
||||
public void setFromAccount(Account fromAccount) {
|
||||
this.fromAccount = fromAccount;
|
||||
}
|
||||
|
||||
public Account getToAccount() {
|
||||
return toAccount;
|
||||
}
|
||||
|
||||
public void setToAccount(Account toAccount) {
|
||||
this.toAccount = toAccount;
|
||||
}
|
||||
|
||||
public LocalDate getDate() {
|
||||
return date;
|
||||
}
|
||||
|
||||
public void setDate(LocalDate date) {
|
||||
this.date = date;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public Long getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public void setAmount(Long amount) {
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
public RecurringTransaction getRecurringTransaction() {
|
||||
return recurringTransaction;
|
||||
}
|
||||
|
||||
public void setRecurringTransaction(RecurringTransaction recurringTransaction) {
|
||||
this.recurringTransaction = recurringTransaction;
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
/**
|
||||
* <p>
|
||||
* This package contains the main model for the financer application.
|
||||
* In the DDD (<i>Domain Driven Design</i>) sense the models are anemic
|
||||
* as they contain no logic themselves but act as mere POJOs with additional
|
||||
* Hibernate annotations. The (business) logic is located in the services of the
|
||||
* {@link de.financer.service} package.
|
||||
* </p>
|
||||
*/
|
||||
package de.financer.model;
|
||||
@@ -7,6 +7,7 @@ import de.financer.model.Account;
|
||||
import de.financer.model.AccountType;
|
||||
import de.financer.model.RecurringTransaction;
|
||||
import de.financer.model.Transaction;
|
||||
import de.financer.util.ExpensePeriod;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.math.NumberUtils;
|
||||
import org.slf4j.Logger;
|
||||
@@ -224,12 +225,17 @@ public class TransactionService {
|
||||
return response;
|
||||
}
|
||||
|
||||
public Long getExpensesCurrentPeriod() {
|
||||
final LocalDate periodStart = LocalDate.now().withDayOfMonth(this.financerConfig.getMonthPeriodStartDay());
|
||||
final LocalDate periodEnd = periodStart.plusMonths(1);
|
||||
public Long getExpensesCurrentPeriod(Integer monthPeriodStartDay) {
|
||||
if (monthPeriodStartDay == null) {
|
||||
return Long.valueOf(-1l);
|
||||
}
|
||||
|
||||
final ExpensePeriod expensePeriod = ExpensePeriod
|
||||
.getCurrentExpensePeriod(monthPeriodStartDay);
|
||||
|
||||
final Long expensesCurrentPeriod = this.transactionRepository
|
||||
.getExpensesCurrentPeriod(periodStart, periodEnd, AccountType.EXPENSE, AccountType.LIABILITY);
|
||||
.getExpensesCurrentPeriod(expensePeriod.getStart(), expensePeriod
|
||||
.getEnd(), AccountType.EXPENSE, AccountType.LIABILITY);
|
||||
|
||||
return Optional.ofNullable(expensesCurrentPeriod).orElse(Long.valueOf(0l));
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
###
|
||||
### This is the main configuration file of the application.
|
||||
### Filtering of the @...@ values happens via the maven-resource-plugin. The execution of the plugin is configured in
|
||||
### the Spring Boot parent POM.
|
||||
### the Spring Boot parent POM.// The same property exists on the server, look there for documentation
|
||||
|
||||
spring.profiles.active=@activeProfiles@
|
||||
|
||||
@@ -46,7 +46,4 @@ spring.mail.host=localhost
|
||||
|
||||
# Disable JMX as we don't need it and it blocks parallel deployment on Tomcat
|
||||
# because the connection pool cannot shutdown properly
|
||||
spring.jmx.enabled=false
|
||||
|
||||
# The day of month indicating the start of an expense period. Valid values range from 1-28
|
||||
financer.monthPeriodStartDay=15
|
||||
spring.jmx.enabled=false
|
||||
Reference in New Issue
Block a user