Fixed account editing.

This commit is contained in:
Andrew Lalis 2024-02-06 17:59:13 -05:00
parent 807259b2a5
commit abf132ec99
5 changed files with 52 additions and 56 deletions

View File

@ -1,8 +1,10 @@
package com.andrewlalis.perfin.control;
import com.andrewlalis.javafx_scene_router.RouteSelectionListener;
import com.andrewlalis.perfin.data.util.CurrencyUtil;
import com.andrewlalis.perfin.model.Account;
import com.andrewlalis.perfin.model.AccountType;
import com.andrewlalis.perfin.model.MoneyValue;
import com.andrewlalis.perfin.model.Profile;
import com.andrewlalis.perfin.view.component.PropertiesPane;
import com.andrewlalis.perfin.view.component.validation.ValidationApplier;
@ -52,20 +54,20 @@ public class EditAccountController implements RouteSelectionListener {
public void initialize() {
var nameValid = new ValidationApplier<>(new PredicateValidator<String>()
.addTerminalPredicate(s -> s != null && !s.isBlank(), "Name should not be empty.")
.addPredicate(s -> s.length() <= 63, "Name is too long.")
.addPredicate(s -> s.strip().length() <= 63, "Name is too long.")
).attachToTextField(accountNameField);
var numberValid = new ValidationApplier<>(new PredicateValidator<String>()
.addTerminalPredicate(s -> s != null && !s.isBlank(), "Account number should not be empty.")
.addPredicate(s -> s.length() <= 255, "Account number is too long.")
.addPredicate(s -> s.strip().length() <= 255, "Account number is too long.")
).attachToTextField(accountNumberField);
var balanceValid = new ValidationApplier<>(
new CurrencyAmountValidator(() -> accountCurrencyComboBox.getValue(), false, false)
new CurrencyAmountValidator(() -> accountCurrencyComboBox.getValue(), true, false)
).attachToTextField(initialBalanceField, accountCurrencyComboBox.valueProperty());
// Combine validity of all fields for an expression that determines if the whole form is valid.
BooleanExpression formValid = nameValid.and(numberValid).and(balanceValid);
BooleanExpression formValid = nameValid.and(numberValid).and(balanceValid.or(creatingNewAccount.not()));
saveButton.disableProperty().bind(formValid.not());
List<Currency> priorityCurrencies = Stream.of("USD", "EUR", "GBP", "CAD", "AUD")
@ -104,34 +106,35 @@ public class EditAccountController implements RouteSelectionListener {
@FXML
public void save() {
String name = accountNameField.getText().strip();
String number = accountNumberField.getText().strip();
AccountType type = accountTypeChoiceBox.getValue();
Currency currency = accountCurrencyComboBox.getValue();
try (
var accountRepo = Profile.getCurrent().dataSource().getAccountRepository();
var balanceRepo = Profile.getCurrent().dataSource().getBalanceRecordRepository()
) {
if (creatingNewAccount.get()) {
String name = accountNameField.getText().strip();
String number = accountNumberField.getText().strip();
AccountType type = accountTypeChoiceBox.getValue();
Currency currency = accountCurrencyComboBox.getValue();
BigDecimal initialBalance = new BigDecimal(initialBalanceField.getText().strip());
List<Path> attachments = Collections.emptyList();
boolean success = Popups.confirm(accountNameField, "Are you sure you want to create this account?");
String prompt = String.format(
"Are you sure you want to create this account?\nName: %s\nNumber: %s\nType: %s\nInitial Balance: %s",
name,
number,
type.toString(),
CurrencyUtil.formatMoneyWithCurrencyPrefix(new MoneyValue(initialBalance, currency))
);
boolean success = Popups.confirm(accountNameField, prompt);
if (success) {
long id = accountRepo.insert(type, number, name, currency);
balanceRepo.insert(LocalDateTime.now(ZoneOffset.UTC), id, initialBalance, currency, attachments);
// Once we create the new account, go to the account.
Account newAccount = accountRepo.findById(id).orElseThrow();
router.replace("account", newAccount);
}
} else {
log.debug("Updating account {}", account.id);
account.setName(accountNameField.getText().strip());
account.setAccountNumber(accountNumberField.getText().strip());
account.setType(accountTypeChoiceBox.getValue());
account.setCurrency(accountCurrencyComboBox.getValue());
accountRepo.update(account);
accountRepo.update(account.id, type, number, name, currency);
Account updatedAccount = accountRepo.findById(account.id).orElseThrow();
router.replace("account", updatedAccount);
}

View File

@ -23,8 +23,7 @@ public interface AccountRepository extends Repository, AutoCloseable {
List<Account> findTopNRecentlyActive(int n, int daysSinceLastActive);
List<Account> findAllByCurrency(Currency currency);
Optional<Account> findById(long id);
void updateName(long id, String name);
void update(Account account);
void update(long accountId, AccountType type, String accountNumber, String name, Currency currency);
void delete(Account account);
void archive(long accountId);
void unarchive(long accountId);

View File

@ -113,11 +113,6 @@ public record JdbcAccountRepository(Connection conn, Path contentDir) implements
return DbUtil.findById(conn, "SELECT * FROM account WHERE id = ?", id, JdbcAccountRepository::parseAccount);
}
@Override
public void updateName(long id, String name) {
DbUtil.updateOne(conn, "UPDATE account SET name = ? WHERE id = ? AND NOT archived", List.of(name, id));
}
@Override
public BigDecimal deriveBalance(long accountId, Instant timestamp) {
// First find the account itself, since its properties influence the balance.
@ -215,18 +210,33 @@ public record JdbcAccountRepository(Connection conn, Path contentDir) implements
}
@Override
public void update(Account account) {
DbUtil.updateOne(
conn,
"UPDATE account SET name = ?, account_number = ?, currency = ?, account_type = ? WHERE id = ?",
List.of(
account.getName(),
account.getAccountNumber(),
account.getCurrency().getCurrencyCode(),
account.getType().name(),
account.id
)
);
public void update(long accountId, AccountType type, String accountNumber, String name, Currency currency) {
DbUtil.doTransaction(conn, () -> {
Account account = findById(accountId).orElse(null);
if (account == null) return;
List<String> updateMessages = new ArrayList<>();
if (account.getType() != type) {
DbUtil.updateOne(conn, "UPDATE account SET account_type = ? WHERE id = ?", type, accountId);
updateMessages.add(String.format("Updated account type from %s to %s.", account.getType().toString(), type.toString()));
}
if (!account.getAccountNumber().equals(accountNumber)) {
DbUtil.updateOne(conn, "UPDATE account SET account_number = ? WHERE id = ?", accountNumber, accountId);
updateMessages.add(String.format("Updated account number from %s to %s.", account.getAccountNumber(), accountNumber));
}
if (!account.getName().equals(name)) {
DbUtil.updateOne(conn, "UPDATE account SET name = ? WHERE id = ?", name, accountId);
updateMessages.add(String.format("Updated account name from \"%s\" to \"%s\".", account.getName(), name));
}
if (account.getCurrency() != currency) {
DbUtil.updateOne(conn, "UPDATE account SET currency = ? WHERE id = ?", currency.getCurrencyCode(), accountId);
updateMessages.add(String.format("Updated account currency from %s to %s.", account.getCurrency(), currency));
}
if (!updateMessages.isEmpty()) {
var historyRepo = new JdbcHistoryRepository(conn);
long historyId = historyRepo.getOrCreateHistoryForAccount(accountId);
historyRepo.addTextItem(historyId, String.join("\n", updateMessages));
}
});
}
@Override

View File

@ -11,10 +11,10 @@ public class Account extends IdEntity {
private final LocalDateTime createdAt;
private final boolean archived;
private AccountType type;
private String accountNumber;
private String name;
private Currency currency;
private final AccountType type;
private final String accountNumber;
private final String name;
private final Currency currency;
public Account(long id, LocalDateTime createdAt, boolean archived, AccountType type, String accountNumber, String name, Currency currency) {
super(id);
@ -62,22 +62,6 @@ public class Account extends IdEntity {
return currency;
}
public void setType(AccountType type) {
this.type = type;
}
public void setAccountNumber(String accountNumber) {
this.accountNumber = accountNumber;
}
public void setName(String name) {
this.name = name;
}
public void setCurrency(Currency currency) {
this.currency = currency;
}
public LocalDateTime getCreatedAt() {
return createdAt;
}

View File

@ -70,7 +70,7 @@ public class AccountsModule extends DashboardModule {
Label nameLabel = new Label(account.getName());
nameLabel.getStyleClass().addAll("bold-text");
Label numberLabel = new Label(account.getAccountNumber());
Label numberLabel = new Label(account.getAccountNumberSuffix());
numberLabel.getStyleClass().addAll("mono-font");
Label typeLabel = new Label(account.getType().toString());
typeLabel.getStyleClass().add("bold-text");