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.perfin.data.AccountRepository;
 | 
			
		||||
import com.andrewlalis.perfin.data.util.CurrencyUtil;
 | 
			
		||||
import com.andrewlalis.perfin.data.util.DateUtil;
 | 
			
		||||
import com.andrewlalis.perfin.model.Account;
 | 
			
		||||
import com.andrewlalis.perfin.model.MoneyValue;
 | 
			
		||||
import com.andrewlalis.perfin.model.Profile;
 | 
			
		||||
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.property.BooleanProperty;
 | 
			
		||||
import javafx.beans.property.SimpleBooleanProperty;
 | 
			
		||||
import javafx.fxml.FXML;
 | 
			
		||||
import javafx.scene.control.Button;
 | 
			
		||||
import javafx.scene.control.DatePicker;
 | 
			
		||||
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;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -30,10 +38,13 @@ public class AccountViewController implements RouteSelectionListener {
 | 
			
		|||
 | 
			
		||||
    @FXML public AccountHistoryView accountHistory;
 | 
			
		||||
 | 
			
		||||
    @FXML public VBox actionsVBox;
 | 
			
		||||
    @FXML public HBox actionsBox;
 | 
			
		||||
 | 
			
		||||
    @FXML public DatePicker balanceCheckerDatePicker;
 | 
			
		||||
    @FXML public Button balanceCheckerButton;
 | 
			
		||||
 | 
			
		||||
    @FXML public void initialize() {
 | 
			
		||||
        actionsVBox.getChildren().forEach(node -> {
 | 
			
		||||
        actionsBox.getChildren().forEach(node -> {
 | 
			
		||||
            Button button = (Button) node;
 | 
			
		||||
            BooleanExpression buttonActive = accountArchivedProperty;
 | 
			
		||||
            if (button.getText().equalsIgnoreCase("Unarchive")) {
 | 
			
		||||
| 
						 | 
				
			
			@ -43,6 +54,28 @@ public class AccountViewController implements RouteSelectionListener {
 | 
			
		|||
            button.managedProperty().bind(button.visibleProperty());
 | 
			
		||||
            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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -81,6 +81,7 @@ public class StyledText extends VBox {
 | 
			
		|||
            idx = 0;
 | 
			
		||||
            currentRun.setLength(0);
 | 
			
		||||
            currentParagraph = new TextFlow();
 | 
			
		||||
            currentParagraph.setStyle("-fx-text-fill: inherit;");
 | 
			
		||||
 | 
			
		||||
            while (idx < text.length()) {
 | 
			
		||||
                if (text.startsWith("**", idx)) {
 | 
			
		||||
| 
						 | 
				
			
			@ -118,6 +119,7 @@ public class StyledText extends VBox {
 | 
			
		|||
            int endIdx = text.indexOf(marker, idx + marker.length());
 | 
			
		||||
            Text textItem = new Text(text.substring(idx + marker.length(), endIdx));
 | 
			
		||||
            textItem.getStyleClass().add(styleClass);
 | 
			
		||||
            textItem.setStyle("-fx-text-fill: inherit;");
 | 
			
		||||
            currentParagraph.getChildren().add(textItem);
 | 
			
		||||
            idx = endIdx + marker.length();
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -183,6 +185,7 @@ public class StyledText extends VBox {
 | 
			
		|||
            if (!currentParagraph.getChildren().isEmpty()) {
 | 
			
		||||
                flows.add(currentParagraph);
 | 
			
		||||
                currentParagraph = new TextFlow();
 | 
			
		||||
                currentParagraph.setStyle("-fx-text-fill: inherit;");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,6 +5,8 @@
 | 
			
		|||
<?import javafx.scene.control.*?>
 | 
			
		||||
<?import javafx.scene.layout.*?>
 | 
			
		||||
<?import javafx.scene.text.Text?>
 | 
			
		||||
<?import com.andrewlalis.perfin.view.component.StyledText?>
 | 
			
		||||
<?import javafx.scene.text.TextFlow?>
 | 
			
		||||
<BorderPane
 | 
			
		||||
        xmlns="http://javafx.com/javafx"
 | 
			
		||||
        xmlns:fx="http://javafx.com/fxml"
 | 
			
		||||
| 
						 | 
				
			
			@ -16,49 +18,60 @@
 | 
			
		|||
    <center>
 | 
			
		||||
        <VBox>
 | 
			
		||||
            <!-- Main account properties and actions -->
 | 
			
		||||
            <BorderPane>
 | 
			
		||||
                <center>
 | 
			
		||||
                    <VBox styleClass="std-padding,std-spacing">
 | 
			
		||||
                        <FlowPane>
 | 
			
		||||
                            <!-- Main account properties. -->
 | 
			
		||||
                            <PropertiesPane vgap="5" hgap="5">
 | 
			
		||||
                                <Label text="Name" styleClass="bold-text"/>
 | 
			
		||||
                                <Label fx:id="accountNameLabel"/>
 | 
			
		||||
            <FlowPane styleClass="std-padding,std-spacing">
 | 
			
		||||
                <!-- Main account properties. -->
 | 
			
		||||
                <PropertiesPane vgap="5" hgap="5">
 | 
			
		||||
                    <Label text="Name" styleClass="bold-text"/>
 | 
			
		||||
                    <Label fx:id="accountNameLabel"/>
 | 
			
		||||
 | 
			
		||||
                                <Label text="Number" styleClass="bold-text"/>
 | 
			
		||||
                                <Label fx:id="accountNumberLabel" styleClass="mono-font"/>
 | 
			
		||||
                    <Label text="Number" styleClass="bold-text"/>
 | 
			
		||||
                    <Label fx:id="accountNumberLabel" styleClass="mono-font"/>
 | 
			
		||||
 | 
			
		||||
                                <Label text="Currency" styleClass="bold-text"/>
 | 
			
		||||
                                <Label fx:id="accountCurrencyLabel"/>
 | 
			
		||||
                    <Label text="Currency" styleClass="bold-text"/>
 | 
			
		||||
                    <Label fx:id="accountCurrencyLabel"/>
 | 
			
		||||
 | 
			
		||||
                                <Label text="Created At" styleClass="bold-text"/>
 | 
			
		||||
                                <Label fx:id="accountCreatedAtLabel" styleClass="mono-font"/>
 | 
			
		||||
                    <Label text="Created At" styleClass="bold-text"/>
 | 
			
		||||
                    <Label fx:id="accountCreatedAtLabel" styleClass="mono-font"/>
 | 
			
		||||
 | 
			
		||||
                                <VBox>
 | 
			
		||||
                                    <Label text="Current Balance" styleClass="bold-text" fx:id="balanceLabel"/>
 | 
			
		||||
                                    <Text
 | 
			
		||||
                                            styleClass="small-font,secondary-color-fill"
 | 
			
		||||
                                            wrappingWidth="${balanceLabel.width}"
 | 
			
		||||
                                    >Computed using the last recorded balance and all transactions since.</Text>
 | 
			
		||||
                                </VBox>
 | 
			
		||||
                                <Label fx:id="accountBalanceLabel" styleClass="mono-font"/>
 | 
			
		||||
                            </PropertiesPane>
 | 
			
		||||
                        </FlowPane>
 | 
			
		||||
                    <VBox>
 | 
			
		||||
                        <Label text="Current Balance" styleClass="bold-text" fx:id="balanceLabel"/>
 | 
			
		||||
                        <Text
 | 
			
		||||
                                styleClass="small-font,secondary-color-fill"
 | 
			
		||||
                                wrappingWidth="${balanceLabel.width}"
 | 
			
		||||
                        >Computed using the last recorded balance and all transactions since.</Text>
 | 
			
		||||
                    </VBox>
 | 
			
		||||
                </center>
 | 
			
		||||
                <right>
 | 
			
		||||
                    <VBox styleClass="std-padding,std-spacing">
 | 
			
		||||
                        <Label text="Actions" styleClass="bold-text"/>
 | 
			
		||||
                        <VBox fx:id="actionsVBox" styleClass="std-spacing">
 | 
			
		||||
                            <Button text="Edit" onAction="#goToEditPage" maxWidth="Infinity"/>
 | 
			
		||||
                            <Button text="Record Balance" onAction="#goToCreateBalanceRecord" maxWidth="Infinity"/>
 | 
			
		||||
                            <Button text="Archive" onAction="#archiveAccount" maxWidth="Infinity"/>
 | 
			
		||||
                            <Button text="Delete" onAction="#deleteAccount" maxWidth="Infinity"/>
 | 
			
		||||
                            <Button text="Unarchive" onAction="#unarchiveAccount" maxWidth="Infinity"/>
 | 
			
		||||
                        </VBox>
 | 
			
		||||
                    </VBox>
 | 
			
		||||
                </right>
 | 
			
		||||
            </BorderPane>
 | 
			
		||||
                    <Label fx:id="accountBalanceLabel" styleClass="mono-font"/>
 | 
			
		||||
                </PropertiesPane>
 | 
			
		||||
            </FlowPane>
 | 
			
		||||
 | 
			
		||||
            <!-- Action buttons -->
 | 
			
		||||
            <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">
 | 
			
		||||
                <HBox styleClass="std-spacing">
 | 
			
		||||
                    <AnchorPane>
 | 
			
		||||
                        <Label text="Check Historical Balance" styleClass="bold-text" AnchorPane.topAnchor="0" AnchorPane.bottomAnchor="0" AnchorPane.leftAnchor="0"/>
 | 
			
		||||
                    </AnchorPane>
 | 
			
		||||
                    <DatePicker fx:id="balanceCheckerDatePicker"/>
 | 
			
		||||
                    <Button text="Check" fx:id="balanceCheckerButton"/>
 | 
			
		||||
                </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>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            <!-- Account history -->
 | 
			
		||||
            <VBox VBox.vgrow="ALWAYS">
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue