@Override
 public Status process(AccountTransaction transaction, Account account) {
   // ensure consistency (in case the user deleted the creation of the
   // security via the dialog)
   if (transaction.getSecurity() != null) process(transaction.getSecurity());
   account.addTransaction(transaction);
   return Status.OK_STATUS;
 }
  @Test
  public void testErtragsgutschrift() throws IOException {
    DeutscheBankPDFExctractor extractor =
        new DeutscheBankPDFExctractor(new Client()) {
          @Override
          String strip(File file) throws IOException {
            return from("DeutscheBankErtragsgutschrift.txt");
          }
        };
    List<Exception> errors = new ArrayList<Exception>();

    List<Item> results = extractor.extract(Arrays.asList(new File("t")), errors);

    assertThat(errors, empty());
    assertThat(results.size(), is(2));
    new AssertImportActions().check(results, CurrencyUnit.EUR);

    // check security
    Security security = assertSecurity(results);

    // check 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.getDate(), is(LocalDate.parse("2014-12-15")));
    assertThat(transaction.getMonetaryAmount(), is(Money.of(CurrencyUnit.EUR, 1495L)));
    assertThat(transaction.getShares(), is(Values.Share.factorize(123)));
  }
  @Test
  public void testErtragsgutschriftWhenSecurityExists() throws IOException {
    Client client = new Client();
    Security security = new Security("BASF", "DE000BASF111", null, null);
    client.addSecurity(security);

    DeutscheBankPDFExctractor extractor =
        new DeutscheBankPDFExctractor(client) {
          @Override
          String strip(File file) throws IOException {
            return from("DeutscheBankErtragsgutschrift.txt");
          }
        };
    List<Exception> errors = new ArrayList<Exception>();

    List<Item> results = extractor.extract(Arrays.asList(new File("t")), errors);

    assertThat(errors, empty());
    assertThat(results.size(), is(1));
    new AssertImportActions().check(results, CurrencyUnit.EUR);

    // check transaction
    AccountTransaction transaction = (AccountTransaction) results.get(0).getSubject();
    assertThat(transaction.getType(), is(AccountTransaction.Type.DIVIDENDS));
    assertThat(transaction.getSecurity(), is(security));
  }
 private void adaptAccountTransactions(
     Account account, ReadOnlyAccount pseudoAccount, Set<Security> usedSecurities) {
   for (AccountTransaction t : account.getTransactions()) {
     switch (t.getType()) {
       case BUY:
         if (portfolios.contains(t.getCrossEntry().getCrossOwner(t)))
           pseudoAccount.internalAddTransaction(t);
         else pseudoAccount.internalAddTransaction(convertTo(t, AccountTransaction.Type.REMOVAL));
         break;
       case SELL:
         if (portfolios.contains(t.getCrossEntry().getCrossOwner(t)))
           pseudoAccount.internalAddTransaction(t);
         else pseudoAccount.internalAddTransaction(convertTo(t, AccountTransaction.Type.DEPOSIT));
         break;
       case TRANSFER_IN:
         if (accounts.contains(t.getCrossEntry().getCrossOwner(t)))
           pseudoAccount.internalAddTransaction(t);
         else pseudoAccount.internalAddTransaction(convertTo(t, AccountTransaction.Type.DEPOSIT));
         break;
       case TRANSFER_OUT:
         if (accounts.contains(t.getCrossEntry().getCrossOwner(t)))
           pseudoAccount.internalAddTransaction(t);
         else pseudoAccount.internalAddTransaction(convertTo(t, AccountTransaction.Type.REMOVAL));
         break;
       case DIVIDENDS:
       case TAX_REFUND:
         if (t.getSecurity() == null || usedSecurities.contains(t.getSecurity()))
           pseudoAccount.internalAddTransaction(t);
         else pseudoAccount.internalAddTransaction(convertTo(t, AccountTransaction.Type.DEPOSIT));
         break;
       case DEPOSIT:
       case REMOVAL:
       case INTEREST:
       case INTEREST_CHARGE:
       case TAXES:
       case FEES:
         pseudoAccount.internalAddTransaction(t);
         break;
       default:
         throw new UnsupportedOperationException();
     }
   }
 }
  private void collectDividends(
      Portfolio portfolio, ReadOnlyAccount pseudoAccount, Set<Security> usedSecurities) {
    if (portfolio.getReferenceAccount() == null) return;

    for (AccountTransaction t : portfolio.getReferenceAccount().getTransactions()) // NOSONAR
    {
      if (t.getSecurity() == null) continue;

      if (!usedSecurities.contains(t.getSecurity())) continue;

      switch (t.getType()) {
        case TAX_REFUND:
          // security must be non-null -> tax refund is relevant for
          // performance of security
        case DIVIDENDS:
          pseudoAccount.internalAddTransaction(t);
          pseudoAccount.internalAddTransaction(
              new AccountTransaction(
                  t.getDate(),
                  t.getCurrencyCode(),
                  t.getAmount(),
                  null,
                  AccountTransaction.Type.REMOVAL));
          break;
        case BUY:
        case TRANSFER_IN:
        case SELL:
        case TRANSFER_OUT:
        case DEPOSIT:
        case REMOVAL:
        case INTEREST:
        case INTEREST_CHARGE:
        case TAXES:
        case FEES:
          // do nothing
          break;
        default:
          throw new UnsupportedOperationException();
      }
    }
  }
  private static void extractSecurityRelatedAccountTransactions(
      Account account, ReportingPeriod period, Map<Security, SecurityPerformanceRecord> records) {
    for (AccountTransaction t : account.getTransactions()) {
      if (t.getSecurity() == null) continue;

      if (!period.containsTransaction().test(t)) continue;

      if (t.getType() == AccountTransaction.Type.DIVIDENDS //
          || t.getType() == AccountTransaction.Type.INTEREST) {
        DividendTransaction dt = new DividendTransaction();
        dt.setDate(t.getDate());
        dt.setSecurity(t.getSecurity());
        dt.setAccount(account);
        dt.setCurrencyCode(t.getCurrencyCode());
        dt.setAmount(t.getAmount());
        dt.setShares(t.getShares());
        dt.setNote(t.getNote());
        records.get(t.getSecurity()).addTransaction(dt);
      } else if (t.getType() == AccountTransaction.Type.TAX_REFUND) {
        records.get(t.getSecurity()).addTransaction(t);
      }
    }
  }
  @Test
  public void testErtragsgutschrift2() throws IOException {
    DeutscheBankPDFExctractor extractor =
        new DeutscheBankPDFExctractor(new Client()) {
          @Override
          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("DeutscheBankErtragsgutschrift2.txt")), errors);

    assertThat(errors, empty());
    assertThat(results.size(), is(2));
    new AssertImportActions().check(results, CurrencyUnit.EUR);

    // check security
    Security security =
        results.stream().filter(i -> i instanceof SecurityItem).findFirst().get().getSecurity();
    assertThat(security.getName(), is("ISHS-MSCI N. AMERIC.UCITS ETF BE.SH.(DT.ZT.)"));
    assertThat(security.getIsin(), is("DE000A0J2060"));
    assertThat(security.getWkn(), is("A0J206"));
    assertThat(security.getCurrencyCode(), is("USD"));

    // check 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.getDate(), is(LocalDate.parse("2015-03-24")));
    assertThat(transaction.getMonetaryAmount(), is(Money.of(CurrencyUnit.EUR, 16_17L)));
    assertThat(transaction.getShares(), is(Values.Share.factorize(123)));

    Optional<Unit> grossValue = transaction.getUnit(Unit.Type.GROSS_VALUE);
    assertThat(grossValue.isPresent(), is(true));
    assertThat(grossValue.get().getAmount(), is(Money.of("EUR", 16_17L)));
    assertThat(grossValue.get().getForex(), is(Money.of("USD", 17_38L)));
    assertThat(
        grossValue.get().getExchangeRate().doubleValue(), IsCloseTo.closeTo(0.930578, 0.000001));
  }