Compare commits
1 Commits
develop
...
develop-cl
Author | SHA1 | Date | |
---|---|---|---|
1e15a6b077 |
@ -35,6 +35,16 @@
|
|||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0-SNAPSHOT</version>
|
||||||
<classifier>jersey</classifier>
|
<classifier>jersey</classifier>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.dataformat</groupId>
|
||||||
|
<artifactId>jackson-dataformat-csv</artifactId>
|
||||||
|
<version>2.12.2</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.datatype</groupId>
|
||||||
|
<artifactId>jackson-datatype-jsr310</artifactId>
|
||||||
|
<version>2.12.2</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.glassfish.jersey.core</groupId>
|
<groupId>org.glassfish.jersey.core</groupId>
|
||||||
<artifactId>jersey-client</artifactId>
|
<artifactId>jersey-client</artifactId>
|
||||||
|
@ -3,19 +3,54 @@ package com.inteligr8.buxfer;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.dataformat.csv.CsvMapper;
|
||||||
|
import com.fasterxml.jackson.dataformat.csv.CsvSchema;
|
||||||
|
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||||
import com.inteligr8.buxfer.model.Transaction;
|
import com.inteligr8.buxfer.model.Transaction;
|
||||||
|
import com.inteligr8.buxfer.msp.MyStocksPortfolioTransaction;
|
||||||
|
|
||||||
public class CsvTransactionWriter implements Observer<Transaction> {
|
public abstract class CsvTransactionWriter<T> implements Observer<Transaction> {
|
||||||
|
|
||||||
private final OutputStream ostream;
|
private final OutputStream ostream;
|
||||||
|
private final CsvMapper mapper;
|
||||||
|
private final CsvSchema schema;
|
||||||
|
|
||||||
public CsvTransactionWriter(OutputStream ostream) {
|
public CsvTransactionWriter(OutputStream ostream, Class<T> txClass) {
|
||||||
this.ostream = ostream;
|
this.ostream = ostream;
|
||||||
|
|
||||||
|
this.mapper = CsvMapper.builder().build();
|
||||||
|
this.mapper.registerModule(new JavaTimeModule());
|
||||||
|
|
||||||
|
if (txClass == null) {
|
||||||
|
this.schema = this.mapper.schema().withHeader();
|
||||||
|
} else {
|
||||||
|
this.schema = this.mapper.schemaFor(txClass).withHeader();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int observed(Transaction tx) throws IOException {
|
public int observed(Transaction tx) throws IOException {
|
||||||
return 0;
|
try {
|
||||||
|
ParsedTransaction ptx = NormalizedParser.getInstance().parse(tx);
|
||||||
|
return this.observed(ptx);
|
||||||
|
} catch (IllegalArgumentException iae) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int observed(ParsedTransaction ptx) throws IOException {
|
||||||
|
if (ptx.getContractType() != null)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
Object otx = this.mapTransaction(ptx);
|
||||||
|
|
||||||
|
this.mapper.writerFor(MyStocksPortfolioTransaction.class)
|
||||||
|
.with(this.schema)
|
||||||
|
.writeValue(this.ostream, otx);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract Object mapTransaction(ParsedTransaction ptx);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,11 +0,0 @@
|
|||||||
package com.inteligr8.buxfer;
|
|
||||||
|
|
||||||
import java.io.OutputStream;
|
|
||||||
|
|
||||||
public class MyStockPortfolioCsvTransactionWriter extends CsvTransactionWriter {
|
|
||||||
|
|
||||||
public MyStockPortfolioCsvTransactionWriter(OutputStream ostream) {
|
|
||||||
super(ostream);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -19,6 +19,7 @@ import org.slf4j.LoggerFactory;
|
|||||||
import com.inteligr8.buxfer.api.CommandApi;
|
import com.inteligr8.buxfer.api.CommandApi;
|
||||||
import com.inteligr8.buxfer.model.Transaction;
|
import com.inteligr8.buxfer.model.Transaction;
|
||||||
import com.inteligr8.buxfer.model.TransactionsResponse;
|
import com.inteligr8.buxfer.model.TransactionsResponse;
|
||||||
|
import com.inteligr8.buxfer.msp.MyStocksPortfolioCsvTransactionWriter;
|
||||||
|
|
||||||
public class WriterCLI {
|
public class WriterCLI {
|
||||||
|
|
||||||
@ -27,8 +28,7 @@ public class WriterCLI {
|
|||||||
private enum Format {
|
private enum Format {
|
||||||
|
|
||||||
Json,
|
Json,
|
||||||
Csv,
|
MyStocksPortfolioCsv("my-stocks-portfolio-csv");
|
||||||
MyStockPortfolioCsv("my-stock-portfolio-csv");
|
|
||||||
|
|
||||||
private final String key;
|
private final String key;
|
||||||
private Format() {
|
private Format() {
|
||||||
@ -91,13 +91,15 @@ public class WriterCLI {
|
|||||||
|
|
||||||
for (Transaction tx : response.getItems())
|
for (Transaction tx : response.getItems())
|
||||||
observer.observed(tx);
|
observer.observed(tx);
|
||||||
|
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Options buildOptions() {
|
private static Options buildOptions() {
|
||||||
return new Options()
|
return new Options()
|
||||||
.addOption(new Option("u", "email", true, "A Buxfer email for authentication"))
|
.addOption(new Option("bu", "buxfer-email", true, "A Buxfer email for authentication"))
|
||||||
.addOption(new Option("p", "password", true, "A Buxfer password for authentication"))
|
.addOption(new Option("bp", "buxfer-password", true, "A Buxfer password for authentication"))
|
||||||
.addOption(new Option("t", "format", true, "The output format [json | csv | my-stock-portfolio-csv]"))
|
.addOption(new Option("t", "format", true, "The output format [json | csv | my-stock-portfolio-csv]"))
|
||||||
.addOption(new Option("f", "file", true, "The output filename"))
|
.addOption(new Option("f", "file", true, "The output filename"))
|
||||||
.addOption(new Option(null, "portfolio-name", true, "The portfolio name where applicable"));
|
.addOption(new Option(null, "portfolio-name", true, "The portfolio name where applicable"));
|
||||||
@ -110,7 +112,7 @@ public class WriterCLI {
|
|||||||
private static File determineFile(CommandLine cli) {
|
private static File determineFile(CommandLine cli) {
|
||||||
Format format = Format.valueByKey(cli.getOptionValue("format", "json"));
|
Format format = Format.valueByKey(cli.getOptionValue("format", "json"));
|
||||||
|
|
||||||
String filename = cli.hasOption("file") ? cli.getOptionValue("file") : "portfolio";
|
String filename = cli.hasOption("file") ? cli.getOptionValue("file") : cli.getOptionValue("portfolio-name", "portfolio");
|
||||||
if (filename.lastIndexOf('.') < 0) {
|
if (filename.lastIndexOf('.') < 0) {
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case Json:
|
case Json:
|
||||||
@ -129,10 +131,10 @@ public class WriterCLI {
|
|||||||
switch (format) {
|
switch (format) {
|
||||||
case Json:
|
case Json:
|
||||||
return new JsonTransactionWriter(ostream);
|
return new JsonTransactionWriter(ostream);
|
||||||
case MyStockPortfolioCsv:
|
case MyStocksPortfolioCsv:
|
||||||
return new MyStockPortfolioCsvTransactionWriter(ostream);
|
return new MyStocksPortfolioCsvTransactionWriter(ostream, cli.getOptionValue("portfolio-name"));
|
||||||
default:
|
default:
|
||||||
return new CsvTransactionWriter(ostream);
|
throw new IllegalArgumentException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -140,10 +142,10 @@ public class WriterCLI {
|
|||||||
BuxferClientConfiguration config = new BuxferClientConfiguration();
|
BuxferClientConfiguration config = new BuxferClientConfiguration();
|
||||||
config.setBaseUrl("https://www.buxfer.com");
|
config.setBaseUrl("https://www.buxfer.com");
|
||||||
|
|
||||||
if (cli.hasOption("email"))
|
if (cli.hasOption("buxfer-email"))
|
||||||
config.setAuthEmail(cli.getOptionValue("email"));
|
config.setAuthEmail(cli.getOptionValue("buxfer-email"));
|
||||||
if (cli.hasOption("password"))
|
if (cli.hasOption("buxfer-password"))
|
||||||
config.setAuthPassword(cli.getOptionValue("password"));
|
config.setAuthPassword(cli.getOptionValue("buxfer-password"));
|
||||||
|
|
||||||
BuxferClientJerseyImpl client = new BuxferClientJerseyImpl(config);
|
BuxferClientJerseyImpl client = new BuxferClientJerseyImpl(config);
|
||||||
return client.getApi().getCommandApi();
|
return client.getApi().getCommandApi();
|
||||||
|
@ -0,0 +1,30 @@
|
|||||||
|
package com.inteligr8.buxfer.msp;
|
||||||
|
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.time.ZoneId;
|
||||||
|
|
||||||
|
import com.inteligr8.buxfer.CsvTransactionWriter;
|
||||||
|
import com.inteligr8.buxfer.ParsedTransaction;
|
||||||
|
|
||||||
|
public class MyStocksPortfolioCsvTransactionWriter extends CsvTransactionWriter<MyStocksPortfolioTransaction> {
|
||||||
|
|
||||||
|
private long nextId;
|
||||||
|
|
||||||
|
public MyStocksPortfolioCsvTransactionWriter(OutputStream ostream, String portfolioName) {
|
||||||
|
super(ostream, MyStocksPortfolioTransaction.class);
|
||||||
|
this.nextId = 1L;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Object mapTransaction(ParsedTransaction ptx) {
|
||||||
|
MyStocksPortfolioTransaction msptx = new MyStocksPortfolioTransaction();
|
||||||
|
msptx.setId(this.nextId++);
|
||||||
|
msptx.setDatetime(ptx.getTransaction().getDate().atStartOfDay(ZoneId.systemDefault()).toOffsetDateTime());
|
||||||
|
msptx.setCurrency("USD");
|
||||||
|
msptx.setSymbol(ptx.getSecuritySymbol());
|
||||||
|
msptx.setQuantity((int)ptx.getSecurities());
|
||||||
|
msptx.setPricePerShare(ptx.getPricePerSecurity());
|
||||||
|
return msptx;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,238 @@
|
|||||||
|
package com.inteligr8.buxfer.msp;
|
||||||
|
|
||||||
|
import java.time.LocalTime;
|
||||||
|
import java.time.OffsetDateTime;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
|
||||||
|
|
||||||
|
@JsonPropertyOrder({
|
||||||
|
"Id",
|
||||||
|
"Symbol",
|
||||||
|
"Name",
|
||||||
|
"DisplaySymbol",
|
||||||
|
"Exchange",
|
||||||
|
"Portfolio",
|
||||||
|
"Currency",
|
||||||
|
"Quantity",
|
||||||
|
"Cost Per Share",
|
||||||
|
"Cost Basis Method",
|
||||||
|
"Commission",
|
||||||
|
"Date",
|
||||||
|
"TimeOfDay",
|
||||||
|
"PurchaseFX",
|
||||||
|
"Type",
|
||||||
|
"Method",
|
||||||
|
"Method Execution Ids",
|
||||||
|
"Notes"
|
||||||
|
})
|
||||||
|
public class MyStocksPortfolioTransaction {
|
||||||
|
|
||||||
|
public enum Type {
|
||||||
|
Buy,
|
||||||
|
Sell,
|
||||||
|
Dividend
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum Method {
|
||||||
|
FIFO
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("Id")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@JsonProperty("Symbol")
|
||||||
|
private String symbol;
|
||||||
|
|
||||||
|
@JsonProperty("Name")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@JsonProperty("DisplaySymbol")
|
||||||
|
private String symbolDisplay;
|
||||||
|
|
||||||
|
@JsonProperty("Exchange")
|
||||||
|
private String exchange;
|
||||||
|
|
||||||
|
@JsonProperty("Portfolio")
|
||||||
|
private String portfolio;
|
||||||
|
|
||||||
|
@JsonProperty("Currency")
|
||||||
|
private String currency;
|
||||||
|
|
||||||
|
@JsonProperty("Quantity")
|
||||||
|
private Integer quantity;
|
||||||
|
|
||||||
|
@JsonProperty("Cost Per Share")
|
||||||
|
private Double pricePerShare;
|
||||||
|
|
||||||
|
@JsonProperty("Cost Basis Method")
|
||||||
|
private Double costBasisMethod;
|
||||||
|
|
||||||
|
@JsonProperty("Commission")
|
||||||
|
private Double commission;
|
||||||
|
|
||||||
|
private OffsetDateTime datetime;
|
||||||
|
|
||||||
|
@JsonProperty("PurchaseFX")
|
||||||
|
private String fx;
|
||||||
|
|
||||||
|
@JsonProperty("Type")
|
||||||
|
private Type type;
|
||||||
|
|
||||||
|
@JsonProperty("Method")
|
||||||
|
private Method method;
|
||||||
|
|
||||||
|
@JsonProperty("Method Execution Ids")
|
||||||
|
private String methodExecutionId;
|
||||||
|
|
||||||
|
@JsonProperty("Notes")
|
||||||
|
private String notes;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSymbol() {
|
||||||
|
return symbol;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSymbol(String symbol) {
|
||||||
|
this.symbol = symbol;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSymbolDisplay() {
|
||||||
|
return symbolDisplay;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSymbolDisplay(String symbolDisplay) {
|
||||||
|
this.symbolDisplay = symbolDisplay;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getExchange() {
|
||||||
|
return exchange;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExchange(String exchange) {
|
||||||
|
this.exchange = exchange;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPortfolio() {
|
||||||
|
return portfolio;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPortfolio(String portfolio) {
|
||||||
|
this.portfolio = portfolio;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCurrency() {
|
||||||
|
return currency;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCurrency(String currency) {
|
||||||
|
this.currency = currency;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getQuantity() {
|
||||||
|
return quantity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setQuantity(Integer quantity) {
|
||||||
|
this.quantity = quantity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getPricePerShare() {
|
||||||
|
return pricePerShare;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPricePerShare(Double pricePerShare) {
|
||||||
|
this.pricePerShare = pricePerShare;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getCostBasisMethod() {
|
||||||
|
return costBasisMethod;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCostBasisMethod(Double costBasisMethod) {
|
||||||
|
this.costBasisMethod = costBasisMethod;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getCommission() {
|
||||||
|
return commission;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCommission(Double commission) {
|
||||||
|
this.commission = commission;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("Date")
|
||||||
|
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd Z")
|
||||||
|
public OffsetDateTime getDateTz() {
|
||||||
|
return this.datetime;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("TimeOfDay")
|
||||||
|
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "hh:mm:ss")
|
||||||
|
public LocalTime getTime() {
|
||||||
|
return this.datetime.toLocalTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDatetime(OffsetDateTime datetime) {
|
||||||
|
this.datetime = datetime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFx() {
|
||||||
|
return fx;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFx(String fx) {
|
||||||
|
this.fx = fx;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Type getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setType(Type type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Method getMethod() {
|
||||||
|
return method;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMethod(Method method) {
|
||||||
|
this.method = method;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMethodExecutionId() {
|
||||||
|
return methodExecutionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMethodExecutionId(String methodExecutionId) {
|
||||||
|
this.methodExecutionId = methodExecutionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNotes() {
|
||||||
|
return notes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNotes(String notes) {
|
||||||
|
this.notes = notes;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user