#23 Transaction import: new period

This commit is contained in:
2021-09-01 22:41:18 +02:00
parent 6a3359ea5c
commit 70218ad7dc
14 changed files with 235 additions and 90 deletions

View File

@@ -2,91 +2,114 @@ package de.financer.dto;
import org.apache.commons.lang3.builder.ReflectionToStringBuilder; import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
import java.util.List;
public class CreateUploadedTransactionsRequestDto { public class CreateUploadedTransactionsRequestDto {
private String fromAccountKey; private List<CreateUploadedTransactionsRequestEntry> entries;
private String toAccountKey; private Long newPeriodOnRecurringTransactionId;
private String amount;
private String date;
private String description;
private Boolean taxRelevant;
private String fileContent;
private String fileName;
private String recurringTransactionId;
@Override public List<CreateUploadedTransactionsRequestEntry> getEntries() {
public String toString() { return entries;
return ReflectionToStringBuilder.toString(this);
} }
public String getFromAccountKey() { public void setEntries(List<CreateUploadedTransactionsRequestEntry> entries) {
return fromAccountKey; this.entries = entries;
} }
public void setFromAccountKey(String fromAccountKey) { public Long getNewPeriodOnRecurringTransactionId() {
this.fromAccountKey = fromAccountKey; return newPeriodOnRecurringTransactionId;
} }
public String getToAccountKey() { public void setNewPeriodOnRecurringTransactionId(Long newPeriodOnRecurringTransactionId) {
return toAccountKey; this.newPeriodOnRecurringTransactionId = newPeriodOnRecurringTransactionId;
} }
public void setToAccountKey(String toAccountKey) { public static class CreateUploadedTransactionsRequestEntry {
this.toAccountKey = toAccountKey; private String fromAccountKey;
} private String toAccountKey;
private String amount;
private String date;
private String description;
private Boolean taxRelevant;
private String fileContent;
private String fileName;
private String recurringTransactionId;
public String getAmount() { @Override
return amount; public String toString() {
} return ReflectionToStringBuilder.toString(this);
}
public void setAmount(String amount) { public String getFromAccountKey() {
this.amount = amount; return fromAccountKey;
} }
public String getDate() { public void setFromAccountKey(String fromAccountKey) {
return date; this.fromAccountKey = fromAccountKey;
} }
public void setDate(String date) { public String getToAccountKey() {
this.date = date; return toAccountKey;
} }
public String getDescription() { public void setToAccountKey(String toAccountKey) {
return description; this.toAccountKey = toAccountKey;
} }
public void setDescription(String description) { public String getAmount() {
this.description = description; return amount;
} }
public Boolean getTaxRelevant() { public void setAmount(String amount) {
return taxRelevant; this.amount = amount;
} }
public void setTaxRelevant(Boolean taxRelevant) { public String getDate() {
this.taxRelevant = taxRelevant; return date;
} }
public String getFileContent() { public void setDate(String date) {
return fileContent; this.date = date;
} }
public void setFileContent(String fileContent) { public String getDescription() {
this.fileContent = fileContent; return description;
} }
public String getFileName() { public void setDescription(String description) {
return fileName; this.description = description;
} }
public void setFileName(String fileName) { public Boolean getTaxRelevant() {
this.fileName = fileName; return taxRelevant;
} }
public String getRecurringTransactionId() { public void setTaxRelevant(Boolean taxRelevant) {
return recurringTransactionId; this.taxRelevant = taxRelevant;
} }
public void setRecurringTransactionId(String recurringTransactionId) { public String getFileContent() {
this.recurringTransactionId = recurringTransactionId; return fileContent;
}
public void setFileContent(String fileContent) {
this.fileContent = fileContent;
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public String getRecurringTransactionId() {
return recurringTransactionId;
}
public void setRecurringTransactionId(String recurringTransactionId) {
this.recurringTransactionId = recurringTransactionId;
}
} }
} }

View File

@@ -10,7 +10,9 @@ import org.springframework.http.ResponseEntity;
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;
import java.time.LocalDateTime;
import java.util.List; import java.util.List;
import java.util.Optional;
@RestController @RestController
@RequestMapping("periods") @RequestMapping("periods")
@@ -26,7 +28,8 @@ public class PeriodController {
LOGGER.debug("/periods/closeCurrentExpensePeriod called"); LOGGER.debug("/periods/closeCurrentExpensePeriod called");
} }
final ResponseEntity responseEntity = this.periodService.closeCurrentExpensePeriod().toResponseEntity(); final ResponseEntity responseEntity = this.periodService.closeCurrentExpensePeriod(Optional.empty())
.toResponseEntity();
if (LOGGER.isDebugEnabled()) { if (LOGGER.isDebugEnabled()) {
LOGGER.debug(String.format("/periods/closeCurrentExpensePeriod returns with %s", responseEntity)); LOGGER.debug(String.format("/periods/closeCurrentExpensePeriod returns with %s", responseEntity));

View File

@@ -168,12 +168,12 @@ public class TransactionController {
} }
@PostMapping(value = "/transactions/upload") @PostMapping(value = "/transactions/upload")
public ResponseEntity createTransaction(@RequestBody Collection<CreateUploadedTransactionsRequestDto> requestDtos) { public ResponseEntity createTransaction(@RequestBody CreateUploadedTransactionsRequestDto requestDto) {
if (LOGGER.isDebugEnabled()) { if (LOGGER.isDebugEnabled()) {
LOGGER.debug(String.format("POST /transactions/upload got parameters: %s", requestDtos)); LOGGER.debug(String.format("POST /transactions/upload got parameters: %s", requestDto));
} }
final ResponseReason responseReason = this.transactionService.createTransactions(requestDtos); final ResponseReason responseReason = this.transactionService.createTransactions(requestDto);
if (LOGGER.isDebugEnabled()) { if (LOGGER.isDebugEnabled()) {
LOGGER.debug(String.format("POST /transactions/upload returns with %s", responseReason.name())); LOGGER.debug(String.format("POST /transactions/upload returns with %s", responseReason.name()));

View File

@@ -45,14 +45,17 @@ public class PeriodService {
/** /**
* This method closes the current expense period and opens a new one. * This method closes the current expense period and opens a new one.
* *
* @param endDate an optional end date timestamp for the currently open expense period. If none is given the current
* timestamp is used
*
* @return {@link ResponseReason#OK} if the operation succeeded, {@link ResponseReason#UNKNOWN_ERROR} if an * @return {@link ResponseReason#OK} if the operation succeeded, {@link ResponseReason#UNKNOWN_ERROR} if an
* unexpected exception occurred. * unexpected exception occurred.
*/ */
@Transactional(propagation = Propagation.REQUIRED) @Transactional(propagation = Propagation.REQUIRED)
public ResponseReason closeCurrentExpensePeriod() { public ResponseReason closeCurrentExpensePeriod(Optional<LocalDateTime> endDate) {
final Period currentPeriod = this.getCurrentExpensePeriod(); final Period currentPeriod = this.getCurrentExpensePeriod();
final Period nextPeriod = new Period(); final Period nextPeriod = new Period();
final LocalDateTime now = LocalDateTime.now(); final LocalDateTime now = endDate.orElse(LocalDateTime.now());
ResponseReason response; ResponseReason response;
currentPeriod.setEnd(now); currentPeriod.setEnd(now);

View File

@@ -22,6 +22,8 @@ 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.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException; import java.time.format.DateTimeParseException;
import java.util.*; import java.util.*;
@@ -418,15 +420,16 @@ public class TransactionService {
/** /**
* This method creates multiple transactions in one batch based on the given parameters. In case of invalid * This method creates multiple transactions in one batch based on the given parameters. In case of invalid
* parameters the creation aborts and the first issue found is returned. * parameters the creation aborts and the first issue found is returned. If requested via the given parameter
* the method will also close and open expense periods.
* *
* @param requestDtos parameters to create the transactions for * @param requestDto parameter to create the transactions for
* @return {@link ResponseReason#CREATED CREATED} in case of success, another instance of {@link ResponseReason} * @return {@link ResponseReason#CREATED CREATED} in case of success, another instance of {@link ResponseReason}
* otherwise. Never <code>null</code> * otherwise. Never <code>null</code>
*/ */
@Transactional(propagation = Propagation.REQUIRED) @Transactional(propagation = Propagation.REQUIRED)
public ResponseReason createTransactions(Collection<CreateUploadedTransactionsRequestDto> requestDtos) { public ResponseReason createTransactions(CreateUploadedTransactionsRequestDto requestDto) {
requestDtos.stream().forEach(dto -> { requestDto.getEntries().stream().forEach(dto -> {
final ResponseReason responseReason; final ResponseReason responseReason;
if(StringUtils.isNotEmpty(dto.getRecurringTransactionId())) { if(StringUtils.isNotEmpty(dto.getRecurringTransactionId())) {
@@ -435,6 +438,15 @@ public class TransactionService {
.orElseThrow(() -> new FinancerServiceException( .orElseThrow(() -> new FinancerServiceException(
ResponseReason.RECURRING_TRANSACTION_NOT_FOUND)); ResponseReason.RECURRING_TRANSACTION_NOT_FOUND));
if(recurringTransaction.getId().equals(requestDto.getNewPeriodOnRecurringTransactionId())) {
this.periodService
.closeCurrentExpensePeriod(Optional.of(
LocalDateTime.of(
LocalDate.parse(dto.getDate(),
DateTimeFormatter.ofPattern(this.financerConfig.getDateFormat())),
LocalTime.now())));
}
responseReason = this.createTransaction(dto.getFromAccountKey(), responseReason = this.createTransaction(dto.getFromAccountKey(),
dto.getToAccountKey(), dto.getToAccountKey(),
Long.valueOf(dto.getAmount()), Long.valueOf(dto.getAmount()),

View File

@@ -19,8 +19,12 @@ import de.financer.transactionUpload.TransactionUploadWorker;
import de.financer.transactionUpload.TransactionUploadWorkerFactory; import de.financer.transactionUpload.TransactionUploadWorkerFactory;
import de.financer.transactionUpload.UploadedTransaction; import de.financer.transactionUpload.UploadedTransaction;
import de.financer.util.ControllerUtils; import de.financer.util.ControllerUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.IterableUtils; import org.apache.commons.collections4.IterableUtils;
import org.apache.commons.collections4.ListUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.ParameterizedTypeReference; import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
@@ -180,6 +184,17 @@ public class TransactionController {
@GetMapping("/uploadTransactions") @GetMapping("/uploadTransactions")
public String uploadTransaction(Model model) { public String uploadTransaction(Model model) {
final ResponseEntity<Iterable<RecurringTransaction>> response = new GetAllRecurringTransactionsTemplate()
.exchange(this.financerConfig);
final List<RecurringTransaction> recurringTransactionList = new ArrayList<>();
final RecurringTransaction emptyRecurring = new RecurringTransaction();
emptyRecurring.setDescription("-");
recurringTransactionList.add(emptyRecurring);
recurringTransactionList.addAll(IterableUtils.toList(response.getBody()));
model.addAttribute("recurringTransactions", recurringTransactionList);
model.addAttribute("form", new UploadTransactionsForm()); model.addAttribute("form", new UploadTransactionsForm());
model.addAttribute("formats", TransactionUploadFormat.values()); model.addAttribute("formats", TransactionUploadFormat.values());
@@ -201,10 +216,30 @@ public class TransactionController {
final Collection<UploadedTransaction> uploadedTransactions = worker.process(form.getFile()); final Collection<UploadedTransaction> uploadedTransactions = worker.process(form.getFile());
return _uploadTransactions(model, Optional.empty(), CreateUploadedTransactionForm.of(uploadedTransactions)); Long newPeriodOnRecurringTransaction = null;
if(BooleanUtils.isTrue(form.getEnableNewPeriodOnRecurringTransaction())) {
if(NumberUtils.isCreatable(form.getNewPeriodOnRecurringTransaction())) {
newPeriodOnRecurringTransaction = Long.valueOf(form.getNewPeriodOnRecurringTransaction());
}
}
return _uploadTransactions(model, Optional.empty(),
CreateUploadedTransactionForm.of(uploadedTransactions, newPeriodOnRecurringTransaction));
} }
catch(Exception e) { catch(Exception e) {
// TODO // TODO
final ResponseEntity<Iterable<RecurringTransaction>> response = new GetAllRecurringTransactionsTemplate()
.exchange(this.financerConfig);
final List<RecurringTransaction> recurringTransactionList = new ArrayList<>();
final RecurringTransaction emptyRecurring = new RecurringTransaction();
emptyRecurring.setDescription("-");
recurringTransactionList.add(emptyRecurring);
recurringTransactionList.addAll(IterableUtils.toList(response.getBody()));
model.addAttribute("recurringTransactions", recurringTransactionList);
model.addAttribute("errorMessage", "KAPUTT"); model.addAttribute("errorMessage", "KAPUTT");
model.addAttribute("formats", TransactionUploadFormat.values()); model.addAttribute("formats", TransactionUploadFormat.values());
model.addAttribute("form", form); model.addAttribute("form", form);
@@ -220,38 +255,47 @@ public class TransactionController {
@PostMapping("/createUploadedTransactions") @PostMapping("/createUploadedTransactions")
public String createUploadedTransactions(CreateUploadedTransactionForm form, Model model) { public String createUploadedTransactions(CreateUploadedTransactionForm form, Model model) {
try { try {
final Collection<CreateUploadedTransactionsRequestDto> dtos = final List<CreateUploadedTransactionsRequestDto.CreateUploadedTransactionsRequestEntry> entries =
form.getEntries() form.getEntries()
.stream() .stream()
.filter(CreateUploadedTransactionForm.CreateUploadedTransactionFormEntry::getCreate) .filter(CreateUploadedTransactionForm.CreateUploadedTransactionFormEntry::getCreate)
.map(e -> { .map(e -> {
final CreateUploadedTransactionsRequestDto dto = new CreateUploadedTransactionsRequestDto(); final CreateUploadedTransactionsRequestDto.CreateUploadedTransactionsRequestEntry entry =
new CreateUploadedTransactionsRequestDto.CreateUploadedTransactionsRequestEntry();
dto.setAmount(e.getAmount().toString()); entry.setAmount(e.getAmount().toString());
dto.setDate(ControllerUtils.formatDate(this.financerConfig, e.getDate())); entry.setDate(ControllerUtils.formatDate(this.financerConfig, e.getDate()));
dto.setDescription(e.getDescription()); entry.setDescription(e.getDescription());
dto.setFromAccountKey(e.getFromAccountKey()); entry.setFromAccountKey(e.getFromAccountKey());
dto.setToAccountKey(e.getToAccountKey()); entry.setToAccountKey(e.getToAccountKey());
dto.setRecurringTransactionId(Optional.ofNullable(e.getRecurringTransactionId()) entry.setRecurringTransactionId(Optional.ofNullable(e.getRecurringTransactionId())
.map(id -> id.toString()) .map(id -> id.toString())
.orElse(null)); .orElse(null));
dto.setTaxRelevant(e.getTaxRelevant()); entry.setTaxRelevant(e.getTaxRelevant());
if (e.getFile() != null && StringUtils.isNotEmpty(e.getFile().getOriginalFilename())) { if (e.getFile() != null && StringUtils.isNotEmpty(e.getFile().getOriginalFilename())) {
try { try {
dto.setFileContent(Base64.getEncoder().encodeToString(e.getFile().getBytes())); entry.setFileContent(Base64.getEncoder().encodeToString(e.getFile().getBytes()));
dto.setFileName(e.getFile().getOriginalFilename()); entry.setFileName(e.getFile().getOriginalFilename());
} catch (IOException ioe) { } catch (IOException ioe) {
// TODO No file for us :( // TODO No file for us :(
} }
} }
return dto; return entry;
}) })
.collect(Collectors.toList()); .collect(Collectors.toList());
final CreateUploadedTransactionsRequestDto dto = new CreateUploadedTransactionsRequestDto();
// We need to reverse the entries because of the actual booking order
// In the UI it is sorted descending, but we need to book ascending
Collections.reverse(entries);
dto.setEntries(entries);
dto.setNewPeriodOnRecurringTransactionId(form.getNewPeriodOnRecurringTransaction());
final ResponseReason responseReason = FinancerRestTemplate final ResponseReason responseReason = FinancerRestTemplate
.exchangePost(this.financerConfig, Function.TR_CREATE_UPLOADED_TRANSACTIONS, dtos); .exchangePost(this.financerConfig, Function.TR_CREATE_UPLOADED_TRANSACTIONS, dto);
if (!ResponseReason.CREATED.equals(responseReason)) { if (!ResponseReason.CREATED.equals(responseReason)) {
return _uploadTransactions(model, Optional.of(responseReason), form); return _uploadTransactions(model, Optional.of(responseReason), form);

View File

@@ -9,11 +9,13 @@ import java.util.List;
public class CreateUploadedTransactionForm { public class CreateUploadedTransactionForm {
private List<CreateUploadedTransactionFormEntry> entries = new ArrayList<>(); private List<CreateUploadedTransactionFormEntry> entries = new ArrayList<>();
private Long newPeriodOnRecurringTransaction;
public static CreateUploadedTransactionForm of(Collection<UploadedTransaction> uploadedTransactions) { public static CreateUploadedTransactionForm of(Collection<UploadedTransaction> uploadedTransactions, Long newPeriodOnRecurringTransaction) {
final CreateUploadedTransactionForm form = new CreateUploadedTransactionForm(); final CreateUploadedTransactionForm form = new CreateUploadedTransactionForm();
uploadedTransactions.stream().forEach(e -> form.getEntries().add(CreateUploadedTransactionFormEntry.of(e))); uploadedTransactions.stream().forEach(e -> form.getEntries().add(CreateUploadedTransactionFormEntry.of(e)));
form.setNewPeriodOnRecurringTransaction(newPeriodOnRecurringTransaction);
return form; return form;
} }
@@ -26,6 +28,14 @@ public class CreateUploadedTransactionForm {
this.entries = entries; this.entries = entries;
} }
public Long getNewPeriodOnRecurringTransaction() {
return newPeriodOnRecurringTransaction;
}
public void setNewPeriodOnRecurringTransaction(Long newPeriodOnRecurringTransaction) {
this.newPeriodOnRecurringTransaction = newPeriodOnRecurringTransaction;
}
public static final class CreateUploadedTransactionFormEntry { public static final class CreateUploadedTransactionFormEntry {
private Boolean create; private Boolean create;
private String fromAccountKey; private String fromAccountKey;

View File

@@ -5,6 +5,8 @@ import org.springframework.web.multipart.MultipartFile;
public class UploadTransactionsForm { public class UploadTransactionsForm {
private String format; private String format;
private MultipartFile file; private MultipartFile file;
private String newPeriodOnRecurringTransaction;
private Boolean enableNewPeriodOnRecurringTransaction;
public String getFormat() { public String getFormat() {
return format; return format;
@@ -21,4 +23,20 @@ public class UploadTransactionsForm {
public void setFile(MultipartFile file) { public void setFile(MultipartFile file) {
this.file = file; this.file = file;
} }
public String getNewPeriodOnRecurringTransaction() {
return newPeriodOnRecurringTransaction;
}
public void setNewPeriodOnRecurringTransaction(String newPeriodOnRecurringTransaction) {
this.newPeriodOnRecurringTransaction = newPeriodOnRecurringTransaction;
}
public Boolean getEnableNewPeriodOnRecurringTransaction() {
return enableNewPeriodOnRecurringTransaction;
}
public void setEnableNewPeriodOnRecurringTransaction(Boolean enableNewPeriodOnRecurringTransaction) {
this.enableNewPeriodOnRecurringTransaction = enableNewPeriodOnRecurringTransaction;
}
} }

View File

@@ -176,6 +176,9 @@ financer.upload-transactions.label.format=Format\:
financer.upload-transactions.format.MT940_CSV=MT940 CSV financer.upload-transactions.format.MT940_CSV=MT940 CSV
financer.upload-transactions.label.file=File\: financer.upload-transactions.label.file=File\:
financer.upload-transactions.submit=Upload transactions financer.upload-transactions.submit=Upload transactions
financer.upload-transactions.label.new-period-on-recurring-transaction-summary=New period on encountering a certain recurring transaction
financer.upload-transactions.label.new-period-on-recurring-transaction=Recurring transaction\:
financer.upload-transactions.label.new-period-on-recurring-transaction-enable=Enable\:
financer.create-upload-transactions.title=financer\: create uploaded transactions financer.create-upload-transactions.title=financer\: create uploaded transactions
financer.create-upload-transactions.table-header.create=Create financer.create-upload-transactions.table-header.create=Create
@@ -272,8 +275,8 @@ financer.heading.account-edit=financer\: edit account
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.back-to-overview=Back to overview
financer.show-actions=Show... financer.show-actions=Show...
financer.show-options=Show options...
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

View File

@@ -176,6 +176,9 @@ financer.upload-transactions.label.format=Format\:
financer.upload-transactions.format.MT940_CSV=MT940 CSV financer.upload-transactions.format.MT940_CSV=MT940 CSV
financer.upload-transactions.label.file=Datei\: financer.upload-transactions.label.file=Datei\:
financer.upload-transactions.submit=Buchungen hochladen financer.upload-transactions.submit=Buchungen hochladen
financer.upload-transactions.label.new-period-on-recurring-transaction-summary=Neue Periode bei wiederkehrender Buchung
financer.upload-transactions.label.new-period-on-recurring-transaction=Wiederkehrende Buchung\:
financer.upload-transactions.label.new-period-on-recurring-transaction-enable=Aktiv\:
financer.create-upload-transactions.title=financer\: Erstelle hochgeladene Buchungen financer.create-upload-transactions.title=financer\: Erstelle hochgeladene Buchungen
financer.create-upload-transactions.table-header.create=Erstellen financer.create-upload-transactions.table-header.create=Erstellen
@@ -272,6 +275,7 @@ financer.heading.account-edit=financer\: Bearbeite Konto
financer.cancel-back-to-overview=Abbrechen und zur\u00FCck zur \u00DCbersicht financer.cancel-back-to-overview=Abbrechen und zur\u00FCck zur \u00DCbersicht
financer.back-to-overview=Zur\u00FCck zur \u00DCbersicht financer.back-to-overview=Zur\u00FCck zur \u00DCbersicht
financer.show-actions=Anzeigen... financer.show-actions=Anzeigen...
financer.show-options=Zeige Optionen...
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

View File

@@ -3,6 +3,8 @@ v48 -> v49:
only the active ones only the active ones
- #11 It is now possible to specify a date during creation of a transaction from a recurring transaction - #11 It is now possible to specify a date during creation of a transaction from a recurring transaction
- #25 Added the possibility to edit accounts - #25 Added the possibility to edit accounts
- #23 Added an option to specify a recurring transaction during transaction upload that will close and open expense
periods
v47 -> v48: v47 -> v48:
- #20 Added new property 'transaction type' to a transaction, denoting the type of the transaction, e.g. asset swap, - #20 Added new property 'transaction type' to a transaction, denoting the type of the transaction, e.g. asset swap,

View File

@@ -389,3 +389,12 @@ input[type=submit] {
.cal-day-con-today { .cal-day-con-today {
background-color: #f5e5b8; background-color: #f5e5b8;
} }
.transaction-upload-fieldset {
margin-left: 1em;
margin-top: 0px !important;
}
.transaction-upload-fieldset * {
width: 17.75em !important;
}

View File

@@ -66,6 +66,7 @@
</td> </td>
</tr> </tr>
</table> </table>
<input type="hidden" id="inputNewPeriodOnRecurringTransaction" th:field="*{newPeriodOnRecurringTransaction}"/>
<input type="submit" th:value="#{financer.create-upload-transactions.submit}"/> <input type="submit" th:value="#{financer.create-upload-transactions.submit}"/>
</form> </form>
<div th:replace="includes/footer :: footer"/> <div th:replace="includes/footer :: footer"/>

View File

@@ -22,6 +22,19 @@
</select> </select>
<label for="inputFile" th:text="#{financer.upload-transactions.label.file}" /> <label for="inputFile" th:text="#{financer.upload-transactions.label.file}" />
<input type="file" id="inputFile" th:field="*{file}" /> <input type="file" id="inputFile" th:field="*{file}" />
<details>
<summary th:text="#{financer.show-options}"/>
<fieldset class="transaction-upload-fieldset">
<legend th:text="#{financer.upload-transactions.label.new-period-on-recurring-transaction-summary}"/>
<label for="inputEnableNewPeriodOnRecurringTransaction" th:text="#{financer.upload-transactions.label.new-period-on-recurring-transaction-enable}"/>
<input type="checkbox" id="inputEnableNewPeriodOnRecurringTransaction" th:field="*{enableNewPeriodOnRecurringTransaction}" />
<label for="inputRecurringTransaction" th:text="#{financer.upload-transactions.label.new-period-on-recurring-transaction}" />
<select th:field="*{newPeriodOnRecurringTransaction}" id="inputRecurringTransaction">
<option th:each="rt : ${recurringTransactions}" th:value="${rt.id}"
th:text="${rt.description}"/>
</select>
</fieldset>
</details>
<input type="submit" th:value="#{financer.upload-transactions.submit}" /> <input type="submit" th:value="#{financer.upload-transactions.submit}" />
</form> </form>
<div th:replace="includes/footer :: footer" /> <div th:replace="includes/footer :: footer" />