Add calendar, SKIP and fix some bugs

This commit is contained in:
2020-10-09 16:44:05 +02:00
parent da3ce372b7
commit 2ee77f9d4f
29 changed files with 649 additions and 40 deletions

View File

@@ -96,7 +96,7 @@ L_PAREN : '(' ;
R_PAREN : ')' ;
IDENTIFIER : [a-zA-Z]+ ;
INT_VALUE : [0-9]+ ;
STRING_VALUE : '\'' [a-zA-Z0-9- ]+ '\'' ;
STRING_VALUE : '\'' [a-zA-Z0-9\-/ ]+ '\'' ;
DATE_VALUE : [0-9-]+ ;
NEWLINE : ('\r'? '\n' | '\r')+ ;

View File

@@ -1,12 +1,14 @@
package de.financer.controller;
import de.financer.ResponseReason;
import de.financer.dto.RecurringTransactionDueInRangeResponseDto;
import de.financer.model.RecurringTransaction;
import de.financer.service.RecurringTransactionService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
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.RestController;
@@ -114,4 +116,22 @@ public class RecurringTransactionController {
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;
}
}

View File

@@ -3,7 +3,11 @@ package de.financer.service;
import de.financer.ResponseReason;
import de.financer.config.FinancerConfig;
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.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
@@ -17,9 +21,12 @@ import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDate;
import java.time.Period;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
@@ -144,8 +151,19 @@ public class RecurringTransactionService {
// If so the recurring transaction is due today
.anyMatch((d) -> d.equals(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) {
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
*/
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())) {
LOGGER.debug(String.format("Recurring transaction %s has HWT %s and thus cannot be due in the past",
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
*/
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())) {
LOGGER.debug(String.format("Recurring transaction %s has HWT %s and thus cannot be due in the future",
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
// holiday weekend type says PREVIOUS_WORKDAY.
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," +
" thus it cannot be due in the future",
ReflectionToStringBuilder.toString(recurringTransaction),
recurringTransaction.getHolidayWeekendType()));
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",
ReflectionToStringBuilder.toString(recurringTransaction),
recurringTransaction.getHolidayWeekendType()));
return false; // early return
return false; // early return
}
@@ -313,7 +331,6 @@ public class RecurringTransactionService {
}
@Transactional(propagation = Propagation.REQUIRED)
public ResponseReason createRecurringTransaction(String fromAccountKey, String toAccountKey, Long amount,
String description, String holidayWeekendType,
@@ -512,4 +529,26 @@ public class RecurringTransactionService {
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;
}
}

View File

@@ -68,6 +68,7 @@ public class RuleService implements InitializingBean {
* <p>
* 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.
* </p>
*
* @param fromAccount the from account to get the multiplier for
*
@@ -102,6 +103,7 @@ public class RuleService implements InitializingBean {
* <p>
* 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.
* </p>
*
* @param toAccount the to account to get the multiplier for
*