diff --git a/src/main/java/de/financer/ResponseReason.java b/src/main/java/de/financer/ResponseReason.java index 01a1025..f73464b 100644 --- a/src/main/java/de/financer/ResponseReason.java +++ b/src/main/java/de/financer/ResponseReason.java @@ -7,7 +7,6 @@ public enum ResponseReason { OK(HttpStatus.OK), UNKNOWN_ERROR(HttpStatus.INTERNAL_SERVER_ERROR), INVALID_ACCOUNT_TYPE(HttpStatus.INTERNAL_SERVER_ERROR), - INVALID_ACCOUNT_KEY(HttpStatus.INTERNAL_SERVER_ERROR), FROM_ACCOUNT_NOT_FOUND(HttpStatus.INTERNAL_SERVER_ERROR), TO_ACCOUNT_NOT_FOUND(HttpStatus.INTERNAL_SERVER_ERROR), FROM_AND_TO_ACCOUNT_NOT_FOUND(HttpStatus.INTERNAL_SERVER_ERROR), @@ -30,7 +29,9 @@ public enum ResponseReason { INVALID_TRANSACTION_ID(HttpStatus.INTERNAL_SERVER_ERROR), TRANSACTION_NOT_FOUND(HttpStatus.INTERNAL_SERVER_ERROR), ACCOUNT_NOT_FOUND(HttpStatus.INTERNAL_SERVER_ERROR), - DUPLICATE_ACCOUNT_KEY(HttpStatus.INTERNAL_SERVER_ERROR); + DUPLICATE_ACCOUNT_KEY(HttpStatus.INTERNAL_SERVER_ERROR), + DUPLICATE_ACCOUNT_GROUP_NAME(HttpStatus.INTERNAL_SERVER_ERROR), + ACCOUNT_GROUP_NOT_FOUND(HttpStatus.INTERNAL_SERVER_ERROR); private HttpStatus httpStatus; diff --git a/src/main/java/de/financer/controller/AccountController.java b/src/main/java/de/financer/controller/AccountController.java index a1633cf..8c69a8f 100644 --- a/src/main/java/de/financer/controller/AccountController.java +++ b/src/main/java/de/financer/controller/AccountController.java @@ -45,7 +45,11 @@ public class AccountController { @GetMapping("/newAccount") public String newAccount(Model model) { - model.addAttribute("accounttypes", AccountType.valueList()); + final ResponseEntity> accountGroupResponse = new GetAllAccountGroupsTemplate() + .exchange(this.financerConfig); + + model.addAttribute("accountGroups", ControllerUtils.sortAccountGroups(accountGroupResponse.getBody())); + model.addAttribute("accountTypes", AccountType.valueList()); model.addAttribute("form", new NewAccountForm()); ControllerUtils.addVersionAttribute(model, this.financerConfig); @@ -57,14 +61,19 @@ public class AccountController { final UriComponentsBuilder builder = UriComponentsBuilder .fromHttpUrl(ControllerUtils.buildUrl(this.financerConfig, Function.ACC_CREATE_ACCOUNT)) .queryParam("key", form.getKey()) + .queryParam("accountGroupName", form.getGroup()) .queryParam("type", form.getType()); final ResponseEntity response = new StringTemplate().exchange(builder); final ResponseReason responseReason = ResponseReason.fromResponseEntity(response); if (!ResponseReason.OK.equals(responseReason)) { + final ResponseEntity> accountGroupResponse = new GetAllAccountGroupsTemplate() + .exchange(this.financerConfig); + model.addAttribute("form", form); - model.addAttribute("accounttypes", AccountType.valueList()); + model.addAttribute("accountGroups", ControllerUtils.sortAccountGroups(accountGroupResponse.getBody())); + model.addAttribute("accountTypes", AccountType.valueList()); model.addAttribute("errorMessage", responseReason.name()); ControllerUtils.addVersionAttribute(model, this.financerConfig); diff --git a/src/main/java/de/financer/controller/AccountGroupController.java b/src/main/java/de/financer/controller/AccountGroupController.java new file mode 100644 index 0000000..047d330 --- /dev/null +++ b/src/main/java/de/financer/controller/AccountGroupController.java @@ -0,0 +1,48 @@ +package de.financer.controller; + +import de.financer.ResponseReason; +import de.financer.config.FinancerConfig; +import de.financer.controller.template.StringTemplate; +import de.financer.form.NewAccountGroupForm; +import de.financer.util.ControllerUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.util.UriComponentsBuilder; + +@Controller +public class AccountGroupController { + @Autowired + private FinancerConfig financerConfig; + + @GetMapping("/newAccountGroup") + public String newAccountGroup(Model model) { + model.addAttribute("form", new NewAccountGroupForm()); + ControllerUtils.addVersionAttribute(model, this.financerConfig); + + return "accountGroup/newAccountGroup"; + } + + @PostMapping("/saveAccountGroup") + public String saveAccontGroup(NewAccountGroupForm form, Model model) { + final UriComponentsBuilder builder = UriComponentsBuilder + .fromHttpUrl(ControllerUtils.buildUrl(this.financerConfig, Function.ACC_GP_CREATE_ACCOUNT_GROUP)) + .queryParam("name", form.getName()); + + final ResponseEntity response = new StringTemplate().exchange(builder); + final ResponseReason responseReason = ResponseReason.fromResponseEntity(response); + + if (!ResponseReason.OK.equals(responseReason)) { + model.addAttribute("form", form); + model.addAttribute("errorMessage", responseReason.name()); + ControllerUtils.addVersionAttribute(model, this.financerConfig); + + return "accountGroup/newAccountGroup"; + } + + return "redirect:/accountOverview"; + } +} diff --git a/src/main/java/de/financer/controller/Function.java b/src/main/java/de/financer/controller/Function.java index e97bdcb..602a4fd 100644 --- a/src/main/java/de/financer/controller/Function.java +++ b/src/main/java/de/financer/controller/Function.java @@ -7,6 +7,9 @@ public enum Function { ACC_CLOSE_ACCOUNT("accounts/closeAccount"), ACC_OPEN_ACCOUNT("accounts/openAccount"), + ACC_GP_CREATE_ACCOUNT_GROUP("accountGroups/createAccountGroup"), + ACC_GP_GET_ALL("accountGroups/getAll"), + TR_GET_ALL("transactions/getAll"), TR_GET_ALL_FOR_ACCOUNT("transactions/getAllForAccount"), TR_CREATE_TRANSACTION("transactions/createTransaction"), diff --git a/src/main/java/de/financer/controller/template/GetAllAccountGroupsTemplate.java b/src/main/java/de/financer/controller/template/GetAllAccountGroupsTemplate.java new file mode 100644 index 0000000..46b2ecc --- /dev/null +++ b/src/main/java/de/financer/controller/template/GetAllAccountGroupsTemplate.java @@ -0,0 +1,16 @@ +package de.financer.controller.template; + +import de.financer.config.FinancerConfig; +import de.financer.controller.Function; +import de.financer.model.AccountGroup; +import de.financer.util.ControllerUtils; +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.http.ResponseEntity; + +public class GetAllAccountGroupsTemplate { + public ResponseEntity> exchange(FinancerConfig financerConfig) { + return new FinancerRestTemplate>().exchange(ControllerUtils + .buildUrl(financerConfig, Function.ACC_GP_GET_ALL), new ParameterizedTypeReference>() { + }); + } +} diff --git a/src/main/java/de/financer/form/NewAccountForm.java b/src/main/java/de/financer/form/NewAccountForm.java index fd3218d..dea8a7d 100644 --- a/src/main/java/de/financer/form/NewAccountForm.java +++ b/src/main/java/de/financer/form/NewAccountForm.java @@ -3,6 +3,7 @@ package de.financer.form; public class NewAccountForm { private String key; private String type; + private String group; public String getKey() { return key; @@ -19,4 +20,12 @@ public class NewAccountForm { public void setType(String type) { this.type = type; } + + public String getGroup() { + return group; + } + + public void setGroup(String group) { + this.group = group; + } } diff --git a/src/main/java/de/financer/form/NewAccountGroupForm.java b/src/main/java/de/financer/form/NewAccountGroupForm.java new file mode 100644 index 0000000..4872398 --- /dev/null +++ b/src/main/java/de/financer/form/NewAccountGroupForm.java @@ -0,0 +1,13 @@ +package de.financer.form; + +public class NewAccountGroupForm { + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/src/main/java/de/financer/model/Account.java b/src/main/java/de/financer/model/Account.java index 0e4101e..50d0ff3 100644 --- a/src/main/java/de/financer/model/Account.java +++ b/src/main/java/de/financer/model/Account.java @@ -6,6 +6,7 @@ public class Account { private AccountType type; private AccountStatus status; private Long currentBalance; + private AccountGroup accountGroup; public Long getId() { return id; @@ -42,4 +43,12 @@ public class Account { public void setCurrentBalance(Long currentBalance) { this.currentBalance = currentBalance; } + + public AccountGroup getAccountGroup() { + return accountGroup; + } + + public void setAccountGroup(AccountGroup accountGroup) { + this.accountGroup = accountGroup; + } } diff --git a/src/main/java/de/financer/model/AccountGroup.java b/src/main/java/de/financer/model/AccountGroup.java new file mode 100644 index 0000000..8e0a90f --- /dev/null +++ b/src/main/java/de/financer/model/AccountGroup.java @@ -0,0 +1,18 @@ +package de.financer.model; + +public class AccountGroup { + private Long id; + private String name; + + public Long getId() { + return id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/src/main/java/de/financer/util/ControllerUtils.java b/src/main/java/de/financer/util/ControllerUtils.java index 6843801..d167e6c 100644 --- a/src/main/java/de/financer/util/ControllerUtils.java +++ b/src/main/java/de/financer/util/ControllerUtils.java @@ -3,6 +3,7 @@ package de.financer.util; import de.financer.config.FinancerConfig; import de.financer.controller.Function; import de.financer.model.Account; +import de.financer.model.AccountGroup; import de.financer.model.AccountStatus; import de.financer.model.RecurringTransaction; import de.financer.util.comparator.AccountByTypeByIdComparator; @@ -12,6 +13,7 @@ import org.springframework.ui.Model; import java.time.LocalDate; import java.time.format.DateTimeFormatter; +import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; @@ -32,6 +34,12 @@ public class ControllerUtils { .collect(Collectors.toList()); } + public static List sortAccountGroups(Iterable accountGroups) { + return IterableUtils.toList(accountGroups).stream() + .sorted(Comparator.comparing(AccountGroup::getName)) + .collect(Collectors.toList()); + } + public static String formatDate(FinancerConfig financerConfig, String dateFromForm) { if (StringUtils.isEmpty(dateFromForm)) { return null; diff --git a/src/main/resources/i18n/message.properties b/src/main/resources/i18n/message.properties index daf3ce3..9d7b159 100644 --- a/src/main/resources/i18n/message.properties +++ b/src/main/resources/i18n/message.properties @@ -6,11 +6,13 @@ financer.account-overview.available-actions.create-account=Create new account financer.account-overview.available-actions.create-transaction=Create new transaction financer.account-overview.available-actions.create-recurring-transaction=Create new recurring transaction financer.account-overview.available-actions.recurring-transaction-all=Show all recurring transactions +financer.account-overview.available-actions.create-account-group=Create new account group financer.account-overview.status=Status\: 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.table-header.id=ID -financer.account-overview.table-header.key=Key +financer.account-overview.table-header.key=Account +financer.account-overview.table-header.group=Group financer.account-overview.table-header.balance=Current Balance financer.account-overview.table-header.type=Type financer.account-overview.table-header.status=Status @@ -18,8 +20,13 @@ financer.account-overview.table-header.status=Status financer.account-new.title=financer\: create new account financer.account-new.label.key=Key\: financer.account-new.label.type=Type\: +financer.account-new.label.group=Group\: financer.account-new.submit=Create account +financer.account-group-new.title=financer\: create new account group +financer.account-group-new.label.name=Name\: +financer.account-group-new.submit=Create account group + financer.transaction-new.title=financer\: create new transaction financer.transaction-new.label.from-account=From account\: financer.transaction-new.label.to-account=To account\: @@ -83,7 +90,8 @@ financer.account-details.table-header.amount=Amount financer.account-details.table-header.description=Description financer.account-details.table-header.byRecurring=Recurring? financer.account-details.details.type=Type\: -financer.account-details.details.balance=Current Balance\: +financer.account-details.details.balance=Current balance\: +financer.account-details.details.group=Group\: financer.account-details.table-header.actions=Actions financer.account-details.table.actions.deleteTransaction=Delete @@ -114,6 +122,7 @@ financer.account-status.CLOSED=Closed financer.heading.transaction-new=financer\: create new transaction financer.heading.recurring-transaction-new=financer\: create new recurring transaction financer.heading.account-new=financer\: create new account +financer.heading.account-group-new=financer\: create new account group financer.heading.account-overview=financer\: overview financer.heading.account-details=financer\: account details for {0} financer.heading.recurring-transaction-list.dueToday=financer\: recurring transactions due today @@ -145,4 +154,6 @@ financer.error-message.MISSING_TRANSACTION_ID=No transaction entered! financer.error-message.INVALID_TRANSACTION_ID=The transaction is not valid! financer.error-message.TRANSACTION_NOT_FOUND=The transaction could not be found! financer.error-message.ACCOUNT_NOT_FOUND=The account could not be found! -financer.error-message.DUPLICATE_ACCOUNT_KEY=An account with the given key already exists! \ No newline at end of file +financer.error-message.DUPLICATE_ACCOUNT_KEY=An account with the given key already exists! +financer.error-message.DUPLICATE_ACCOUNT_GROUP_NAME=An account group with the given key already exists! +financer.error-message.ACCOUNT_GROUP_NOT_FOUND=The account group could not be found! \ No newline at end of file diff --git a/src/main/resources/i18n/message_de_DE.properties b/src/main/resources/i18n/message_de_DE.properties index d91e4b9..ddb1924 100644 --- a/src/main/resources/i18n/message_de_DE.properties +++ b/src/main/resources/i18n/message_de_DE.properties @@ -6,11 +6,13 @@ financer.account-overview.available-actions.create-account=Neues Konto erstellen financer.account-overview.available-actions.create-transaction=Neue Buchung erstellen financer.account-overview.available-actions.create-recurring-transaction=Neue wiederkehrende Buchung erstellen financer.account-overview.available-actions.recurring-transaction-all=Zeige alle wiederkehrende Buchungen +financer.account-overview.available-actions.create-account-group=Neue Konto-Gruppe erstellen financer.account-overview.status=Status\: 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.table-header.id=ID -financer.account-overview.table-header.key=Schl\u00FCssel +financer.account-overview.table-header.key=Konto +financer.account-overview.table-header.group=Gruppe financer.account-overview.table-header.balance=Kontostand financer.account-overview.table-header.type=Typ financer.account-overview.table-header.status=Status @@ -18,7 +20,12 @@ financer.account-overview.table-header.status=Status financer.account-new.title=financer\: Neues Konto erstellen financer.account-new.label.key=Schl\u00FCssel\: financer.account-new.label.type=Typ\: -financer.account-new.submit=Account erstellen +financer.account-new.label.group=Gruppe\: +financer.account-new.submit=Konto erstellen + +financer.account-group-new.title=financer\: Neue Konto-Gruppe erstellen +financer.account-group-new.label.name=Name\: +financer.account-group-new.submit=Konto-Gruppe erstellen financer.transaction-new.title=financer\: Neue Buchung erstellen financer.transaction-new.label.from-account=Von Konto\: @@ -84,6 +91,7 @@ financer.account-details.table-header.description=Beschreibung financer.account-details.table-header.byRecurring=Wiederkehrend? financer.account-details.details.type=Typ\: financer.account-details.details.balance=Kontostand\: +financer.account-details.details.group=Gruppe\: financer.account-details.table-header.actions=Aktionen financer.account-details.table.actions.deleteTransaction=L\u00F6schen @@ -114,6 +122,7 @@ financer.account-status.CLOSED=Geschlossen financer.heading.transaction-new=financer\: Neue Buchung erstellen financer.heading.recurring-transaction-new=financer\: Neue wiederkehrende Buchung erstellen financer.heading.account-new=financer\: Neues Konto erstellen +financer.heading.account-group-new=financer\: Neue Konto-Gruppe erstellen financer.heading.account-overview=financer\: \u00DCbersicht financer.heading.account-details=financer\: Kontodetails f\u00FCr {0} financer.heading.recurring-transaction-list.dueToday=financer\: wiederkehrende Buchungen heute f\u00E4llig diff --git a/src/main/resources/static/css/main.css b/src/main/resources/static/css/main.css index d3ef84a..fc642c3 100644 --- a/src/main/resources/static/css/main.css +++ b/src/main/resources/static/css/main.css @@ -32,9 +32,19 @@ tr:hover { #new-recurring-transaction-form * { width: 100% !important; } + #action-container * { + display: block !important; + margin-bottom: 0.1em; + } } -#action-container *, +#action-container * { + display: inline-grid; + padding-inline-end: 0.2em; + margin-bottom: 0.2em; +} + +#account-details-action-container *, #recurring-transaction-list-table-actions-container *, #account-transaction-table-actions-container * { display: block; @@ -56,7 +66,8 @@ tr:hover { #new-account-form *, #new-transaction-form *, #new-recurring-transaction-form *, -#recurring-to-transaction-with-amount-form * { +#recurring-to-transaction-with-amount-form *, +#new-account-group-form * { display: block; margin-top: 1em; width: 20em; diff --git a/src/main/resources/templates/account/accountDetails.html b/src/main/resources/templates/account/accountDetails.html index 73cf347..e393186 100644 --- a/src/main/resources/templates/account/accountDetails.html +++ b/src/main/resources/templates/account/accountDetails.html @@ -18,8 +18,12 @@ +
+ + +
- + @@ -46,6 +54,7 @@ diff --git a/src/main/resources/templates/account/newAccount.html b/src/main/resources/templates/account/newAccount.html index e26e3c4..7a10e30 100644 --- a/src/main/resources/templates/account/newAccount.html +++ b/src/main/resources/templates/account/newAccount.html @@ -14,7 +14,11 @@
+
+