bool MyMoneyReport::includes( const MyMoneyAccount& acc ) const
{
  bool result = false;

  if ( includesAccountGroup ( acc.accountGroup() ) )
  {
    switch ( acc.accountGroup() )
    {
      case MyMoneyAccount::Income:
      case MyMoneyAccount::Expense:
        if ( isTax() )
          result = ( acc.value ( "Tax" ) == "Yes" ) && includesCategory ( acc.id() );
        else
          result = includesCategory ( acc.id() );
        break;
      case MyMoneyAccount::Asset:
      case MyMoneyAccount::Liability:
        if ( isLoansOnly() )
          result = acc.isLoan() && includesAccount ( acc.id() );
        else if ( isInvestmentsOnly() )
          result = acc.isInvest() && includesAccount ( acc.id() );
        else if ( isIncludingTransfers() && m_rowType == MyMoneyReport::eExpenseIncome )
          // If transfers are included, ONLY include this account if it is NOT
          // included in the report itself!!
          result = ! includesAccount ( acc.id() );
        else
          result = includesAccount ( acc.id() );
        break;
      default:
        result = includesAccount ( acc.id() );
    }
  }
  return result;
}
int MyMoneyForecast::daysToZeroBalance(const MyMoneyAccount& acc)
{
  dailyBalances balance;

  //Check if acc is not a forecast account, return -1
  if(!isForecastAccount(acc)) {
    return -2;
  }

  balance = m_accountList[acc.id()];

  if (acc.accountGroup() == MyMoneyAccount::Asset) {
    for (QDate it_day = QDate::currentDate() ; it_day <= forecastEndDate(); )
    {
      if ( balance[it_day] < MyMoneyMoney ( 0, 1 ) )
      {
        return QDate::currentDate().daysTo(it_day);
      }
      it_day = it_day.addDays(1);
    }
  } else if (acc.accountGroup() == MyMoneyAccount::Liability) {
    for (QDate it_day = QDate::currentDate() ; it_day <= forecastEndDate(); )
    {
      if ( balance[it_day] > MyMoneyMoney ( 0, 1 ) )
      {
        return QDate::currentDate().daysTo(it_day);
      }
      it_day = it_day.addDays(1);
    }
  }
  return -1;
}
MyMoneyMoney MyMoneyForecast::calculateAccountTrend(const MyMoneyAccount& acc, int trendDays)
{
  MyMoneyFile* file = MyMoneyFile::instance();
  MyMoneyTransactionFilter filter;
  MyMoneyMoney netIncome;
  QDate startDate;
  QDate openingDate = acc.openingDate();

  //validate arguments
  if(trendDays < 1)
  {
    throw new MYMONEYEXCEPTION("Illegal arguments when calling calculateAccountTrend. trendDays must be higher than 0");
  }

  //If it is a new account, we don't take into account the first day
  //because it is usually a weird one and it would mess up the trend
  if(openingDate.daysTo(QDate::currentDate())<trendDays){
    startDate = (acc.openingDate()).addDays(1);
  }
  else {
    startDate = QDate::currentDate().addDays(-trendDays);
  }
  //get all transactions for the period
  filter.setDateFilter(startDate, QDate::currentDate());
  if(acc.accountGroup() == MyMoneyAccount::Income
     || acc.accountGroup() == MyMoneyAccount::Expense) {
    filter.addCategory(acc.id());
     } else {
       filter.addAccount(acc.id());
     }

  filter.setReportAllSplits(false);
  QValueList<MyMoneyTransaction> transactions = file->transactionList(filter);
  QValueList<MyMoneyTransaction>::const_iterator it_t = transactions.begin();

  //add all transactions for that account
  for(; it_t != transactions.end(); ++it_t ) {
    const QValueList<MyMoneySplit>& splits = (*it_t).splits();
    QValueList<MyMoneySplit>::const_iterator it_s = splits.begin();
    for(; it_s != splits.end(); ++it_s ) {
      if(!(*it_s).shares().isZero()) {
        if(acc.id()==(*it_s).accountId()) netIncome += (*it_s).value();
      }
    }
  }

  //calculate trend of the account in the past period
  MyMoneyMoney accTrend;

  //don't take into account the first day of the account
  if(openingDate.daysTo(QDate::currentDate())<trendDays) {
    accTrend = netIncome/MyMoneyMoney(openingDate.daysTo(QDate::currentDate())-1,1);
  } else {
    accTrend = netIncome/MyMoneyMoney(trendDays,1);
  }
  return accTrend;
}
void MyMoneyQifWriter::writeTransactionEntry(QTextStream &s, const MyMoneyTransaction& t, const QString& accountId)
{
  MyMoneyFile* file = MyMoneyFile::instance();
  MyMoneySplit split = t.splitByAccount(accountId);

  s << "D" << m_qifProfile.date(t.postDate()) << endl;

  switch(split.reconcileFlag()) {
    case MyMoneySplit::Cleared:
      s << "C*" << endl;
      break;

    case MyMoneySplit::Reconciled:
    case MyMoneySplit::Frozen:
      s << "CX" << endl;
      break;

    default:
      break;
  }

  if(split.memo().length() > 0) {
    QString m = split.memo();
    m.replace('\n', "\\n");
    s << "M" << m << endl;
  }

  s << "T" << m_qifProfile.value('T', split.value()) << endl;

  if(split.number().length() > 0)
    s << "N" << split.number() << endl;

  if(!split.payeeId().isEmpty()) {
    MyMoneyPayee payee = file->payee(split.payeeId());
    s << "P" << payee.name() << endl;
  }

  QValueList<MyMoneySplit> list = t.splits();
  if(list.count() > 1) {
    MyMoneySplit sp = t.splitByAccount(accountId, false);
    MyMoneyAccount acc = file->account(sp.accountId());
    if(acc.accountGroup() != MyMoneyAccount::Income
    && acc.accountGroup() != MyMoneyAccount::Expense) {
      s << "L" << m_qifProfile.accountDelimiter()[0]
              << MyMoneyFile::instance()->accountToCategory(sp.accountId())
              << m_qifProfile.accountDelimiter()[1] << endl;
    } else {
      s << "L" << file->accountToCategory(sp.accountId()) << endl;
    }
    if(list.count() > 2) {
      QValueList<MyMoneySplit>::ConstIterator it;
      for(it = list.begin(); it != list.end(); ++it) {
        if(!((*it) == split)) {
          writeSplitEntry(s, *it);
        }
      }
    }
  }
  s << "^" << endl;
}
Exemple #5
0
void CsvUtil::dissectTransaction(const MyMoneyTransaction& transaction, const MyMoneySplit& split, MyMoneySplit& assetAccountSplit, QList<MyMoneySplit>& feeSplits, QList<MyMoneySplit>& interestSplits, MyMoneySecurity& security, MyMoneySecurity& currency, MyMoneySplit::investTransactionTypeE& transactionType)
{
  // collect the splits. split references the stock account and should already
  // be set up. assetAccountSplit references the corresponding asset account (maybe
  // empty), feeSplits is the list of all expenses and interestSplits
  // the list of all incomes
  MyMoneyFile* file = MyMoneyFile::instance();
  QList<MyMoneySplit>::ConstIterator it_s;
  for (it_s = transaction.splits().constBegin(); it_s != transaction.splits().constEnd(); ++it_s) {
    MyMoneyAccount acc = file->account((*it_s).accountId());
    if ((*it_s).id() == split.id()) {
      security = file->security(acc.currencyId());
    } else if (acc.accountGroup() == MyMoneyAccount::Expense) {
      feeSplits.append(*it_s);
    } else if (acc.accountGroup() == MyMoneyAccount::Income) {
      interestSplits.append(*it_s);
    } else {
      assetAccountSplit = *it_s;
    }
  }

  // determine transaction type
  if (split.action() == MyMoneySplit::ActionAddShares) {
    transactionType = (!split.shares().isNegative()) ? MyMoneySplit::AddShares : MyMoneySplit::RemoveShares;
  } else if (split.action() == MyMoneySplit::ActionBuyShares) {
    transactionType = (!split.value().isNegative()) ? MyMoneySplit::BuyShares : MyMoneySplit::SellShares;
  } else if (split.action() == MyMoneySplit::ActionDividend) {
    transactionType = MyMoneySplit::Dividend;
  } else if (split.action() == MyMoneySplit::ActionReinvestDividend) {
    transactionType = MyMoneySplit::ReinvestDividend;
  } else if (split.action() == MyMoneySplit::ActionYield) {
    transactionType = MyMoneySplit::Yield;
  } else if (split.action() == MyMoneySplit::ActionSplitShares) {
    transactionType = MyMoneySplit::SplitShares;
  } else if (split.action() == MyMoneySplit::ActionInterestIncome) {
    transactionType = MyMoneySplit::InterestIncome;
  } else
    transactionType = MyMoneySplit::BuyShares;

  currency.setTradingSymbol("???");
  try {
    currency = file->security(transaction.commodity());
  } catch (const MyMoneyException &) {
  }
}
void MyMoneyQifWriter::writeSplitEntry(QTextStream& s, const MyMoneySplit& split)
{
  MyMoneyFile* file = MyMoneyFile::instance();

  s << "S";
  MyMoneyAccount acc = file->account(split.accountId());
  if(acc.accountGroup() != MyMoneyAccount::Income
  && acc.accountGroup() != MyMoneyAccount::Expense) {
    s << m_qifProfile.accountDelimiter()[0]
      << file->accountToCategory(split.accountId())
      << m_qifProfile.accountDelimiter()[1];
  } else {
    s << file->accountToCategory(split.accountId());
  }
  s << endl;

  if(split.memo().length() > 0) {
    QString m = split.memo();
    m.replace('\n', "\\n");
    s << "E" << m << endl;
  }

  s << "$" << m_qifProfile.value('$', -split.value()) << endl;
}
Exemple #7
0
void CsvUtil::createAccount(MyMoneyAccount& newAccount, MyMoneyAccount& parentAccount, MyMoneyAccount& brokerageAccount, MyMoneyMoney openingBal)
{
  MyMoneyFile* file = MyMoneyFile::instance();

  // make sure we have a currency. If none is assigned, we assume base currency
  if (newAccount.currencyId().isEmpty())
    newAccount.setCurrencyId(file->baseCurrency().id());

  MyMoneyFileTransaction ft;
  try {
    int pos;
    // check for ':' in the name and use it as separator for a hierarchy
    while ((pos = newAccount.name().indexOf(MyMoneyFile::AccountSeperator)) != -1) {
      QString part = newAccount.name().left(pos);
      QString remainder = newAccount.name().mid(pos + 1);
      const MyMoneyAccount& existingAccount = file->subAccountByName(parentAccount, part);
      if (existingAccount.id().isEmpty()) {
        newAccount.setName(part);

        file->addAccount(newAccount, parentAccount);
        parentAccount = newAccount;
      } else {
        parentAccount = existingAccount;
      }
      newAccount.setParentAccountId(QString());  // make sure, there's no parent
      newAccount.clearId();                       // and no id set for adding
      newAccount.removeAccountIds();              // and no sub-account ids
      newAccount.setName(remainder);
    }

    const MyMoneySecurity& sec = file->security(newAccount.currencyId());
    // Check the opening balance
    if (openingBal.isPositive() && newAccount.accountGroup() == MyMoneyAccount::Liability) {
      QString message = i18n("This account is a liability and if the "
                             "opening balance represents money owed, then it should be negative.  "
                             "Negate the amount?\n\n"
                             "Please click Yes to change the opening balance to %1,\n"
                             "Please click No to leave the amount as %2,\n"
                             "Please click Cancel to abort the account creation."
                             , MyMoneyUtils::formatMoney(-openingBal, newAccount, sec)
                             , MyMoneyUtils::formatMoney(openingBal, newAccount, sec));

      int ans = KMessageBox::questionYesNoCancel(0, message);
      if (ans == KMessageBox::Yes) {
        openingBal = -openingBal;

      } else if (ans == KMessageBox::Cancel)
        return;
    }

    file->addAccount(newAccount, parentAccount);

    if (newAccount.accountType() == MyMoneyAccount::Investment
        && !brokerageAccount.name().isEmpty()) {
      file->addAccount(brokerageAccount, parentAccount);

      // set a link from the investment account to the brokerage account
      file->modifyAccount(newAccount);
      file->createOpeningBalanceTransaction(brokerageAccount, openingBal);

    } else
      file->createOpeningBalanceTransaction(newAccount, openingBal);

    ft.commit();
  } catch (const MyMoneyException &e) {
    KMessageBox::information(0, i18n("Unable to add account: %1", e.what()));
  }
}
void KNewAccountDlg::okClicked()
{
  MyMoneyFile* file = MyMoneyFile::instance();

  QString accountNameText = accountNameEdit->text();
  if (accountNameText.isEmpty())
  {
    KMessageBox::error(this, i18n("You have not specified a name.\nPlease fill in this field."));
    accountNameEdit->setFocus();
    return;
  }

  MyMoneyAccount parent = parentAccount();
  if (parent.name().length() == 0)
  {
    KMessageBox::error(this, i18n("Please select a parent account."));
    return;
  }

  if (!m_categoryEditor)
  {
    QString institutionNameText = m_qcomboboxInstitutions->currentText();
    if (institutionNameText != i18n("<No Institution>"))
    {
      try
      {
        MyMoneyFile *file = MyMoneyFile::instance();

        QValueList<MyMoneyInstitution> list = file->institutionList();
        QValueList<MyMoneyInstitution>::ConstIterator institutionIterator;
        for (institutionIterator = list.begin(); institutionIterator != list.end(); ++institutionIterator)
        {
          if ((*institutionIterator).name() == institutionNameText)
            m_account.setInstitutionId((*institutionIterator).id());
        }
      }
      catch (MyMoneyException *e)
      {
        qDebug("Exception in account institution set: %s", e->what().latin1());
        delete e;
      }
    }
    else
    {
      m_account.setInstitutionId(QString());
    }
  }

  m_account.setName(accountNameText);
  m_account.setNumber(accountNoEdit->text());
  storeKVP("iban", ibanEdit);
  storeKVP("minBalanceAbsolute", m_minBalanceAbsoluteEdit);
  storeKVP("minBalanceEarly", m_minBalanceEarlyEdit);

  // the figures for credit line with reversed sign
  if(!m_maxCreditAbsoluteEdit->lineedit()->text().isEmpty())
    m_maxCreditAbsoluteEdit->setValue(m_maxCreditAbsoluteEdit->value()*MyMoneyMoney(-1,1));
  if(!m_maxCreditEarlyEdit->lineedit()->text().isEmpty())
    m_maxCreditEarlyEdit->setValue(m_maxCreditEarlyEdit->value()*MyMoneyMoney(-1,1));
  storeKVP("maxCreditAbsolute", m_maxCreditAbsoluteEdit);
  storeKVP("maxCreditEarly", m_maxCreditEarlyEdit);
  if(!m_maxCreditAbsoluteEdit->lineedit()->text().isEmpty())
    m_maxCreditAbsoluteEdit->setValue(m_maxCreditAbsoluteEdit->value()*MyMoneyMoney(-1,1));
  if(!m_maxCreditEarlyEdit->lineedit()->text().isEmpty())
    m_maxCreditEarlyEdit->setValue(m_maxCreditEarlyEdit->value()*MyMoneyMoney(-1,1));

  storeKVP("lastNumberUsed", m_lastCheckNumberUsed);
  // delete a previous version of the minimumbalance information
  storeKVP("minimumBalance", QString(), QString());

  MyMoneyAccount::accountTypeE acctype;
  if (!m_categoryEditor)
  {
    acctype = KMyMoneyUtils::stringToAccountType(typeCombo->currentText());
    // If it's a loan, check if the parent is asset or liability. In
    // case of asset, we change the account type to be AssetLoan
    if(acctype == MyMoneyAccount::Loan
    && parent.accountGroup() == MyMoneyAccount::Asset)
      acctype = MyMoneyAccount::AssetLoan;

#if 0
    // we do allow the same name for different accounts, so
    // we don't need this check anymore.
    if(!file->nameToAccount(accountNameText).isEmpty()
    && (file->nameToAccount(accountNameText) != m_account.id())) {
      KMessageBox::error(this, QString("<qt>")+i18n("An account named <b>%1</b> already exists. You cannot create a second account with the same name.").arg(accountNameText)+QString("</qt>"));
      return;
    }
#endif
  }
  else
  {
    acctype = parent.accountGroup();
    QString newName;
    if(!MyMoneyFile::instance()->isStandardAccount(parent.id())) {
      newName = MyMoneyFile::instance()->accountToCategory(parent.id()) + MyMoneyFile::AccountSeperator;
    }
    newName += accountNameText;
    if(!file->categoryToAccount(newName, acctype).isEmpty()
    && (file->categoryToAccount(newName, acctype) != m_account.id())) {
      KMessageBox::error(this, QString("<qt>")+i18n("A category named <b>%1</b> already exists. You cannot create a second category with the same name.").arg(newName)+QString("</qt>"));
      return;
    }
  }
  m_account.setAccountType(acctype);

  m_account.setDescription(descriptionEdit->text());

  if (!m_categoryEditor)
  {
    m_account.setOpeningDate(startDateEdit->date());
    m_account.setCurrencyId(m_currency->security().id());

    if(m_qcheckboxPreferred->isChecked())
      m_account.setValue("PreferredAccount", "Yes");
    else
      m_account.deletePair("PreferredAccount");
    if(m_qcheckboxNoVat->isChecked())
      m_account.setValue("NoVat", "Yes");
    else
      m_account.deletePair("NoVat");

    if(m_minBalanceAbsoluteEdit->isVisible()) {
      m_account.setValue("minimumBalance", m_minBalanceAbsoluteEdit->value().toString());
    }
  }
  else
  {
    if(KMyMoneyGlobalSettings::hideUnusedCategory() && !m_isEditing) {
      KMessageBox::information(this, i18n("You have selected to suppress the display of unused categories in the KMyMoney configuration dialog. The category you just created will therefore only be shown if it is used. Otherwise, it will be hidden in the accounts/categories view."), i18n("Hidden categories"), "NewHiddenCategory");
    }
  }

  if ( m_qcheckboxTax->isChecked())
    m_account.setValue("Tax", "Yes");
  else
    m_account.deletePair("Tax");

  m_account.deletePair("VatAccount");
  m_account.deletePair("VatAmount");
  m_account.deletePair("VatRate");

  if(m_vatCategory->isChecked()) {
    m_account.setValue("VatRate", (m_vatRate->value().abs() / MyMoneyMoney(100,1)).toString());
  } else {
    if(m_vatAssignment->isChecked()) {
      m_account.setValue("VatAccount", m_vatAccount->selectedItems().first());
      if(m_netAmount->isChecked())
        m_account.setValue("VatAmount", "Net");
    }
  }

  accept();
}
void MyMoneyStorageDump::writeStream(QDataStream& _s, IMyMoneySerialize* _storage)
{
  QTextStream s(_s.device());
  IMyMoneyStorage* storage = dynamic_cast<IMyMoneyStorage *>(_storage);
  MyMoneyPayee user = storage->user();

  s << "File-Info\n";
  s << "---------\n";
  s << "user name = " << user.name() << "\n";
  s << "user street = " << user.address() << "\n";
  s << "user city = " << user.city() << "\n";
  s << "user city = " << user.state() << "\n";
  s << "user zip = " << user.postcode() << "\n";
  s << "user telephone = " << user.telephone() << "\n";
  s << "user e-mail = " << user.email() << "\n";
  s << "creation date = " << storage->creationDate().toString(Qt::ISODate) << "\n";
  s << "last modification date = " << storage->lastModificationDate().toString(Qt::ISODate) << "\n";
  s << "base currency = " << storage->value("kmm-baseCurrency") << "\n";
  s << "\n";

  s << "Internal-Info\n";
  s << "-------------\n";
  QList<MyMoneyAccount> list_a;
  storage->accountList(list_a);
  s << "accounts = " << list_a.count() << ", next id = " << _storage->accountId() << "\n";
  MyMoneyTransactionFilter filter;
  filter.setReportAllSplits(false);
  QList<MyMoneyTransaction> list_t;
  storage->transactionList(list_t, filter);
  QList<MyMoneyTransaction>::ConstIterator it_t;
  s << "transactions = " << list_t.count() << ", next id = " << _storage->transactionId() << "\n";
  QMap<int, int> xferCount;
  for (it_t = list_t.constBegin(); it_t != list_t.constEnd(); ++it_t) {
    QList<MyMoneySplit>::ConstIterator it_s;
    int accountCount = 0;
    for (it_s = (*it_t).splits().constBegin(); it_s != (*it_t).splits().constEnd(); ++it_s) {
      MyMoneyAccount acc = storage->account((*it_s).accountId());
      if (acc.accountGroup() != MyMoneyAccount::Expense
          && acc.accountGroup() != MyMoneyAccount::Income)
        accountCount++;
    }
    if (accountCount > 1)
      xferCount[accountCount] = xferCount[accountCount] + 1;
  }
  QMap<int, int>::ConstIterator it_cnt;
  for (it_cnt = xferCount.constBegin(); it_cnt != xferCount.constEnd(); ++it_cnt) {
    s << "               " << *it_cnt << " of them references " << it_cnt.key() << " accounts\n";
  }

  s << "payees = " << _storage->payeeList().count() << ", next id = " << _storage->payeeId() << "\n";
  s << "tags = " << _storage->tagList().count() << ", next id = " << _storage->tagId() << "\n";
  s << "institutions = " << _storage->institutionList().count() << ", next id = " << _storage->institutionId() << "\n";
  s << "schedules = " << _storage->scheduleList().count() << ", next id = " << _storage->scheduleId() << "\n";
  s << "\n";

  s << "Institutions\n";
  s << "------------\n";

  QList<MyMoneyInstitution> list_i = storage->institutionList();
  QList<MyMoneyInstitution>::ConstIterator it_i;
  for (it_i = list_i.constBegin(); it_i != list_i.constEnd(); ++it_i) {
    s << "  ID = " << (*it_i).id() << "\n";
    s << "  Name = " << (*it_i).name() << "\n";
    s << "\n";
  }
  s << "\n";

  s << "Payees" << "\n";
  s << "------" << "\n";

  QList<MyMoneyPayee> list_p = storage->payeeList();
  QList<MyMoneyPayee>::ConstIterator it_p;
  for (it_p = list_p.constBegin(); it_p != list_p.constEnd(); ++it_p) {
    s << "  ID = " << (*it_p).id() << "\n";
    s << "  Name = " << (*it_p).name() << "\n";
    s << "  Address = " << (*it_p).address() << "\n";
    s << "  City = " << (*it_p).city() << "\n";
    s << "  State = " << (*it_p).state() << "\n";
    s << "  Zip = " << (*it_p).postcode() << "\n";
    s << "  E-Mail = " << (*it_p).email() << "\n";
    s << "  Telephone = " << (*it_p).telephone() << "\n";
    s << "  Reference = " << (*it_p).reference() << "\n";
    s << "\n";
  }
  s << "\n";

  s << "Tags" << "\n";
  s << "------" << "\n";

  QList<MyMoneyTag> list_ta = storage->tagList();
  QList<MyMoneyTag>::ConstIterator it_ta;
  for (it_ta = list_ta.constBegin(); it_ta != list_ta.constEnd(); ++it_ta) {
    s << "  ID = " << (*it_ta).id() << "\n";
    s << "  Name = " << (*it_ta).name() << "\n";
    s << "  Closed = " << (*it_ta).isClosed() << "\n";
    s << "  TagColor = " << (*it_ta).tagColor().name() << "\n";
    s << "  Notes = " << (*it_ta).notes() << "\n";
    s << "\n";
  }
  s << "\n";

  s << "Accounts" << "\n";
  s << "--------" << "\n";

  list_a.push_front(storage->equity());
  list_a.push_front(storage->expense());
  list_a.push_front(storage->income());
  list_a.push_front(storage->liability());
  list_a.push_front(storage->asset());
  QList<MyMoneyAccount>::ConstIterator it_a;
  for (it_a = list_a.constBegin(); it_a != list_a.constEnd(); ++it_a) {
    s << "  ID = " << (*it_a).id() << "\n";
    s << "  Name = " << (*it_a).name() << "\n";
    s << "  Number = " << (*it_a).number() << "\n";
    s << "  Description = " << (*it_a).description() << "\n";
    s << "  Type = " << (*it_a).accountType() << "\n";
    if ((*it_a).currencyId().isEmpty()) {
      s << "  Currency = unknown\n";
    } else {
      if ((*it_a).isInvest()) {
        s << "  Equity = " << storage->security((*it_a).currencyId()).name() << "\n";
      } else {
        s << "  Currency = " << storage->currency((*it_a).currencyId()).name() << "\n";
      }
    }
    s << "  Parent = " << (*it_a).parentAccountId();
    if (!(*it_a).parentAccountId().isEmpty()) {
      MyMoneyAccount parent = storage->account((*it_a).parentAccountId());
      s << " (" << parent.name() << ")";
    } else {
      s << "n/a";
    }
    s << "\n";

    s << "  Institution = " << (*it_a).institutionId();
    if (!(*it_a).institutionId().isEmpty()) {
      MyMoneyInstitution inst = storage->institution((*it_a).institutionId());
      s << " (" << inst.name() << ")";
    } else {
      s << "n/a";
    }
    s << "\n";

    s << "  Opening date = " << (*it_a).openingDate().toString(Qt::ISODate) << "\n";
    s << "  Last modified = " << (*it_a).lastModified().toString(Qt::ISODate) << "\n";
    s << "  Last reconciled = " << (*it_a).lastReconciliationDate().toString(Qt::ISODate) << "\n";
    s << "  Balance = " << (*it_a).balance().formatMoney("", 2) << "\n";

    dumpKVP("  KVP: ", s, *it_a);
    dumpKVP("  OnlineBankingSettings: ", s, (*it_a).onlineBankingSettings());

    QStringList list_s = (*it_a).accountList();
    QStringList::ConstIterator it_s;
    if (list_s.count() > 0) {
      s << "  Children =" << "\n";
    }
    for (it_s = list_s.constBegin(); it_s != list_s.constEnd(); ++it_s) {
      MyMoneyAccount child = storage->account(*it_s);
      s << "    " << *it_s << " (" << child.name() << ")\n";
    }
    s << "\n";
  }
  s << "\n";

#if 0
  s << "Currencies" << "\n";
  s << "----------" << "\n";

  QList<MyMoneyCurrency> list_c = storage->currencyList();
  QList<MyMoneyCurrency>::ConstIterator it_c;
  for (it_c = list_c.begin(); it_c != list_c.end(); ++it_c) {
    s << "  Name = " << (*it_c).name() << "\n";
    s << "    ID = " << (*it_c).id() << "\n";
    s << "    Symbol = " << (*it_c).tradingSymbol() << "\n";
    s << "    Parts/Unit = " << (*it_c).partsPerUnit() << "\n";
    s << "    smallest cash fraction = " << (*it_c).smallestCashFraction() << "\n";
    s << "    smallest account fraction = " << (*it_c).smallestAccountFraction() << "\n";
    dumpPriceHistory(s, (*it_c).priceHistory());
    s << "\n";
  }
  s << "\n";
#endif

  s << "Securities" << "\n";
  s << "----------" << "\n";

  QList<MyMoneySecurity> list_e = storage->securityList();
  QList<MyMoneySecurity>::ConstIterator it_e;
  for (it_e = list_e.constBegin(); it_e != list_e.constEnd(); ++it_e) {
    s << "  Name = " << (*it_e).name() << "\n";
    s << "    ID = " << (*it_e).id() << "\n";
    s << "    Market   = " << (*it_e).tradingMarket() << "\n";
    s << "    Symbol   = " << (*it_e).tradingSymbol() << "\n";
    s << "    Currency = " << (*it_e).tradingCurrency() << " (";
    if ((*it_e).tradingCurrency().isEmpty()) {
      s << "unknown";
    } else {
      MyMoneySecurity tradingCurrency = storage->currency((*it_e).tradingCurrency());
      if (!tradingCurrency.isCurrency()) {
        s << "invalid currency: ";
      }
      s << tradingCurrency.name();
    }
    s << ")\n";

    s << "    Type = " << MyMoneySecurity::securityTypeToString((*it_e).securityType()) << "\n";
    s << "    smallest account fraction = " << (*it_e).smallestAccountFraction() << "\n";

    s << "    KVP: " << "\n";
    QMap<QString, QString>kvp = (*it_e).pairs();
    QMap<QString, QString>::Iterator it;
    for (it = kvp.begin(); it != kvp.end(); ++it) {
      s << "      '" << it.key() << "' = '" << it.value() << "'\n";
    }
    s << "\n";
  }
  s << "\n";

  s << "Prices" << "\n";
  s << "--------" << "\n";

  MyMoneyPriceList list_pr = _storage->priceList();
  MyMoneyPriceList::ConstIterator it_pr;
  for (it_pr = list_pr.constBegin(); it_pr != list_pr.constEnd(); ++it_pr) {
    s << "  From = " << it_pr.key().first << "\n";
    s << "    To = " << it_pr.key().second << "\n";
    MyMoneyPriceEntries::ConstIterator it_pre;
    for (it_pre = (*it_pr).constBegin(); it_pre != (*it_pr).constEnd(); ++it_pre) {
      s << "      Date = " << (*it_pre).date().toString() << "\n";
      s << "        Price = " << (*it_pre).rate(QString()).formatMoney("", 8) << "\n";
      s << "        Source = " << (*it_pre).source() << "\n";
      s << "        From = " << (*it_pre).from() << "\n";
      s << "        To   = " << (*it_pre).to() << "\n";
    }
    s << "\n";
  }
  s << "\n";

  s << "Transactions" << "\n";
  s << "------------" << "\n";

  for (it_t = list_t.constBegin(); it_t != list_t.constEnd(); ++it_t) {
    dumpTransaction(s, storage, *it_t);
  }
  s << "\n";


  s << "Schedules" << "\n";
  s << "---------" << "\n";

  QList<MyMoneySchedule> list_s = storage->scheduleList();
  QList<MyMoneySchedule>::ConstIterator it_s;
  for (it_s = list_s.constBegin(); it_s != list_s.constEnd(); ++it_s) {
    s << "  ID = " << (*it_s).id() << "\n";
    s << "  Name = " << (*it_s).name() << "\n";
    s << "  Startdate = " << (*it_s).startDate().toString(Qt::ISODate) << "\n";
    if ((*it_s).willEnd())
      s << "  Enddate   = " << (*it_s).endDate().toString(Qt::ISODate) << "\n";
    else
      s << "  Enddate   = not specified\n";
    s << "  Occurence = " << (*it_s).occurrenceToString() << "\n"; // krazy:exclude=spelling
    s << "  OccurenceMultiplier = " << (*it_s).occurrenceMultiplier() << "\n";
    s << "  Type = " << MyMoneySchedule::scheduleTypeToString((*it_s).type()) << "\n";
    s << "  Paymenttype = " << MyMoneySchedule::paymentMethodToString((*it_s).paymentType()) << "\n";
    s << "  Fixed = " << (*it_s).isFixed() << "\n";
    s << "  AutoEnter = " << (*it_s).autoEnter() << "\n";

    if ((*it_s).lastPayment().isValid())
      s << "  Last payment = " << (*it_s).lastPayment().toString(Qt::ISODate) << "\n";
    else
      s << "  Last payment = not defined" << "\n";
    if ((*it_s).isFinished())
      s << "  Next payment = payment finished" << "\n";
    else {
      s << "  Next payment = " << (*it_s).nextDueDate().toString(Qt::ISODate) << "\n";
      if ((*it_s).isOverdue())
        s << "               = overdue!" << "\n";
    }

    QList<QDate> list_d;
    QList<QDate>::ConstIterator it_d;

    list_d = (*it_s).recordedPayments();
    if (list_d.count() > 0) {
      s << "  Recorded payments" << "\n";
      for (it_d = list_d.constBegin(); it_d != list_d.constEnd(); ++it_d) {
        s << "    " << (*it_d).toString(Qt::ISODate) << "\n";
      }
    }
    s << "  TRANSACTION\n";
    dumpTransaction(s, storage, (*it_s).transaction());
  }
  s << "\n";

  s << "Reports" << "\n";
  s << "-------" << "\n";

  QList<MyMoneyReport> list_r = storage->reportList();
  QList<MyMoneyReport>::ConstIterator it_r;
  for (it_r = list_r.constBegin(); it_r != list_r.constEnd(); ++it_r) {
    s << "  ID = " << (*it_r).id() << "\n";
    s << "  Name = " << (*it_r).name() << "\n";
  }

  s << "Budgets" << "\n";
  s << "-------" << "\n";

  QList<MyMoneyBudget> list_b = storage->budgetList();
  QList<MyMoneyBudget>::ConstIterator it_b;
  for (it_b = list_b.constBegin(); it_b != list_b.constEnd(); ++it_b) {
    s << "  ID = " << (*it_b).id() << "\n";
    s << "  Name = " << (*it_b).name() << "\n";
  }
}