Added basic transactions export, just to say it has it. Also did more to sanitize transaction descriptions.

This commit is contained in:
Andrew Lalis 2024-01-11 07:48:46 -05:00
parent 2c49dd5766
commit 89d7438ab1
3 changed files with 43 additions and 3 deletions

View File

@ -101,7 +101,7 @@ public class CreateTransactionController implements RouteSelectionListener {
LocalDateTime utcTimestamp = DateUtil.localToUTC(parseTimestamp()); LocalDateTime utcTimestamp = DateUtil.localToUTC(parseTimestamp());
BigDecimal amount = new BigDecimal(amountField.getText()); BigDecimal amount = new BigDecimal(amountField.getText());
Currency currency = currencyChoiceBox.getValue(); Currency currency = currencyChoiceBox.getValue();
String description = descriptionField.getText() == null ? null : descriptionField.getText().strip(); String description = getSanitizedDescription();
CreditAndDebitAccounts linkedAccounts = getSelectedAccounts(); CreditAndDebitAccounts linkedAccounts = getSelectedAccounts();
List<Path> attachments = attachmentsSelectionArea.getSelectedFiles(); List<Path> attachments = attachmentsSelectionArea.getSelectedFiles();
Profile.getCurrent().getDataSource().useTransactionRepository(repo -> { Profile.getCurrent().getDataSource().useTransactionRepository(repo -> {
@ -190,4 +190,11 @@ public class CreateTransactionController implements RouteSelectionListener {
}); });
}); });
} }
private String getSanitizedDescription() {
String raw = descriptionField.getText();
if (raw == null) return null;
if (raw.isBlank()) return null;
return raw.strip();
}
} }

View File

@ -4,6 +4,7 @@ import com.andrewlalis.javafx_scene_router.RouteSelectionListener;
import com.andrewlalis.perfin.data.pagination.Page; import com.andrewlalis.perfin.data.pagination.Page;
import com.andrewlalis.perfin.data.pagination.PageRequest; import com.andrewlalis.perfin.data.pagination.PageRequest;
import com.andrewlalis.perfin.data.pagination.Sort; import com.andrewlalis.perfin.data.pagination.Sort;
import com.andrewlalis.perfin.data.util.DateUtil;
import com.andrewlalis.perfin.data.util.Pair; import com.andrewlalis.perfin.data.util.Pair;
import com.andrewlalis.perfin.model.Account; import com.andrewlalis.perfin.model.Account;
import com.andrewlalis.perfin.model.Profile; import com.andrewlalis.perfin.model.Profile;
@ -22,7 +23,11 @@ import javafx.scene.control.ComboBox;
import javafx.scene.layout.BorderPane; import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox; import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox; import javafx.scene.layout.VBox;
import javafx.stage.FileChooser;
import java.io.File;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
@ -152,11 +157,38 @@ public class TransactionsViewController implements RouteSelectionListener {
} }
} }
@FXML @FXML public void addTransaction() {
public void addTransaction() {
router.navigate("create-transaction"); router.navigate("create-transaction");
} }
@FXML public void exportTransactions() {
FileChooser fileChooser = new FileChooser();
fileChooser.setTitle("Export Transactions");
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("CSV Files", ".csv"));
File file = fileChooser.showSaveDialog(detailPanel.getScene().getWindow());
if (file != null) {
try (
var repo = Profile.getCurrent().getDataSource().getTransactionRepository();
var out = new PrintWriter(file, StandardCharsets.UTF_8)
) {
out.println("id,utc-timestamp,amount,currency,description");
List<Transaction> allTransactions = repo.findAll(PageRequest.unpaged(Sort.desc("timestamp"))).items();
for (Transaction tx : allTransactions) {
out.println("%d,%s,%s,%s,%s".formatted(
tx.id,
tx.getTimestamp().format(DateUtil.DEFAULT_DATETIME_FORMAT),
tx.getAmount().toPlainString(),
tx.getCurrency().getCurrencyCode(),
tx.getDescription() == null ? "" : tx.getDescription()
));
}
} catch (Exception e) {
Popups.error("An error occurred: " + e.getMessage());
}
}
}
private TransactionTile makeTile(Transaction transaction) { private TransactionTile makeTile(Transaction transaction) {
var tile = new TransactionTile(transaction); var tile = new TransactionTile(transaction);
tile.setOnMouseClicked(event -> { tile.setOnMouseClicked(event -> {

View File

@ -13,6 +13,7 @@
<top> <top>
<HBox styleClass="std-padding,std-spacing"> <HBox styleClass="std-padding,std-spacing">
<Button text="Add Transaction" onAction="#addTransaction"/> <Button text="Add Transaction" onAction="#addTransaction"/>
<Button text="Export Transactions" onAction="#exportTransactions"/>
</HBox> </HBox>
</top> </top>
<center> <center>