package name.abuchen.portfolio.datatransfer.pdf.dab; import static org.hamcrest.CoreMatchers.instanceOf; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.collection.IsEmptyCollection.empty; import static org.junit.Assert.assertThat; import java.io.File; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.time.LocalDate; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Optional; import java.util.Scanner; import org.junit.Test; import name.abuchen.portfolio.datatransfer.Extractor.BuySellEntryItem; import name.abuchen.portfolio.datatransfer.Extractor.Item; import name.abuchen.portfolio.datatransfer.Extractor.SecurityItem; import name.abuchen.portfolio.datatransfer.Extractor.TransactionItem; import name.abuchen.portfolio.datatransfer.actions.AssertImportActions; import name.abuchen.portfolio.datatransfer.pdf.DABPDFExctractor; import name.abuchen.portfolio.model.AccountTransaction; import name.abuchen.portfolio.model.BuySellEntry; import name.abuchen.portfolio.model.Client; import name.abuchen.portfolio.model.PortfolioTransaction; import name.abuchen.portfolio.model.Security; import name.abuchen.portfolio.model.Transaction.Unit; import name.abuchen.portfolio.money.CurrencyUnit; import name.abuchen.portfolio.money.Money; import name.abuchen.portfolio.money.Values; @SuppressWarnings("nls") public class DABPDFExtractorTest { private Security getSecurity(List<Item> results) { Optional<Item> item = results.stream().filter(i -> i instanceof SecurityItem).findFirst(); assertThat(item.isPresent(), is(true)); return ((SecurityItem) item.get()).getSecurity(); } @Test public void testWertpapierKauf() throws IOException { DABPDFExctractor extractor = new DABPDFExctractor(new Client()) { @Override protected String strip(File file) throws IOException { return from(file.getName()); } }; List<Exception> errors = new ArrayList<Exception>(); List<Item> results = extractor.extract(Arrays.asList(new File("DABKauf.txt")), errors); assertThat(errors, empty()); assertThat(results.size(), is(2)); new AssertImportActions().check(results, CurrencyUnit.EUR); // check security Security security = getSecurity(results); assertThat(security.getIsin(), is("LU0360863863")); assertThat(security.getName(), is("ARERO - Der Weltfonds Inhaber-Anteile o.N.")); assertThat(security.getCurrencyCode(), is(CurrencyUnit.EUR)); // check buy sell transaction Optional<Item> item = results.stream().filter(i -> i instanceof BuySellEntryItem).findFirst(); assertThat(item.isPresent(), is(true)); assertThat(item.get().getSubject(), instanceOf(BuySellEntry.class)); BuySellEntry entry = (BuySellEntry) item.get().getSubject(); assertThat(entry.getPortfolioTransaction().getType(), is(PortfolioTransaction.Type.BUY)); assertThat(entry.getAccountTransaction().getType(), is(AccountTransaction.Type.BUY)); assertThat(entry.getPortfolioTransaction().getMonetaryAmount(), is(Money.of(CurrencyUnit.EUR, 150_00L))); assertThat(entry.getPortfolioTransaction().getDate(), is(LocalDate.parse("2015-01-06"))); assertThat(entry.getPortfolioTransaction().getShares(), is(Values.Share.factorize(0.91920))); assertThat(entry.getPortfolioTransaction().getUnitSum(Unit.Type.FEE), is(Money.of(CurrencyUnit.EUR, 0L))); } @Test public void testWertpapierKauf2() throws IOException { DABPDFExctractor extractor = new DABPDFExctractor(new Client()) { @Override protected String strip(File file) throws IOException { return from(file.getName()); } }; List<Exception> errors = new ArrayList<Exception>(); List<Item> results = extractor.extract(Arrays.asList(new File("DABKauf2.txt")), errors); assertThat(errors, empty()); assertThat(results.size(), is(2)); new AssertImportActions().check(results, CurrencyUnit.EUR); // check security Security security = getSecurity(results); assertThat(security.getIsin(), is("LU0274208692")); assertThat(security.getName(), is("db x-tr.MSCI World Index ETF Inhaber-Anteile 1C o.N.")); assertThat(security.getCurrencyCode(), is(CurrencyUnit.EUR)); // check buy sell transaction Optional<Item> item = results.stream().filter(i -> i instanceof BuySellEntryItem).findFirst(); assertThat(item.isPresent(), is(true)); assertThat(item.get().getSubject(), instanceOf(BuySellEntry.class)); BuySellEntry entry = (BuySellEntry) item.get().getSubject(); assertThat(entry.getPortfolioTransaction().getType(), is(PortfolioTransaction.Type.BUY)); assertThat(entry.getAccountTransaction().getType(), is(AccountTransaction.Type.BUY)); assertThat(entry.getPortfolioTransaction().getMonetaryAmount(), is(Money.of(CurrencyUnit.EUR, 60_00))); assertThat(entry.getPortfolioTransaction().getDate(), is(LocalDate.parse("2015-05-04"))); assertThat(entry.getPortfolioTransaction().getShares(), is(Values.Share.factorize(1.42270))); assertThat(entry.getPortfolioTransaction().getUnitSum(Unit.Type.FEE), is(Money.of(CurrencyUnit.EUR, 4_95L))); } @Test public void testWertpapierKauf3() throws IOException { DABPDFExctractor extractor = new DABPDFExctractor(new Client()) { @Override protected String strip(File file) throws IOException { return from(file.getName()); } }; List<Exception> errors = new ArrayList<Exception>(); List<Item> results = extractor.extract(Arrays.asList(new File("DABKauf3.txt")), errors); assertThat(errors, empty()); assertThat(results.size(), is(2)); new AssertImportActions().check(results, CurrencyUnit.EUR); // check security Security security = getSecurity(results); assertThat(security.getIsin(), is("LU0635178014")); assertThat(security.getName(), is("ComSta.-MSCI Em.Mkts.TRN U.ETF Inhaber-Anteile I o.N.")); assertThat(security.getCurrencyCode(), is(CurrencyUnit.EUR)); // check buy sell transaction Optional<Item> item = results.stream().filter(i -> i instanceof BuySellEntryItem).findFirst(); BuySellEntry entry = (BuySellEntry) item.get().getSubject(); assertThat(entry.getPortfolioTransaction().getType(), is(PortfolioTransaction.Type.BUY)); assertThat(entry.getPortfolioTransaction().getMonetaryAmount(), is(Money.of(CurrencyUnit.EUR, 325_00))); assertThat(entry.getPortfolioTransaction().getDate(), is(LocalDate.parse("2016-01-04"))); assertThat(entry.getPortfolioTransaction().getShares(), is(Values.Share.factorize(10.9468))); assertThat(entry.getPortfolioTransaction().getUnitSum(Unit.Type.FEE), is(Money.of(CurrencyUnit.EUR, 0L))); } @Test public void testWertpapierKauf4() throws IOException { DABPDFExctractor extractor = new DABPDFExctractor(new Client()) { @Override protected String strip(File file) throws IOException { return from(file.getName()); } }; List<Exception> errors = new ArrayList<Exception>(); List<Item> results = extractor.extract(Arrays.asList(new File("DABKauf4.txt")), errors); assertThat(errors, empty()); assertThat(results.size(), is(2)); new AssertImportActions().check(results, CurrencyUnit.EUR); // check security Security security = getSecurity(results); assertThat(security.getIsin(), is("US8270481091")); assertThat(security.getName(), is("Silgan Holdings Inc. Registered Shares DL -,01")); assertThat(security.getCurrencyCode(), is(CurrencyUnit.USD)); // check buy sell transaction Optional<Item> item = results.stream().filter(i -> i instanceof BuySellEntryItem).findFirst(); BuySellEntry entry = (BuySellEntry) item.get().getSubject(); assertThat(entry.getPortfolioTransaction().getType(), is(PortfolioTransaction.Type.BUY)); assertThat(entry.getPortfolioTransaction().getMonetaryAmount(), is(Money.of(CurrencyUnit.EUR, Values.Amount.factorize(4798.86)))); assertThat(entry.getPortfolioTransaction().getDate(), is(LocalDate.parse("2015-07-29"))); assertThat(entry.getPortfolioTransaction().getShares(), is(Values.Share.factorize(100))); assertThat(entry.getPortfolioTransaction().getUnitSum(Unit.Type.FEE), is(Money.of(CurrencyUnit.EUR, 0L))); } @Test public void testWertpapierVerkauf() throws IOException { DABPDFExctractor extractor = new DABPDFExctractor(new Client()) { @Override protected String strip(File file) throws IOException { return from(file.getName()); } }; List<Exception> errors = new ArrayList<Exception>(); List<Item> results = extractor.extract(Arrays.asList(new File("DABVerkauf.txt")), errors); assertThat(errors, empty()); assertThat(results.size(), is(2)); new AssertImportActions().check(results, CurrencyUnit.EUR); // check security Security security = getSecurity(results); assertThat(security.getIsin(), is("LU0392495700")); assertThat(security.getName(), is("ComStage-MSCI USA TRN UCIT.ETF Inhaber-Anteile I o.N.")); assertThat(security.getCurrencyCode(), is(CurrencyUnit.EUR)); // check buy sell transaction Optional<Item> item = results.stream().filter(i -> i instanceof BuySellEntryItem).findFirst(); assertThat(item.isPresent(), is(true)); assertThat(item.get().getSubject(), instanceOf(BuySellEntry.class)); BuySellEntry entry = (BuySellEntry) item.get().getSubject(); assertThat(entry.getPortfolioTransaction().getType(), is(PortfolioTransaction.Type.SELL)); assertThat(entry.getAccountTransaction().getType(), is(AccountTransaction.Type.SELL)); assertThat(entry.getPortfolioTransaction().getMonetaryAmount(), is(Money.of(CurrencyUnit.EUR, 1994_12))); assertThat(entry.getPortfolioTransaction().getDate(), is(LocalDate.parse("2015-12-23"))); assertThat(entry.getPortfolioTransaction().getShares(), is(Values.Share.factorize(43))); assertThat(entry.getPortfolioTransaction().getUnitSum(Unit.Type.FEE), is(Money.of(CurrencyUnit.EUR, 10_09))); assertThat(entry.getPortfolioTransaction().getUnitSum(Unit.Type.TAX), is(Money.of(CurrencyUnit.EUR, 45_88 + 2_52 + 4_12))); } @Test public void testWertpapierVerkauf2() throws IOException { DABPDFExctractor extractor = new DABPDFExctractor(new Client()) { @Override protected String strip(File file) throws IOException { return from(file.getName()); } }; List<Exception> errors = new ArrayList<Exception>(); List<Item> results = extractor.extract(Arrays.asList(new File("DABVerkauf2.txt")), errors); assertThat(errors, empty()); assertThat(results.size(), is(2)); new AssertImportActions().check(results, CurrencyUnit.EUR); // check security Security security = getSecurity(results); assertThat(security.getIsin(), is("US8270481091")); assertThat(security.getName(), is("Silgan Holdings Inc. Registered Shares DL -,01")); assertThat(security.getCurrencyCode(), is(CurrencyUnit.USD)); // check buy sell transaction Optional<Item> item = results.stream().filter(i -> i instanceof BuySellEntryItem).findFirst(); assertThat(item.isPresent(), is(true)); assertThat(item.get().getSubject(), instanceOf(BuySellEntry.class)); BuySellEntry entry = (BuySellEntry) item.get().getSubject(); assertThat(entry.getPortfolioTransaction().getType(), is(PortfolioTransaction.Type.SELL)); assertThat(entry.getAccountTransaction().getType(), is(AccountTransaction.Type.SELL)); assertThat(entry.getPortfolioTransaction().getMonetaryAmount(), is(Money.of(CurrencyUnit.EUR, Values.Amount.factorize(4465.12)))); assertThat(entry.getPortfolioTransaction().getDate(), is(LocalDate.parse("2015-08-24"))); assertThat(entry.getPortfolioTransaction().getShares(), is(Values.Share.factorize(100))); assertThat(entry.getPortfolioTransaction().getUnitSum(Unit.Type.TAX), is(Money.of(CurrencyUnit.EUR, Values.Amount.factorize(85.39 + 4.7)))); } @Test public void testWertpapierVerkauf3() throws IOException { DABPDFExctractor extractor = new DABPDFExctractor(new Client()) { @Override protected String strip(File file) throws IOException { return from(file.getName()); } }; List<Exception> errors = new ArrayList<Exception>(); List<Item> results = extractor.extract(Arrays.asList(new File("DABVerkauf3.txt")), errors); assertThat(errors, empty()); assertThat(results.size(), is(2)); new AssertImportActions().check(results, CurrencyUnit.EUR); // check security Security security = getSecurity(results); assertThat(security.getIsin(), is("US8270481091")); assertThat(security.getName(), is("Silgan Holdings Inc. Registered Shares DL -,01")); assertThat(security.getCurrencyCode(), is(CurrencyUnit.USD)); // check buy sell transaction Optional<Item> item = results.stream().filter(i -> i instanceof BuySellEntryItem).findFirst(); assertThat(item.isPresent(), is(true)); assertThat(item.get().getSubject(), instanceOf(BuySellEntry.class)); BuySellEntry entry = (BuySellEntry) item.get().getSubject(); assertThat(entry.getPortfolioTransaction().getType(), is(PortfolioTransaction.Type.SELL)); assertThat(entry.getAccountTransaction().getType(), is(AccountTransaction.Type.SELL)); assertThat(entry.getPortfolioTransaction().getMonetaryAmount(), is(Money.of(CurrencyUnit.EUR, Values.Amount.factorize(4447.21)))); assertThat(entry.getPortfolioTransaction().getDate(), is(LocalDate.parse("2015-08-24"))); assertThat(entry.getPortfolioTransaction().getShares(), is(Values.Share.factorize(100))); assertThat(entry.getPortfolioTransaction().getUnitSum(Unit.Type.TAX), is(Money.of(CurrencyUnit.EUR, Values.Amount.factorize(92.97 + 5.11)))); } @Test public void testDividend() throws IOException { DABPDFExctractor extractor = new DABPDFExctractor(new Client()) { @Override protected String strip(File file) throws IOException { return from(file.getName()); } }; List<Exception> errors = new ArrayList<Exception>(); List<Item> results = extractor.extract(Arrays.asList(new File("DABDividend.txt")), errors); assertThat(errors, empty()); assertThat(results.size(), is(2)); new AssertImportActions().check(results, CurrencyUnit.EUR); // check security Security security = getSecurity(results); assertThat(security.getIsin(), is("DE0005660104")); assertThat(security.getName(), is("EUWAX AG Inhaber-Aktien o.N.")); assertThat(security.getCurrencyCode(), is(CurrencyUnit.EUR)); // check buy sell transaction Optional<Item> item = results.stream().filter(i -> i instanceof TransactionItem).findFirst(); assertThat(item.isPresent(), is(true)); assertThat(item.get().getSubject(), instanceOf(AccountTransaction.class)); AccountTransaction transaction = (AccountTransaction) item.get().getSubject(); assertThat(transaction.getType(), is(AccountTransaction.Type.DIVIDENDS)); assertThat(transaction.getSecurity(), is(security)); assertThat(transaction.getMonetaryAmount(), is(Money.of(CurrencyUnit.EUR, 326_00))); assertThat(transaction.getDate(), is(LocalDate.parse("2014-07-02"))); assertThat(transaction.getShares(), is(Values.Share.factorize(100))); } @Test public void testDividendForeignCurrency() throws IOException { DABPDFExctractor extractor = new DABPDFExctractor(new Client()) { @Override protected String strip(File file) throws IOException { return from(file.getName()); } }; List<Exception> errors = new ArrayList<Exception>(); List<Item> results = extractor.extract(Arrays.asList(new File("DABDividendForeignCurrency.txt")), errors); assertThat(errors, empty()); assertThat(results.size(), is(2)); new AssertImportActions().check(results, CurrencyUnit.USD); // check security Security security = getSecurity(results); assertThat(security.getIsin(), is("US7427181091")); assertThat(security.getName(), is("Procter & Gamble Co., The Registered Shares o.N.")); assertThat(security.getCurrencyCode(), is(CurrencyUnit.USD)); // check buy sell transaction Optional<Item> item = results.stream().filter(i -> i instanceof TransactionItem).findFirst(); assertThat(item.isPresent(), is(true)); assertThat(item.get().getSubject(), instanceOf(AccountTransaction.class)); AccountTransaction transaction = (AccountTransaction) item.get().getSubject(); assertThat(transaction.getType(), is(AccountTransaction.Type.DIVIDENDS)); assertThat(transaction.getSecurity(), is(security)); assertThat(transaction.getMonetaryAmount(), is(Money.of(CurrencyUnit.USD, 56_91))); assertThat(transaction.getDate(), is(LocalDate.parse("2015-05-16"))); assertThat(transaction.getShares(), is(Values.Share.factorize(100))); } @Test public void testDividendInForeignCurrencyButSecurityListedInEuro() throws IOException { Client client = new Client(); Security security = new Security(); security.setName("Procter & Gamble Co., The Registered Shares o.N."); security.setIsin("US7427181091"); security.setCurrencyCode(CurrencyUnit.EUR); client.addSecurity(security); DABPDFExctractor extractor = new DABPDFExctractor(client) { @Override protected String strip(File file) throws IOException { return from(file.getName()); } }; List<Exception> errors = new ArrayList<Exception>(); List<Item> results = extractor.extract(Arrays.asList(new File("DABDividendForeignCurrency.txt")), errors); assertThat(errors, empty()); assertThat(results.size(), is(1)); new AssertImportActions().check(results, CurrencyUnit.USD); // check buy sell transaction Optional<Item> item = results.stream().filter(i -> i instanceof TransactionItem).findFirst(); assertThat(item.isPresent(), is(true)); assertThat(item.get().getSubject(), instanceOf(AccountTransaction.class)); AccountTransaction transaction = (AccountTransaction) item.get().getSubject(); assertThat(transaction.getType(), is(AccountTransaction.Type.DIVIDENDS)); assertThat(transaction.getSecurity(), is(security)); assertThat(transaction.getMonetaryAmount(), is(Money.of(CurrencyUnit.USD, 56_91))); assertThat(transaction.getDate(), is(LocalDate.parse("2015-05-16"))); assertThat(transaction.getShares(), is(Values.Share.factorize(100))); } @Test public void testDividend3() throws IOException { DABPDFExctractor extractor = new DABPDFExctractor(new Client()) { @Override protected String strip(File file) throws IOException { return from(file.getName()); } }; List<Exception> errors = new ArrayList<Exception>(); List<Item> results = extractor.extract(Arrays.asList(new File("DABDividend3.txt")), errors); assertThat(errors, empty()); assertThat(results.size(), is(2)); new AssertImportActions().check(results, CurrencyUnit.EUR); // check security Security security = getSecurity(results); assertThat(security.getIsin(), is("CH0012032048")); assertThat(security.getName(), is("Roche Holding AG Inhaber-Genußscheineo.N.")); assertThat(security.getCurrencyCode(), is("CHF")); // check buy sell transaction Optional<Item> item = results.stream().filter(i -> i instanceof TransactionItem).findFirst(); assertThat(item.isPresent(), is(true)); assertThat(item.get().getSubject(), instanceOf(AccountTransaction.class)); AccountTransaction transaction = (AccountTransaction) item.get().getSubject(); assertThat(transaction.getType(), is(AccountTransaction.Type.DIVIDENDS)); assertThat(transaction.getSecurity(), is(security)); assertThat(transaction.getMonetaryAmount(), is(Money.of(CurrencyUnit.EUR, Values.Amount.factorize(82.92)))); assertThat(transaction.getDate(), is(LocalDate.parse("2006-03-02"))); assertThat(transaction.getShares(), is(Values.Share.factorize(80))); } @Test public void testDividend4() throws IOException { DABPDFExctractor extractor = new DABPDFExctractor(new Client()) { @Override protected String strip(File file) throws IOException { return from(file.getName()); } }; List<Exception> errors = new ArrayList<Exception>(); List<Item> results = extractor.extract(Arrays.asList(new File("DABDividend4.txt")), errors); assertThat(errors, empty()); assertThat(results.size(), is(2)); new AssertImportActions().check(results, CurrencyUnit.EUR); // check security Security security = getSecurity(results); assertThat(security.getIsin(), is("US7033951036")); assertThat(security.getName(), is("Patterson Companies Inc. Registered Shares DL -,01")); assertThat(security.getCurrencyCode(), is(CurrencyUnit.USD)); // check buy sell transaction Optional<Item> item = results.stream().filter(i -> i instanceof TransactionItem).findFirst(); assertThat(item.isPresent(), is(true)); assertThat(item.get().getSubject(), instanceOf(AccountTransaction.class)); AccountTransaction transaction = (AccountTransaction) item.get().getSubject(); assertThat(transaction.getType(), is(AccountTransaction.Type.DIVIDENDS)); assertThat(transaction.getSecurity(), is(security)); assertThat(transaction.getMonetaryAmount(), is(Money.of(CurrencyUnit.EUR, Values.Amount.factorize(80.92)))); assertThat(transaction.getDate(), is(LocalDate.parse("2016-07-29"))); assertThat(transaction.getShares(), is(Values.Share.factorize(500))); } @Test public void testDividend5() throws IOException { DABPDFExctractor extractor = new DABPDFExctractor(new Client()) { @Override protected String strip(File file) throws IOException { return from(file.getName()); } }; List<Exception> errors = new ArrayList<Exception>(); List<Item> results = extractor.extract(Arrays.asList(new File("DABDividend5.txt")), errors); assertThat(errors, empty()); assertThat(results.size(), is(2)); new AssertImportActions().check(results, CurrencyUnit.EUR); // check security Security security = getSecurity(results); assertThat(security.getIsin(), is("ZAE000042164")); assertThat(security.getName(), is("MTN Group Ltd. Registered Shares RC -,0001")); assertThat(security.getCurrencyCode(), is("ZAR")); // check buy sell transaction Optional<Item> item = results.stream().filter(i -> i instanceof TransactionItem).findFirst(); assertThat(item.isPresent(), is(true)); assertThat(item.get().getSubject(), instanceOf(AccountTransaction.class)); AccountTransaction transaction = (AccountTransaction) item.get().getSubject(); assertThat(transaction.getType(), is(AccountTransaction.Type.DIVIDENDS)); assertThat(transaction.getSecurity(), is(security)); assertThat(transaction.getMonetaryAmount(), is(Money.of(CurrencyUnit.EUR, Values.Amount.factorize(586.80)))); assertThat(transaction.getDate(), is(LocalDate.parse("2015-03-30"))); assertThat(transaction.getShares(), is(Values.Share.factorize(1300))); } @Test public void testDividend6() throws IOException { DABPDFExctractor extractor = new DABPDFExctractor(new Client()) { @Override protected String strip(File file) throws IOException { return from(file.getName()); } }; List<Exception> errors = new ArrayList<Exception>(); List<Item> results = extractor.extract(Arrays.asList(new File("DABDividend6.txt")), errors); assertThat(errors, empty()); assertThat(results.size(), is(2)); new AssertImportActions().check(results, CurrencyUnit.EUR); // check security Security security = getSecurity(results); assertThat(security.getIsin(), is("DE0006483001")); assertThat(security.getName(), is("Linde AG Inhaber-Aktien o.N.")); assertThat(security.getCurrencyCode(), is(CurrencyUnit.EUR)); // check buy sell transaction Optional<Item> item = results.stream().filter(i -> i instanceof TransactionItem).findFirst(); assertThat(item.isPresent(), is(true)); assertThat(item.get().getSubject(), instanceOf(AccountTransaction.class)); AccountTransaction transaction = (AccountTransaction) item.get().getSubject(); assertThat(transaction.getType(), is(AccountTransaction.Type.DIVIDENDS)); assertThat(transaction.getSecurity(), is(security)); assertThat(transaction.getMonetaryAmount(), is(Money.of(CurrencyUnit.EUR, Values.Amount.factorize(198.79)))); assertThat(transaction.getDate(), is(LocalDate.parse("2013-05-31"))); assertThat(transaction.getShares(), is(Values.Share.factorize(100))); } private String from(String resource) { try (Scanner scanner = new Scanner(getClass().getResourceAsStream(resource), StandardCharsets.UTF_8.name())) { return scanner.useDelimiter("\\A").next(); } } }