Refactored repository access to use fancy generic method.

This commit is contained in:
Andrew Lalis 2024-01-12 22:44:29 -05:00
parent 4600470cdb
commit f0b061c34d
18 changed files with 165 additions and 136 deletions

View File

@ -1,6 +1,8 @@
package com.andrewlalis.perfin.control;
import com.andrewlalis.javafx_scene_router.RouteSelectionListener;
import com.andrewlalis.perfin.data.AccountHistoryItemRepository;
import com.andrewlalis.perfin.data.AccountRepository;
import com.andrewlalis.perfin.data.util.DateUtil;
import com.andrewlalis.perfin.model.Account;
import com.andrewlalis.perfin.model.Profile;
@ -62,7 +64,8 @@ public class AccountViewController implements RouteSelectionListener {
accountNumberLabel.setText(account.getAccountNumber());
accountCurrencyLabel.setText(account.getCurrency().getDisplayName());
accountCreatedAtLabel.setText(DateUtil.formatUTCAsLocalWithZone(account.getCreatedAt()));
Profile.getCurrent().getDataSource().getAccountBalanceText(account, accountBalanceLabel::setText);
Profile.getCurrent().getDataSource().getAccountBalanceText(account)
.thenAccept(accountBalanceLabel::setText);
reloadHistory();
}
@ -93,7 +96,7 @@ public class AccountViewController implements RouteSelectionListener {
"later if you need to."
);
if (confirmResult) {
Profile.getCurrent().getDataSource().useAccountRepository(repo -> repo.archive(account.id));
Profile.getCurrent().getDataSource().useRepo(AccountRepository.class, repo -> repo.archive(account.id));
router.replace("accounts");
}
}
@ -104,7 +107,7 @@ public class AccountViewController implements RouteSelectionListener {
"status?"
);
if (confirm) {
Profile.getCurrent().getDataSource().useAccountRepository(repo -> repo.unarchive(account.id));
Profile.getCurrent().getDataSource().useRepo(AccountRepository.class, repo -> repo.unarchive(account.id));
router.replace("accounts");
}
}
@ -119,15 +122,14 @@ public class AccountViewController implements RouteSelectionListener {
"want to hide it."
);
if (confirm) {
Profile.getCurrent().getDataSource().useAccountRepository(repo -> repo.delete(account));
Profile.getCurrent().getDataSource().useRepo(AccountRepository.class, repo -> repo.delete(account));
router.replace("accounts");
}
}
@FXML public void loadMoreHistory() {
Thread.ofVirtual().start(() -> {
try (var historyRepo = Profile.getCurrent().getDataSource().getAccountHistoryItemRepository()) {
List<AccountHistoryItem> historyItems = historyRepo.findMostRecentForAccount(
Profile.getCurrent().getDataSource().useRepoAsync(AccountHistoryItemRepository.class, repo -> {
List<AccountHistoryItem> historyItems = repo.findMostRecentForAccount(
account.id,
loadHistoryFrom,
historyLoadSize
@ -138,12 +140,9 @@ public class AccountViewController implements RouteSelectionListener {
loadHistoryFrom = historyItems.getLast().getTimestamp();
}
List<? extends Node> nodes = historyItems.stream()
.map(item -> AccountHistoryItemTile.forItem(item, historyRepo, this))
.map(item -> AccountHistoryItemTile.forItem(item, repo, this))
.toList();
Platform.runLater(() -> historyItemsVBox.getChildren().addAll(nodes));
} catch (Exception e) {
throw new RuntimeException(e);
}
});
}
}

View File

@ -1,6 +1,7 @@
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.model.Account;
import com.andrewlalis.perfin.model.MoneyValue;
@ -48,14 +49,14 @@ public class AccountsViewController implements RouteSelectionListener {
public void refreshAccounts() {
Profile.whenLoaded(profile -> {
Thread.ofVirtual().start(() -> profile.getDataSource().useAccountRepository(repo -> {
profile.getDataSource().useRepoAsync(AccountRepository.class, repo -> {
List<Account> accounts = repo.findAllOrderedByRecentHistory();
Platform.runLater(() -> accountsPane.getChildren()
.setAll(accounts.stream()
.map(AccountTile::new)
.toList()
));
}));
});
// Compute grand totals!
Thread.ofVirtual().start(() -> {
var totals = profile.getDataSource().getCombinedAccountBalances();

View File

@ -1,6 +1,7 @@
package com.andrewlalis.perfin.control;
import com.andrewlalis.javafx_scene_router.RouteSelectionListener;
import com.andrewlalis.perfin.data.BalanceRecordRepository;
import com.andrewlalis.perfin.data.util.CurrencyUtil;
import com.andrewlalis.perfin.data.util.DateUtil;
import com.andrewlalis.perfin.model.Attachment;
@ -40,19 +41,16 @@ public class BalanceRecordViewController implements RouteSelectionListener {
timestampLabel.setText(DateUtil.formatUTCAsLocalWithZone(balanceRecord.getTimestamp()));
balanceLabel.setText(CurrencyUtil.formatMoney(balanceRecord.getMoneyAmount()));
currencyLabel.setText(balanceRecord.getCurrency().getDisplayName());
Thread.ofVirtual().start(() -> Profile.getCurrent().getDataSource().useBalanceRecordRepository(repo -> {
Profile.getCurrent().getDataSource().useRepoAsync(BalanceRecordRepository.class, repo -> {
List<Attachment> attachments = repo.findAttachments(balanceRecord.id);
Platform.runLater(() -> attachmentsViewPane.setAttachments(attachments));
}));
});
}
@FXML public void delete() {
boolean confirm = Popups.confirm("Are you sure you want to delete this balance record? This may have an effect on the derived balance of your account, as shown in Perfin.");
if (confirm) {
Profile.getCurrent().getDataSource().useBalanceRecordRepository(repo -> {
repo.deleteById(balanceRecord.id);
});
Profile.getCurrent().getDataSource().useRepo(BalanceRecordRepository.class, repo -> repo.deleteById(balanceRecord.id));
router.navigateBackAndClear();
}
}

View File

@ -1,6 +1,8 @@
package com.andrewlalis.perfin.control;
import com.andrewlalis.javafx_scene_router.RouteSelectionListener;
import com.andrewlalis.perfin.data.AccountRepository;
import com.andrewlalis.perfin.data.BalanceRecordRepository;
import com.andrewlalis.perfin.data.util.CurrencyUtil;
import com.andrewlalis.perfin.data.util.DateUtil;
import com.andrewlalis.perfin.data.util.FileUtil;
@ -59,12 +61,12 @@ public class CreateBalanceRecordController implements RouteSelectionListener {
return;
}
BigDecimal reportedBalance = new BigDecimal(newValue);
Thread.ofVirtual().start(() -> Profile.getCurrent().getDataSource().useAccountRepository(repo -> {
Profile.getCurrent().getDataSource().useRepoAsync(AccountRepository.class, repo -> {
BigDecimal derivedBalance = repo.deriveCurrentBalance(account.id);
Platform.runLater(() -> balanceWarningLabel.visibleProperty().set(
!reportedBalance.setScale(derivedBalance.scale(), RoundingMode.HALF_UP).equals(derivedBalance)
));
}));
});
});
var formValid = timestampValid.and(balanceValid);
@ -83,12 +85,12 @@ public class CreateBalanceRecordController implements RouteSelectionListener {
public void onRouteSelected(Object context) {
this.account = (Account) context;
timestampField.setText(LocalDateTime.now().format(DateUtil.DEFAULT_DATETIME_FORMAT));
Thread.ofVirtual().start(() -> Profile.getCurrent().getDataSource().useAccountRepository(repo -> {
Profile.getCurrent().getDataSource().useRepoAsync(AccountRepository.class, repo -> {
BigDecimal value = repo.deriveCurrentBalance(account.id);
Platform.runLater(() -> balanceField.setText(
CurrencyUtil.formatMoneyAsBasicNumber(new MoneyValue(value, account.getCurrency()))
));
}));
});
attachmentSelectionArea.clear();
}
@ -102,7 +104,7 @@ public class CreateBalanceRecordController implements RouteSelectionListener {
localTimestamp.atZone(ZoneId.systemDefault()).format(DateUtil.DEFAULT_DATETIME_FORMAT_WITH_ZONE)
));
if (confirm && confirmIfInconsistentBalance(reportedBalance)) {
Profile.getCurrent().getDataSource().useBalanceRecordRepository(repo -> {
Profile.getCurrent().getDataSource().useRepo(BalanceRecordRepository.class, repo -> {
repo.insert(
DateUtil.localToUTC(localTimestamp),
account.id,
@ -120,12 +122,10 @@ public class CreateBalanceRecordController implements RouteSelectionListener {
}
private boolean confirmIfInconsistentBalance(BigDecimal reportedBalance) {
BigDecimal currentDerivedBalance;
try (var accountRepo = Profile.getCurrent().getDataSource().getAccountRepository()) {
currentDerivedBalance = accountRepo.deriveCurrentBalance(account.id);
} catch (Exception e) {
throw new RuntimeException(e);
}
BigDecimal currentDerivedBalance = Profile.getCurrent().getDataSource().mapRepo(
AccountRepository.class,
repo -> repo.deriveCurrentBalance(account.id)
);
if (!reportedBalance.setScale(currentDerivedBalance.scale(), RoundingMode.HALF_UP).equals(currentDerivedBalance)) {
String msg = "The balance you reported (%s) doesn't match the balance that Perfin derived from your account's transactions (%s). It's encouraged to go back and add any missing transactions first, but you may proceed now if you understand the consequences of an inconsistent account balance history.\n\nAre you absolutely sure you want to create this balance record?".formatted(
CurrencyUtil.formatMoney(new MoneyValue(reportedBalance, account.getCurrency())),

View File

@ -1,6 +1,7 @@
package com.andrewlalis.perfin.control;
import com.andrewlalis.javafx_scene_router.RouteSelectionListener;
import com.andrewlalis.perfin.data.TransactionRepository;
import com.andrewlalis.perfin.data.pagination.PageRequest;
import com.andrewlalis.perfin.data.pagination.Sort;
import com.andrewlalis.perfin.data.util.CurrencyUtil;
@ -104,13 +105,15 @@ public class EditTransactionController implements RouteSelectionListener {
}
@FXML public void save() {
final long idToNavigate;
if (transaction == null) {
LocalDateTime utcTimestamp = DateUtil.localToUTC(parseTimestamp());
BigDecimal amount = new BigDecimal(amountField.getText());
Currency currency = currencyChoiceBox.getValue();
String description = getSanitizedDescription();
CreditAndDebitAccounts linkedAccounts = getSelectedAccounts();
List<Path> attachments = attachmentsSelectionArea.getSelectedFiles();
Profile.getCurrent().getDataSource().useTransactionRepository(repo -> {
Profile.getCurrent().getDataSource().useRepo(TransactionRepository.class, repo -> {
repo.insert(
utcTimestamp,
amount,
@ -120,7 +123,7 @@ public class EditTransactionController implements RouteSelectionListener {
attachments
);
});
router.navigateBackAndClear();
}
}
@FXML public void cancel() {

View File

@ -1,5 +1,6 @@
package com.andrewlalis.perfin.control;
import com.andrewlalis.perfin.data.TransactionRepository;
import com.andrewlalis.perfin.data.util.CurrencyUtil;
import com.andrewlalis.perfin.data.util.DateUtil;
import com.andrewlalis.perfin.model.Attachment;
@ -44,10 +45,9 @@ public class TransactionViewController {
amountLabel.setText(CurrencyUtil.formatMoney(transaction.getMoneyAmount()));
timestampLabel.setText(DateUtil.formatUTCAsLocalWithZone(transaction.getTimestamp()));
descriptionLabel.setText(transaction.getDescription());
Thread.ofVirtual().start(() -> {
Profile.getCurrent().getDataSource().useTransactionRepository(repo -> {
Profile.getCurrent().getDataSource().useRepoAsync(TransactionRepository.class, repo -> {
CreditAndDebitAccounts accounts = repo.findLinkedAccounts(transaction.id);
List<Attachment> attachments = repo.findAttachments(transaction.id);
Platform.runLater(() -> {
accounts.ifDebit(acc -> {
debitAccountLink.setText(acc.getShortName());
@ -57,14 +57,7 @@ public class TransactionViewController {
creditAccountLink.setText(acc.getShortName());
creditAccountLink.setOnAction(event -> router.navigate("account", acc));
});
});
});
});
Thread.ofVirtual().start(() -> {
Profile.getCurrent().getDataSource().useTransactionRepository(repo -> {
List<Attachment> attachments = repo.findAttachments(transaction.id);
Platform.runLater(() -> attachmentsViewPane.setAttachments(attachments));
attachmentsViewPane.setAttachments(attachments);
});
});
}
@ -84,10 +77,8 @@ public class TransactionViewController {
"it's derived from the most recent balance-record, and transactions."
);
if (confirm) {
Profile.getCurrent().getDataSource().useTransactionRepository(repo -> {
repo.delete(transaction.id);
Profile.getCurrent().getDataSource().useRepo(TransactionRepository.class, repo -> repo.delete(transaction.id));
router.replace("transactions");
});
}
}

View File

@ -1,6 +1,8 @@
package com.andrewlalis.perfin.control;
import com.andrewlalis.javafx_scene_router.RouteSelectionListener;
import com.andrewlalis.perfin.data.AccountRepository;
import com.andrewlalis.perfin.data.TransactionRepository;
import com.andrewlalis.perfin.data.pagination.Page;
import com.andrewlalis.perfin.data.pagination.PageRequest;
import com.andrewlalis.perfin.data.pagination.Sort;
@ -122,8 +124,7 @@ public class TransactionsViewController implements RouteSelectionListener {
transactionsVBox.getChildren().clear(); // Clear the transactions before reload initially.
// Refresh account filter options.
Thread.ofVirtual().start(() -> {
Profile.getCurrent().getDataSource().useAccountRepository(repo -> {
Profile.getCurrent().getDataSource().useRepoAsync(AccountRepository.class, repo -> {
List<Account> accounts = repo.findAll(PageRequest.unpaged(Sort.asc("name"))).items();
accounts.add(null);
Platform.runLater(() -> {
@ -133,16 +134,15 @@ public class TransactionsViewController implements RouteSelectionListener {
filterByAccountComboBox.getButtonCell().updateIndex(accounts.size() - 1);
});
});
});
// If a transaction id is given in the route context, navigate to the page it's on and select it.
if (context instanceof RouteContext ctx && ctx.selectedTransactionId != null) {
Thread.ofVirtual().start(() -> {
Profile.getCurrent().getDataSource().useTransactionRepository(repo -> {
Profile.getCurrent().getDataSource().useRepoAsync(TransactionRepository.class, repo -> {
repo.findById(ctx.selectedTransactionId).ifPresent(tx -> {
long offset = repo.countAllAfter(tx.id);
int pageNumber = (int) (offset / paginationControls.getItemsPerPage()) + 1;
Platform.runLater(() -> {
paginationControls.setPage(pageNumber).thenRun(() -> selectedTransaction.set(tx));
});
});

View File

@ -7,7 +7,7 @@ import java.time.LocalDateTime;
import java.util.Currency;
import java.util.List;
public interface AccountEntryRepository extends AutoCloseable {
public interface AccountEntryRepository extends Repository, AutoCloseable {
long insert(
LocalDateTime timestamp,
long accountId,

View File

@ -9,7 +9,7 @@ import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
public interface AccountHistoryItemRepository extends AutoCloseable {
public interface AccountHistoryItemRepository extends Repository, AutoCloseable {
void recordAccountEntry(LocalDateTime timestamp, long accountId, long entryId);
void recordBalanceRecord(LocalDateTime timestamp, long accountId, long recordId);
void recordText(LocalDateTime timestamp, long accountId, String text);

View File

@ -13,7 +13,7 @@ import java.util.List;
import java.util.Optional;
import java.util.Set;
public interface AccountRepository extends AutoCloseable {
public interface AccountRepository extends Repository, AutoCloseable {
long insert(AccountType type, String accountNumber, String name, Currency currency);
Page<Account> findAll(PageRequest pagination);
List<Account> findAllOrderedByRecentHistory();

View File

@ -5,7 +5,7 @@ import com.andrewlalis.perfin.model.Attachment;
import java.nio.file.Path;
import java.util.Optional;
public interface AttachmentRepository extends AutoCloseable {
public interface AttachmentRepository extends Repository, AutoCloseable {
Attachment insert(Path sourcePath);
Optional<Attachment> findById(long attachmentId);
Optional<Attachment> findByIdentifier(String identifier);

View File

@ -10,7 +10,7 @@ import java.util.Currency;
import java.util.List;
import java.util.Optional;
public interface BalanceRecordRepository extends AutoCloseable {
public interface BalanceRecordRepository extends Repository, AutoCloseable {
long insert(LocalDateTime utcTimestamp, long accountId, BigDecimal balance, Currency currency, List<Path> attachments);
BalanceRecord findLatestByAccountId(long accountId);
Optional<BalanceRecord> findClosestBefore(long accountId, LocalDateTime utcTimestamp);

View File

@ -2,8 +2,6 @@ package com.andrewlalis.perfin.data;
import com.andrewlalis.perfin.data.pagination.PageRequest;
import com.andrewlalis.perfin.data.util.CurrencyUtil;
import com.andrewlalis.perfin.data.util.DbUtil;
import com.andrewlalis.perfin.data.util.ThrowableConsumer;
import com.andrewlalis.perfin.model.Account;
import com.andrewlalis.perfin.model.AccountType;
import com.andrewlalis.perfin.model.MoneyValue;
@ -11,11 +9,11 @@ import javafx.application.Platform;
import java.math.BigDecimal;
import java.nio.file.Path;
import java.util.Currency;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
/**
* Interface for methods to obtain any data from a {@link com.andrewlalis.perfin.model.Profile}
@ -35,30 +33,70 @@ public interface DataSource {
AttachmentRepository getAttachmentRepository();
AccountHistoryItemRepository getAccountHistoryItemRepository();
default void useAccountRepository(ThrowableConsumer<AccountRepository> repoConsumer) {
DbUtil.useClosable(this::getAccountRepository, repoConsumer);
// Repository helper methods:
@SuppressWarnings("unchecked")
default <R extends Repository, T> T mapRepo(Class<R> repoType, Function<R, T> action) {
Supplier<R> repoSupplier = getRepo(repoType);
if (repoSupplier == null) throw new IllegalArgumentException("Repository type " + repoType + " is not supported.");
boolean repoCloseable = Arrays.asList(repoType.getInterfaces()).contains(AutoCloseable.class);
if (repoCloseable) {
try (AutoCloseable c = (AutoCloseable) repoSupplier.get()) {
R repo = (R) c;
return action.apply(repo);
} catch (Exception e) {
throw new RuntimeException(e);
}
} else {
R repo = repoSupplier.get();
return action.apply(repo);
}
}
default void useBalanceRecordRepository(ThrowableConsumer<BalanceRecordRepository> repoConsumer) {
DbUtil.useClosable(this::getBalanceRecordRepository, repoConsumer);
default <R extends Repository, T> CompletableFuture<T> mapRepoAsync(Class<R> repoType, Function<R, T> action) {
CompletableFuture<T> cf = new CompletableFuture<>();
Thread.ofVirtual().start(() -> {
cf.complete(mapRepo(repoType, action));
});
return cf;
}
default void useTransactionRepository(ThrowableConsumer<TransactionRepository> repoConsumer) {
DbUtil.useClosable(this::getTransactionRepository, repoConsumer);
default <R extends Repository> void useRepo(Class<R> repoType, Consumer<R> action) {
mapRepo(repoType, (Function<R, Void>) repo -> {
action.accept(repo);
return null;
});
}
default void useAttachmentRepository(ThrowableConsumer<AttachmentRepository> repoConsumer) {
DbUtil.useClosable(this::getAttachmentRepository, repoConsumer);
default <R extends Repository> CompletableFuture<Void> useRepoAsync(Class<R> repoType, Consumer<R> action) {
return mapRepoAsync(repoType, repo -> {
action.accept(repo);
return null;
});
}
@SuppressWarnings("unchecked")
private <R extends Repository> Supplier<R> getRepo(Class<R> type) {
final Map<Class<? extends Repository>, Supplier<? extends Repository>> repoSuppliers = Map.of(
AccountRepository.class, this::getAccountRepository,
BalanceRecordRepository.class, this::getBalanceRecordRepository,
TransactionRepository.class, this::getTransactionRepository,
AttachmentRepository.class, this::getAttachmentRepository,
AccountHistoryItemRepository.class, this::getAccountHistoryItemRepository
);
return (Supplier<R>) repoSuppliers.get(type);
}
// Utility methods:
default void getAccountBalanceText(Account account, Consumer<String> balanceConsumer) {
Thread.ofVirtual().start(() -> useAccountRepository(repo -> {
default CompletableFuture<String> getAccountBalanceText(Account account) {
CompletableFuture<String> cf = new CompletableFuture<>();
mapRepoAsync(AccountRepository.class, repo -> {
BigDecimal balance = repo.deriveCurrentBalance(account.id);
MoneyValue money = new MoneyValue(balance, account.getCurrency());
Platform.runLater(() -> balanceConsumer.accept(CurrencyUtil.formatMoney(money)));
}));
return CurrencyUtil.formatMoney(money);
}).thenAccept(s -> Platform.runLater(() -> cf.complete(s)));
return cf;
}
default Map<Currency, BigDecimal> getCombinedAccountBalances() {

View File

@ -0,0 +1,4 @@
package com.andrewlalis.perfin.data;
public interface Repository {
}

View File

@ -14,7 +14,7 @@ import java.util.List;
import java.util.Optional;
import java.util.Set;
public interface TransactionRepository extends AutoCloseable {
public interface TransactionRepository extends Repository, AutoCloseable {
long insert(
LocalDateTime utcTimestamp,
BigDecimal amount,

View File

@ -1,5 +1,6 @@
package com.andrewlalis.perfin.view.component;
import com.andrewlalis.perfin.data.AccountRepository;
import com.andrewlalis.perfin.data.util.CurrencyUtil;
import com.andrewlalis.perfin.model.Account;
import com.andrewlalis.perfin.model.MoneyValue;
@ -109,13 +110,13 @@ public class AccountSelectionBox extends ComboBox<Account> {
nameLabel.setText(item.getName() + " (" + item.getAccountNumberSuffix() + ")");
if (showBalanceProp.get()) {
Thread.ofVirtual().start(() -> Profile.getCurrent().getDataSource().useAccountRepository(repo -> {
Profile.getCurrent().getDataSource().useRepoAsync(AccountRepository.class, repo -> {
BigDecimal balance = repo.deriveCurrentBalance(item.id);
Platform.runLater(() -> {
balanceLabel.setText(CurrencyUtil.formatMoney(new MoneyValue(balance, item.getCurrency())));
balanceLabel.setVisible(true);
});
}));
});
}
}
}

View File

@ -1,5 +1,6 @@
package com.andrewlalis.perfin.view.component;
import com.andrewlalis.perfin.data.AccountRepository;
import com.andrewlalis.perfin.data.util.CurrencyUtil;
import com.andrewlalis.perfin.model.Account;
import com.andrewlalis.perfin.model.AccountType;
@ -80,7 +81,7 @@ public class AccountTile extends BorderPane {
Label balanceLabel = new Label("Computing balance...");
balanceLabel.getStyleClass().addAll("mono-font");
balanceLabel.setDisable(true);
Thread.ofVirtual().start(() -> Profile.getCurrent().getDataSource().useAccountRepository(repo -> {
Profile.getCurrent().getDataSource().useRepoAsync(AccountRepository.class, repo -> {
BigDecimal balance = repo.deriveCurrentBalance(account.id);
String text = CurrencyUtil.formatMoney(new MoneyValue(balance, account.getCurrency()));
Platform.runLater(() -> {
@ -92,10 +93,6 @@ public class AccountTile extends BorderPane {
}
balanceLabel.setDisable(false);
});
}));
Profile.getCurrent().getDataSource().getAccountBalanceText(account, text -> {
balanceLabel.setText(text);
balanceLabel.setDisable(false);
});
propertiesPane.getChildren().addAll(

View File

@ -1,5 +1,6 @@
package com.andrewlalis.perfin.view.component;
import com.andrewlalis.perfin.data.TransactionRepository;
import com.andrewlalis.perfin.data.util.CurrencyUtil;
import com.andrewlalis.perfin.data.util.DateUtil;
import com.andrewlalis.perfin.model.CreditAndDebitAccounts;
@ -99,13 +100,9 @@ public class TransactionTile extends BorderPane {
}
private CompletableFuture<CreditAndDebitAccounts> getCreditAndDebitAccounts(Transaction transaction) {
CompletableFuture<CreditAndDebitAccounts> cf = new CompletableFuture<>();
Thread.ofVirtual().start(() -> {
Profile.getCurrent().getDataSource().useTransactionRepository(repo -> {
CreditAndDebitAccounts accounts = repo.findLinkedAccounts(transaction.id);
cf.complete(accounts);
});
});
return cf;
return Profile.getCurrent().getDataSource().mapRepoAsync(
TransactionRepository.class,
repo -> repo.findLinkedAccounts(transaction.id)
);
}
}