diff --git a/src/main/java/com/andrewlalis/perfin/control/EditTransactionController.java b/src/main/java/com/andrewlalis/perfin/control/EditTransactionController.java index 6150129..220e120 100644 --- a/src/main/java/com/andrewlalis/perfin/control/EditTransactionController.java +++ b/src/main/java/com/andrewlalis/perfin/control/EditTransactionController.java @@ -82,6 +82,13 @@ public class EditTransactionController implements RouteSelectionListener { accounts -> (!accounts.hasCredit() || !accounts.hasDebit()) || !accounts.creditAccount().equals(accounts.debitAccount()), "The credit and debit accounts cannot be the same." ) + .addPredicate( + accounts -> ( + (!accounts.hasCredit() || accounts.creditAccount().getCurrency().equals(currencyChoiceBox.getValue())) || + (!accounts.hasDebit() || accounts.debitAccount().getCurrency().equals(currencyChoiceBox.getValue())) + ), + "Linked accounts must use the same currency." + ) ).validatedInitially().attach(linkedAccountsContainer, linkedAccountsProperty); var formValid = timestampValid.and(amountValid).and(descriptionValid).and(linkedAccountsValid); diff --git a/src/main/java/com/andrewlalis/perfin/view/component/AccountSelectionBox.java b/src/main/java/com/andrewlalis/perfin/view/component/AccountSelectionBox.java index 0f0b91f..022e92e 100644 --- a/src/main/java/com/andrewlalis/perfin/view/component/AccountSelectionBox.java +++ b/src/main/java/com/andrewlalis/perfin/view/component/AccountSelectionBox.java @@ -1,26 +1,32 @@ package com.andrewlalis.perfin.view.component; +import com.andrewlalis.perfin.data.util.CurrencyUtil; import com.andrewlalis.perfin.model.Account; +import com.andrewlalis.perfin.model.MoneyValue; +import com.andrewlalis.perfin.model.Profile; +import javafx.application.Platform; import javafx.beans.property.BooleanProperty; import javafx.beans.property.SimpleBooleanProperty; import javafx.scene.control.ComboBox; import javafx.scene.control.Label; import javafx.scene.control.ListCell; import javafx.scene.control.ListView; +import javafx.scene.layout.VBox; import javafx.util.Callback; +import java.math.BigDecimal; import java.util.List; /** * A box that allows the user to select one account from a list of options. */ public class AccountSelectionBox extends ComboBox { - private final CellFactory cellFactory = new CellFactory(); private final BooleanProperty allowNoneProperty = new SimpleBooleanProperty(true); + private final BooleanProperty showBalanceProperty = new SimpleBooleanProperty(false); public AccountSelectionBox() { - setCellFactory(cellFactory); - setButtonCell(cellFactory.call(null)); + setCellFactory(new CellFactory(showBalanceProperty)); + setButtonCell(new AccountListCell(new SimpleBooleanProperty(false))); } public void setAccounts(List accounts) { @@ -37,7 +43,7 @@ public class AccountSelectionBox extends ComboBox { } public void select(Account account) { - setButtonCell(cellFactory.call(null)); + setButtonCell(new AccountListCell(new SimpleBooleanProperty(false))); getSelectionModel().select(account); } @@ -53,28 +59,63 @@ public class AccountSelectionBox extends ComboBox { allowNoneProperty.set(value); } + public final BooleanProperty showBalanceProperty() { + return showBalanceProperty; + } + + public final boolean getShowBalance() { + return showBalanceProperty.get(); + } + + public final void setShowBalance(boolean value) { + showBalanceProperty.set(value); + } + private static class CellFactory implements Callback, ListCell> { + private final BooleanProperty showBalanceProp; + + private CellFactory(BooleanProperty showBalanceProp) { + this.showBalanceProp = showBalanceProp; + } + @Override public ListCell call(ListView param) { - return new AccountListCell(); + return new AccountListCell(showBalanceProp); } } private static class AccountListCell extends ListCell { - private final Label label = new Label(); + private final BooleanProperty showBalanceProp; + private final Label nameLabel = new Label(); + private final Label balanceLabel = new Label(); - public AccountListCell() { - setGraphic(label); - label.getStyleClass().add("normal-color-text-fill"); + public AccountListCell(BooleanProperty showBalanceProp) { + this.showBalanceProp = showBalanceProp; + nameLabel.getStyleClass().add("normal-color-text-fill"); + balanceLabel.getStyleClass().addAll("secondary-color-text-fill", "mono-font", "smallest-font", "italic-text"); + balanceLabel.managedProperty().bind(balanceLabel.visibleProperty()); + balanceLabel.setVisible(false); + setGraphic(new VBox(nameLabel, balanceLabel)); } @Override protected void updateItem(Account item, boolean empty) { super.updateItem(item, empty); if (item == null || empty) { - label.setText("None"); - } else { - label.setText(item.getName() + " " + item.getAccountNumberSuffix()); + nameLabel.setText("None"); + balanceLabel.setVisible(false); + return; + } + + nameLabel.setText(item.getName() + " (" + item.getAccountNumberSuffix() + ")"); + if (showBalanceProp.get()) { + Thread.ofVirtual().start(() -> Profile.getCurrent().getDataSource().useAccountRepository(repo -> { + BigDecimal balance = repo.deriveCurrentBalance(item.id); + Platform.runLater(() -> { + balanceLabel.setText(CurrencyUtil.formatMoney(new MoneyValue(balance, item.getCurrency()))); + balanceLabel.setVisible(true); + }); + })); } } } diff --git a/src/main/resources/edit-transaction.fxml b/src/main/resources/edit-transaction.fxml index 37c4d17..088d234 100644 --- a/src/main/resources/edit-transaction.fxml +++ b/src/main/resources/edit-transaction.fxml @@ -43,11 +43,11 @@