From 7ceaca7068a8f91775452ad55aad8fefa4d3cbe8 Mon Sep 17 00:00:00 2001 From: andrewlalis Date: Thu, 11 Jan 2024 08:46:57 -0500 Subject: [PATCH] Added start of transaction edit page. --- .../com/andrewlalis/perfin/PerfinApp.java | 2 +- ...er.java => EditTransactionController.java} | 66 +++++++++++++------ .../control/TransactionViewController.java | 4 ++ .../control/TransactionsViewController.java | 2 +- .../perfin/data/util/DateUtil.java | 6 ++ .../view/component/FileSelectionArea.java | 4 ++ ...transaction.fxml => edit-transaction.fxml} | 5 +- src/main/resources/transaction-view.fxml | 5 +- 8 files changed, 70 insertions(+), 24 deletions(-) rename src/main/java/com/andrewlalis/perfin/control/{CreateTransactionController.java => EditTransactionController.java} (74%) rename src/main/resources/{create-transaction.fxml => edit-transaction.fxml} (94%) diff --git a/src/main/java/com/andrewlalis/perfin/PerfinApp.java b/src/main/java/com/andrewlalis/perfin/PerfinApp.java index 73ff2f1..22b0fa6 100644 --- a/src/main/java/com/andrewlalis/perfin/PerfinApp.java +++ b/src/main/java/com/andrewlalis/perfin/PerfinApp.java @@ -84,7 +84,7 @@ public class PerfinApp extends Application { router.map("account", PerfinApp.class.getResource("/account-view.fxml")); router.map("edit-account", PerfinApp.class.getResource("/edit-account.fxml")); router.map("transactions", PerfinApp.class.getResource("/transactions-view.fxml")); - router.map("create-transaction", PerfinApp.class.getResource("/create-transaction.fxml")); + router.map("edit-transaction", PerfinApp.class.getResource("/edit-transaction.fxml")); router.map("create-balance-record", PerfinApp.class.getResource("/create-balance-record.fxml")); router.map("balance-record", PerfinApp.class.getResource("/balance-record-view.fxml")); diff --git a/src/main/java/com/andrewlalis/perfin/control/CreateTransactionController.java b/src/main/java/com/andrewlalis/perfin/control/EditTransactionController.java similarity index 74% rename from src/main/java/com/andrewlalis/perfin/control/CreateTransactionController.java rename to src/main/java/com/andrewlalis/perfin/control/EditTransactionController.java index f01e3d3..bb61ea4 100644 --- a/src/main/java/com/andrewlalis/perfin/control/CreateTransactionController.java +++ b/src/main/java/com/andrewlalis/perfin/control/EditTransactionController.java @@ -1,11 +1,13 @@ package com.andrewlalis.perfin.control; import com.andrewlalis.javafx_scene_router.RouteSelectionListener; +import com.andrewlalis.perfin.data.util.CurrencyUtil; import com.andrewlalis.perfin.data.util.DateUtil; import com.andrewlalis.perfin.data.util.FileUtil; import com.andrewlalis.perfin.model.Account; import com.andrewlalis.perfin.model.CreditAndDebitAccounts; import com.andrewlalis.perfin.model.Profile; +import com.andrewlalis.perfin.model.Transaction; import com.andrewlalis.perfin.view.AccountComboBoxCellFactory; import com.andrewlalis.perfin.view.component.FileSelectionArea; import com.andrewlalis.perfin.view.component.validation.ValidationApplier; @@ -31,7 +33,9 @@ import java.util.List; import static com.andrewlalis.perfin.PerfinApp.router; -public class CreateTransactionController implements RouteSelectionListener { +public class EditTransactionController implements RouteSelectionListener { + @FXML public Label titleLabel; + @FXML public TextField timestampField; @FXML public TextField amountField; @FXML public ChoiceBox currencyChoiceBox; @@ -55,15 +59,13 @@ public class CreateTransactionController implements RouteSelectionListener { return ts != null && ts.isBefore(LocalDateTime.now()); }, "Timestamp cannot be in the future.") ).validatedInitially().attachToTextField(timestampField); - var amountValid = new ValidationApplier<>( new CurrencyAmountValidator(() -> currencyChoiceBox.getValue(), false, false) ).validatedInitially().attachToTextField(amountField, currencyChoiceBox.valueProperty()); - var descriptionValid = new ValidationApplier<>(new PredicateValidator() .addTerminalPredicate(s -> s == null || s.length() <= 255, "Description is too long.") ).validatedInitially().attach(descriptionField, descriptionField.textProperty()); - + // Linked accounts will use a property derived from both the debit and credit selections. Property linkedAccountsProperty = new SimpleObjectProperty<>(getSelectedAccounts()); linkDebitAccountComboBox.valueProperty().addListener((observable, oldValue, newValue) -> linkedAccountsProperty.setValue(getSelectedAccounts())); linkCreditAccountComboBox.valueProperty().addListener((observable, oldValue, newValue) -> linkedAccountsProperty.setValue(getSelectedAccounts())); @@ -85,6 +87,7 @@ public class CreateTransactionController implements RouteSelectionListener { linkCreditAccountComboBox.setCellFactory(cellFactory); linkCreditAccountComboBox.setButtonCell(cellFactory.call(null)); currencyChoiceBox.valueProperty().addListener((observable, oldValue, newValue) -> { + System.out.println("Set currency to " + newValue); updateLinkAccountComboBoxes(newValue); }); @@ -123,25 +126,49 @@ public class CreateTransactionController implements RouteSelectionListener { @Override public void onRouteSelected(Object context) { - resetForm(); - } + Transaction transaction = (Transaction) context; + boolean creatingNew = transaction == null; - private void resetForm() { - timestampField.setText(LocalDateTime.now().format(DateUtil.DEFAULT_DATETIME_FORMAT)); - amountField.setText(null); - descriptionField.setText(null); - attachmentsSelectionArea.clear(); - Thread.ofVirtual().start(() -> { - Profile.getCurrent().getDataSource().useAccountRepository(repo -> { - var currencies = repo.findAllUsedCurrencies().stream() - .sorted(Comparator.comparing(Currency::getCurrencyCode)) - .toList(); + if (creatingNew) { + titleLabel.setText("Create New Transaction"); + timestampField.setText(LocalDateTime.now().format(DateUtil.DEFAULT_DATETIME_FORMAT)); + amountField.setText(null); + currencyChoiceBox.getSelectionModel().selectFirst(); + descriptionField.setText(null); + attachmentsSelectionArea.clear(); + + } else { + titleLabel.setText("Edit Transaction #" + transaction.id); + timestampField.setText(DateUtil.formatUTCAsLocal(transaction.getTimestamp())); + amountField.setText(CurrencyUtil.formatMoneyAsBasicNumber(transaction.getMoneyAmount())); + currencyChoiceBox.setValue(transaction.getCurrency()); + descriptionField.setText(transaction.getDescription()); + // TODO: Add an editable list of attachments from which some can be added and removed. + Thread.ofVirtual().start(() -> Profile.getCurrent().getDataSource().useTransactionRepository(repo -> { + CreditAndDebitAccounts accounts = repo.findLinkedAccounts(transaction.id); Platform.runLater(() -> { - currencyChoiceBox.getItems().setAll(currencies); - currencyChoiceBox.getSelectionModel().selectFirst(); + System.out.println(linkCreditAccountComboBox.getItems().indexOf(accounts.creditAccount())); +// linkCreditAccountComboBox.getSelectionModel().select(accounts.creditAccount()); +// linkCreditAccountComboBox.getButtonCell().updateIndex(linkCreditAccountComboBox.getSelectionModel().getSelectedIndex()); +// linkDebitAccountComboBox.getSelectionModel().select(accounts.debitAccount()); +// linkDebitAccountComboBox.getButtonCell().updateIndex(linkDebitAccountComboBox.getSelectionModel().getSelectedIndex()); }); + })); + } + + Thread.ofVirtual().start(() -> Profile.getCurrent().getDataSource().useAccountRepository(repo -> { + var currencies = repo.findAllUsedCurrencies().stream() + .sorted(Comparator.comparing(Currency::getCurrencyCode)) + .toList(); + Platform.runLater(() -> { + currencyChoiceBox.getItems().setAll(currencies); + if (creatingNew) { + currencyChoiceBox.getSelectionModel().selectFirst(); + } else { + currencyChoiceBox.getSelectionModel().select(transaction.getCurrency()); + } }); - }); + })); } private CreditAndDebitAccounts getSelectedAccounts() { @@ -186,6 +213,7 @@ public class CreateTransactionController implements RouteSelectionListener { linkCreditAccountComboBox.getItems().addAll(availableAccounts); linkCreditAccountComboBox.getSelectionModel().selectLast(); linkCreditAccountComboBox.getButtonCell().updateIndex(availableAccounts.size() - 1); + System.out.println("link account boxes updated."); }); }); }); diff --git a/src/main/java/com/andrewlalis/perfin/control/TransactionViewController.java b/src/main/java/com/andrewlalis/perfin/control/TransactionViewController.java index 1a9a10c..e62c156 100644 --- a/src/main/java/com/andrewlalis/perfin/control/TransactionViewController.java +++ b/src/main/java/com/andrewlalis/perfin/control/TransactionViewController.java @@ -69,6 +69,10 @@ public class TransactionViewController { }); } + @FXML public void editTransaction() { + router.navigate("edit-transaction", this.transaction); + } + @FXML public void deleteTransaction() { boolean confirm = Popups.confirm( "Are you sure you want to delete this transaction? This will " + diff --git a/src/main/java/com/andrewlalis/perfin/control/TransactionsViewController.java b/src/main/java/com/andrewlalis/perfin/control/TransactionsViewController.java index 4cf0e37..6394358 100644 --- a/src/main/java/com/andrewlalis/perfin/control/TransactionsViewController.java +++ b/src/main/java/com/andrewlalis/perfin/control/TransactionsViewController.java @@ -158,7 +158,7 @@ public class TransactionsViewController implements RouteSelectionListener { } @FXML public void addTransaction() { - router.navigate("create-transaction"); + router.navigate("edit-transaction"); } @FXML public void exportTransactions() { diff --git a/src/main/java/com/andrewlalis/perfin/data/util/DateUtil.java b/src/main/java/com/andrewlalis/perfin/data/util/DateUtil.java index 5a571fd..9baf682 100644 --- a/src/main/java/com/andrewlalis/perfin/data/util/DateUtil.java +++ b/src/main/java/com/andrewlalis/perfin/data/util/DateUtil.java @@ -18,6 +18,12 @@ public class DateUtil { .format(DEFAULT_DATETIME_FORMAT_WITH_ZONE); } + public static String formatUTCAsLocal(LocalDateTime utcTimestamp) { + return utcTimestamp.atOffset(ZoneOffset.UTC) + .atZoneSameInstant(ZoneId.systemDefault()) + .format(DEFAULT_DATETIME_FORMAT); + } + public static LocalDateTime localToUTC(LocalDateTime localTime, ZoneId localZone) { return localTime.atZone(localZone).withZoneSameInstant(ZoneOffset.UTC).toLocalDateTime(); } diff --git a/src/main/java/com/andrewlalis/perfin/view/component/FileSelectionArea.java b/src/main/java/com/andrewlalis/perfin/view/component/FileSelectionArea.java index 57b063c..53a77f6 100644 --- a/src/main/java/com/andrewlalis/perfin/view/component/FileSelectionArea.java +++ b/src/main/java/com/andrewlalis/perfin/view/component/FileSelectionArea.java @@ -61,6 +61,10 @@ public class FileSelectionArea extends VBox { selectedFiles.clear(); } + public void setSelectedFiles(List files) { + selectedFiles.setAll(files); + } + private Node buildFileItem(Path path) { Label filenameLabel = new Label(path.getFileName().toString()); filenameLabel.getStyleClass().addAll("mono-font"); diff --git a/src/main/resources/create-transaction.fxml b/src/main/resources/edit-transaction.fxml similarity index 94% rename from src/main/resources/create-transaction.fxml rename to src/main/resources/edit-transaction.fxml index d63b6a2..b18baf3 100644 --- a/src/main/resources/create-transaction.fxml +++ b/src/main/resources/edit-transaction.fxml @@ -5,8 +5,11 @@ + +
diff --git a/src/main/resources/transaction-view.fxml b/src/main/resources/transaction-view.fxml index cf21529..3fc2f7a 100644 --- a/src/main/resources/transaction-view.fxml +++ b/src/main/resources/transaction-view.fxml @@ -43,9 +43,10 @@ - + +