diff --git a/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/IBActivityStatementWithDuplicateTransactions.xml b/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/IBActivityStatementWithDuplicateTransactions.xml
new file mode 100644
index 0000000000..b9c4492ea9
--- /dev/null
+++ b/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/IBActivityStatementWithDuplicateTransactions.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/IBFlexStatementExtractorWithDuplicateTransactionsTest.java b/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/IBFlexStatementExtractorWithDuplicateTransactionsTest.java
new file mode 100644
index 0000000000..d943173181
--- /dev/null
+++ b/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/IBFlexStatementExtractorWithDuplicateTransactionsTest.java
@@ -0,0 +1,111 @@
+package name.abuchen.portfolio.datatransfer;
+
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import org.apache.pdfbox.io.IOUtils;
+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.model.AccountTransaction;
+import name.abuchen.portfolio.model.Client;
+import name.abuchen.portfolio.model.Transaction.Unit;
+import name.abuchen.portfolio.money.CurrencyUnit;
+import name.abuchen.portfolio.money.Money;
+
+@SuppressWarnings("nls")
+public class IBFlexStatementExtractorWithDuplicateTransactionsTest
+{
+ private List- runExtractor(List errors) throws IOException
+ {
+ InputStream activityStatement = getClass().getResourceAsStream("IBActivityStatementWithDuplicateTransactions.xml");
+ Client client = new Client();
+ Extractor.InputFile tempFile = createTempFile(activityStatement);
+ IBFlexStatementExtractor extractor = new IBFlexStatementExtractor(client);
+
+ return extractor.extract(Collections.singletonList(tempFile), errors);
+ }
+
+ @Test
+ public void testIBAcitvityStatement() throws IOException
+ {
+ List errors = new ArrayList();
+ List
- results = runExtractor(errors);
+ assertTrue(errors.isEmpty());
+ int numSecurity = 0;
+ int numBuySell = 0;
+ int numTransactions = 1;
+
+ results.stream().filter(i -> !(i instanceof SecurityItem))
+ .forEach(i -> assertThat(i.getAmount(), notNullValue()));
+
+ List securityItems = results.stream().filter(i -> i instanceof SecurityItem)
+ .collect(Collectors.toList());
+
+ assertThat(securityItems.size(), is(numSecurity));
+
+ List buySellTransactions = results.stream().filter(i -> i instanceof BuySellEntryItem)
+ .collect(Collectors.toList());
+
+ assertThat(buySellTransactions.size(), is(numBuySell));
+
+ List accountTransactions = results.stream().filter(i -> i instanceof TransactionItem)
+ .collect(Collectors.toList());
+
+ assertThat(accountTransactions.size(), is(numTransactions));
+
+ assertThat(results.size(), is(numSecurity + numBuySell + numTransactions));
+
+ assertFirstSecurity(results.stream().filter(i -> i instanceof SecurityItem).findFirst());
+ assertFirstTransaction(results.stream().filter(i -> i instanceof TransactionItem).findFirst());
+ assertSecondTransaction(results.stream().filter(i -> i instanceof TransactionItem).skip(1).findFirst());
+ }
+
+ private void assertFirstTransaction(Optional
- item)
+ {
+ assertThat(item.isPresent(), is(true));
+ assertThat(item.get().getSubject(), instanceOf(AccountTransaction.class));
+ AccountTransaction transaction = (AccountTransaction) item.get().getSubject();
+
+ assertThat(transaction.getType(), is(AccountTransaction.Type.INTEREST));
+
+ assertThat(transaction.getMonetaryAmount(), is(Money.of(CurrencyUnit.USD, 0_02L)));
+ assertThat(transaction.getCurrencyCode(), is(CurrencyUnit.USD));
+ assertTrue(!transaction.getUnit(Unit.Type.GROSS_VALUE).isPresent());
+ }
+
+ private void assertSecondTransaction(Optional
- item)
+ {
+ assertThat(item.isPresent(), is(false));
+ }
+
+ private void assertFirstSecurity(Optional
- item)
+ {
+ assertThat(item.isPresent(), is(false));
+ }
+
+ private Extractor.InputFile createTempFile(InputStream input) throws IOException
+ {
+ File tempFile = File.createTempFile("iBFlexStatementExtractorTest", null);
+ FileOutputStream fos = new FileOutputStream(tempFile);
+
+ IOUtils.copy(input, fos);
+ return new Extractor.InputFile(tempFile);
+ }
+}
diff --git a/name.abuchen.portfolio/src/name/abuchen/portfolio/datatransfer/IBFlexStatementExtractor.java b/name.abuchen.portfolio/src/name/abuchen/portfolio/datatransfer/IBFlexStatementExtractor.java
index bfa2692f69..d2222e246e 100644
--- a/name.abuchen.portfolio/src/name/abuchen/portfolio/datatransfer/IBFlexStatementExtractor.java
+++ b/name.abuchen.portfolio/src/name/abuchen/portfolio/datatransfer/IBFlexStatementExtractor.java
@@ -323,7 +323,11 @@ else if (this.ibAccountCurrency.equals(s.getCurrencyCode()))
transaction.setNote(element.getAttribute("description"));
- return new TransactionItem(transaction);
+ // Transactions which do not have an account-id will not be imported.
+ if (!element.getAttribute("accountId").equals("-"))
+ return new TransactionItem(transaction);
+ else
+ return null;
};
/**