Fixed account editing.
This commit is contained in:
parent
807259b2a5
commit
abf132ec99
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
|
Loading…
Reference in New Issue