Added historical balance checker and cleaned up actions layout on account page.
This commit is contained in:
parent
104de66a66
commit
6bafd06fc0
|
@ -2,17 +2,25 @@ package com.andrewlalis.perfin.control;
|
||||||
|
|
||||||
import com.andrewlalis.javafx_scene_router.RouteSelectionListener;
|
import com.andrewlalis.javafx_scene_router.RouteSelectionListener;
|
||||||
import com.andrewlalis.perfin.data.AccountRepository;
|
import com.andrewlalis.perfin.data.AccountRepository;
|
||||||
|
import com.andrewlalis.perfin.data.util.CurrencyUtil;
|
||||||
import com.andrewlalis.perfin.data.util.DateUtil;
|
import com.andrewlalis.perfin.data.util.DateUtil;
|
||||||
import com.andrewlalis.perfin.model.Account;
|
import com.andrewlalis.perfin.model.Account;
|
||||||
|
import com.andrewlalis.perfin.model.MoneyValue;
|
||||||
import com.andrewlalis.perfin.model.Profile;
|
import com.andrewlalis.perfin.model.Profile;
|
||||||
import com.andrewlalis.perfin.view.component.AccountHistoryView;
|
import com.andrewlalis.perfin.view.component.AccountHistoryView;
|
||||||
|
import com.andrewlalis.perfin.view.component.validation.ValidationApplier;
|
||||||
|
import com.andrewlalis.perfin.view.component.validation.validators.PredicateValidator;
|
||||||
|
import javafx.application.Platform;
|
||||||
import javafx.beans.binding.BooleanExpression;
|
import javafx.beans.binding.BooleanExpression;
|
||||||
import javafx.beans.property.BooleanProperty;
|
import javafx.beans.property.BooleanProperty;
|
||||||
import javafx.beans.property.SimpleBooleanProperty;
|
import javafx.beans.property.SimpleBooleanProperty;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.scene.control.Button;
|
import javafx.scene.control.Button;
|
||||||
|
import javafx.scene.control.DatePicker;
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
import javafx.scene.layout.VBox;
|
import javafx.scene.layout.HBox;
|
||||||
|
|
||||||
|
import java.time.*;
|
||||||
|
|
||||||
import static com.andrewlalis.perfin.PerfinApp.router;
|
import static com.andrewlalis.perfin.PerfinApp.router;
|
||||||
|
|
||||||
|
@ -30,10 +38,13 @@ public class AccountViewController implements RouteSelectionListener {
|
||||||
|
|
||||||
@FXML public AccountHistoryView accountHistory;
|
@FXML public AccountHistoryView accountHistory;
|
||||||
|
|
||||||
@FXML public VBox actionsVBox;
|
@FXML public HBox actionsBox;
|
||||||
|
|
||||||
|
@FXML public DatePicker balanceCheckerDatePicker;
|
||||||
|
@FXML public Button balanceCheckerButton;
|
||||||
|
|
||||||
@FXML public void initialize() {
|
@FXML public void initialize() {
|
||||||
actionsVBox.getChildren().forEach(node -> {
|
actionsBox.getChildren().forEach(node -> {
|
||||||
Button button = (Button) node;
|
Button button = (Button) node;
|
||||||
BooleanExpression buttonActive = accountArchivedProperty;
|
BooleanExpression buttonActive = accountArchivedProperty;
|
||||||
if (button.getText().equalsIgnoreCase("Unarchive")) {
|
if (button.getText().equalsIgnoreCase("Unarchive")) {
|
||||||
|
@ -43,6 +54,28 @@ public class AccountViewController implements RouteSelectionListener {
|
||||||
button.managedProperty().bind(button.visibleProperty());
|
button.managedProperty().bind(button.visibleProperty());
|
||||||
button.visibleProperty().bind(button.disableProperty().not());
|
button.visibleProperty().bind(button.disableProperty().not());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var datePickerValid = new ValidationApplier<>(new PredicateValidator<LocalDate>()
|
||||||
|
.addPredicate(date -> date.isBefore(LocalDate.now()), "Date must be in the past.")
|
||||||
|
).attach(balanceCheckerDatePicker, balanceCheckerDatePicker.valueProperty());
|
||||||
|
balanceCheckerButton.disableProperty().bind(datePickerValid.not());
|
||||||
|
balanceCheckerButton.setOnAction(event -> {
|
||||||
|
LocalDate date = balanceCheckerDatePicker.getValue();
|
||||||
|
final Instant timestamp = date.atStartOfDay(ZoneId.systemDefault())
|
||||||
|
.withZoneSameInstant(ZoneOffset.UTC)
|
||||||
|
.toInstant();
|
||||||
|
Profile.getCurrent().dataSource().mapRepoAsync(
|
||||||
|
AccountRepository.class,
|
||||||
|
repo -> repo.deriveBalance(account.id, timestamp)
|
||||||
|
).thenAccept(balance -> Platform.runLater(() -> {
|
||||||
|
String msg = String.format(
|
||||||
|
"Your balance as of %s is %s, according to Perfin's data.",
|
||||||
|
date,
|
||||||
|
CurrencyUtil.formatMoney(new MoneyValue(balance, account.getCurrency()))
|
||||||
|
);
|
||||||
|
Popups.message(balanceCheckerButton, msg);
|
||||||
|
}));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -81,6 +81,7 @@ public class StyledText extends VBox {
|
||||||
idx = 0;
|
idx = 0;
|
||||||
currentRun.setLength(0);
|
currentRun.setLength(0);
|
||||||
currentParagraph = new TextFlow();
|
currentParagraph = new TextFlow();
|
||||||
|
currentParagraph.setStyle("-fx-text-fill: inherit;");
|
||||||
|
|
||||||
while (idx < text.length()) {
|
while (idx < text.length()) {
|
||||||
if (text.startsWith("**", idx)) {
|
if (text.startsWith("**", idx)) {
|
||||||
|
@ -118,6 +119,7 @@ public class StyledText extends VBox {
|
||||||
int endIdx = text.indexOf(marker, idx + marker.length());
|
int endIdx = text.indexOf(marker, idx + marker.length());
|
||||||
Text textItem = new Text(text.substring(idx + marker.length(), endIdx));
|
Text textItem = new Text(text.substring(idx + marker.length(), endIdx));
|
||||||
textItem.getStyleClass().add(styleClass);
|
textItem.getStyleClass().add(styleClass);
|
||||||
|
textItem.setStyle("-fx-text-fill: inherit;");
|
||||||
currentParagraph.getChildren().add(textItem);
|
currentParagraph.getChildren().add(textItem);
|
||||||
idx = endIdx + marker.length();
|
idx = endIdx + marker.length();
|
||||||
}
|
}
|
||||||
|
@ -183,6 +185,7 @@ public class StyledText extends VBox {
|
||||||
if (!currentParagraph.getChildren().isEmpty()) {
|
if (!currentParagraph.getChildren().isEmpty()) {
|
||||||
flows.add(currentParagraph);
|
flows.add(currentParagraph);
|
||||||
currentParagraph = new TextFlow();
|
currentParagraph = new TextFlow();
|
||||||
|
currentParagraph.setStyle("-fx-text-fill: inherit;");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
<?import javafx.scene.control.*?>
|
<?import javafx.scene.control.*?>
|
||||||
<?import javafx.scene.layout.*?>
|
<?import javafx.scene.layout.*?>
|
||||||
<?import javafx.scene.text.Text?>
|
<?import javafx.scene.text.Text?>
|
||||||
|
<?import com.andrewlalis.perfin.view.component.StyledText?>
|
||||||
|
<?import javafx.scene.text.TextFlow?>
|
||||||
<BorderPane
|
<BorderPane
|
||||||
xmlns="http://javafx.com/javafx"
|
xmlns="http://javafx.com/javafx"
|
||||||
xmlns:fx="http://javafx.com/fxml"
|
xmlns:fx="http://javafx.com/fxml"
|
||||||
|
@ -16,10 +18,7 @@
|
||||||
<center>
|
<center>
|
||||||
<VBox>
|
<VBox>
|
||||||
<!-- Main account properties and actions -->
|
<!-- Main account properties and actions -->
|
||||||
<BorderPane>
|
<FlowPane styleClass="std-padding,std-spacing">
|
||||||
<center>
|
|
||||||
<VBox styleClass="std-padding,std-spacing">
|
|
||||||
<FlowPane>
|
|
||||||
<!-- Main account properties. -->
|
<!-- Main account properties. -->
|
||||||
<PropertiesPane vgap="5" hgap="5">
|
<PropertiesPane vgap="5" hgap="5">
|
||||||
<Label text="Name" styleClass="bold-text"/>
|
<Label text="Name" styleClass="bold-text"/>
|
||||||
|
@ -44,21 +43,35 @@
|
||||||
<Label fx:id="accountBalanceLabel" styleClass="mono-font"/>
|
<Label fx:id="accountBalanceLabel" styleClass="mono-font"/>
|
||||||
</PropertiesPane>
|
</PropertiesPane>
|
||||||
</FlowPane>
|
</FlowPane>
|
||||||
</VBox>
|
|
||||||
</center>
|
<!-- Action buttons -->
|
||||||
<right>
|
<HBox fx:id="actionsBox" styleClass="std-padding,std-spacing,small-font">
|
||||||
|
<Button text="Edit" onAction="#goToEditPage"/>
|
||||||
|
<Button text="Record Balance" onAction="#goToCreateBalanceRecord"/>
|
||||||
|
<Button text="Archive" onAction="#archiveAccount"/>
|
||||||
|
<Button text="Delete" onAction="#deleteAccount"/>
|
||||||
|
<Button text="Unarchive" onAction="#unarchiveAccount"/>
|
||||||
|
</HBox>
|
||||||
|
|
||||||
|
<!-- Historical Balance Checker -->
|
||||||
<VBox styleClass="std-padding,std-spacing">
|
<VBox styleClass="std-padding,std-spacing">
|
||||||
<Label text="Actions" styleClass="bold-text"/>
|
<HBox styleClass="std-spacing">
|
||||||
<VBox fx:id="actionsVBox" styleClass="std-spacing">
|
<AnchorPane>
|
||||||
<Button text="Edit" onAction="#goToEditPage" maxWidth="Infinity"/>
|
<Label text="Check Historical Balance" styleClass="bold-text" AnchorPane.topAnchor="0" AnchorPane.bottomAnchor="0" AnchorPane.leftAnchor="0"/>
|
||||||
<Button text="Record Balance" onAction="#goToCreateBalanceRecord" maxWidth="Infinity"/>
|
</AnchorPane>
|
||||||
<Button text="Archive" onAction="#archiveAccount" maxWidth="Infinity"/>
|
<DatePicker fx:id="balanceCheckerDatePicker"/>
|
||||||
<Button text="Delete" onAction="#deleteAccount" maxWidth="Infinity"/>
|
<Button text="Check" fx:id="balanceCheckerButton"/>
|
||||||
<Button text="Unarchive" onAction="#unarchiveAccount" maxWidth="Infinity"/>
|
</HBox>
|
||||||
|
<TextFlow maxWidth="500">
|
||||||
|
<Text styleClass="small-font,secondary-color-fill">
|
||||||
|
Use this tool to check the balance of this account on any
|
||||||
|
given day in the past. Perfin will compute the balance
|
||||||
|
according to any balance records and transactions it finds
|
||||||
|
around that time.
|
||||||
|
</Text>
|
||||||
|
</TextFlow>
|
||||||
</VBox>
|
</VBox>
|
||||||
</VBox>
|
|
||||||
</right>
|
|
||||||
</BorderPane>
|
|
||||||
|
|
||||||
<!-- Account history -->
|
<!-- Account history -->
|
||||||
<VBox VBox.vgrow="ALWAYS">
|
<VBox VBox.vgrow="ALWAYS">
|
||||||
|
|
Loading…
Reference in New Issue