void KInstitutionsView::slotUpdateNetWorth(void)
{
  MyMoneyMoney netWorth;

  // calculate by going through the account trees top items
  // and summing up the total value shown there
  KMyMoneyAccountTreeItem* item = dynamic_cast<KMyMoneyAccountTreeItem*>(m_accountTree->firstChild());
  while(item) {
    netWorth += item->totalValue();
    item = dynamic_cast<KMyMoneyAccountTreeItem*>(item->nextSibling());
  }

  QString s(i18n("Net Worth: "));

  // FIXME figure out how to deal with the approximate
  // if(!(file->totalValueValid(assetAccount.id()) & file->totalValueValid(liabilityAccount.id())))
  //  s += "~ ";

  s.replace(QString(" "), QString("&nbsp;"));
  if(netWorth.isNegative()) {
    s += "<b><font color=\"red\">";
  }
  const MyMoneySecurity& sec = MyMoneyFile::instance()->baseCurrency();
  QString v(netWorth.formatMoney(sec));
  s += v.replace(QString(" "), QString("&nbsp;"));
  if(netWorth.isNegative()) {
    s += "</font></b>";
  }

  m_totalProfitsLabel->setFont(KMyMoneyGlobalSettings::listCellFont());
  m_totalProfitsLabel->setText(s);
}
QString makeAccount( const QString& _name, MyMoneyAccount::accountTypeE _type, MyMoneyMoney _balance, const QDate& _open, const QString& _parent, QString _currency, bool _taxReport )
{
  MyMoneyAccount info;
  MyMoneyFileTransaction ft;

  info.setName(_name);
  info.setAccountType(_type);
  info.setOpeningDate(_open);
  if ( _currency != "" )
    info.setCurrencyId(_currency);
  else
    info.setCurrencyId(MyMoneyFile::instance()->baseCurrency().id());

  if(_taxReport)
    info.setValue("Tax", "Yes");

  MyMoneyAccount parent = MyMoneyFile::instance()->account(_parent);
  MyMoneyFile::instance()->addAccount( info, parent );
  // create the opening balance transaction if any
  if(!_balance.isZero()) {
    MyMoneySecurity sec = MyMoneyFile::instance()->currency(info.currencyId());
    MyMoneyFile::instance()->openingBalanceAccount(sec);
    MyMoneyFile::instance()->createOpeningBalanceTransaction(info, _balance);
  }
  ft.commit();

  return info.id();
}
Example #3
0
void KForecastView::setValue(QTreeWidgetItem* item, int column, const MyMoneyMoney& amount, const QDate& forecastDate)
{
  MyMoneyAccount account = item->data(0, AccountRole).value<MyMoneyAccount>();
  //calculate the balance in base currency for the total row
  if (account.currencyId() != MyMoneyFile::instance()->baseCurrency().id()) {
    ReportAccount repAcc = ReportAccount(account.id());
    MyMoneyMoney curPrice = repAcc.baseCurrencyPrice(forecastDate);
    MyMoneyMoney baseAmountMM = amount * curPrice;
    MyMoneyMoney value = baseAmountMM.convert(MyMoneyFile::instance()->baseCurrency().smallestAccountFraction());
    item->setData(column, ValueRole, QVariant::fromValue(value));
    adjustParentValue(item->parent(), column, value);
  } else {
    item->setData(column, ValueRole, QVariant::fromValue(item->data(column, ValueRole).value<MyMoneyMoney>() + amount));
    adjustParentValue(item->parent(), column, amount);
  }
}
Example #4
0
PivotCell PivotCell::operator += (const MyMoneyMoney& value)
{
  m_cellUsed |= !value.isZero();
  if (m_stockSplit != MyMoneyMoney::ONE)
    m_postSplit += value;
  else
    MyMoneyMoney::operator += (value);
  return *this;
}
Example #5
0
void KForecastView::showAmount(QTreeWidgetItem* item, int column, const MyMoneyMoney& amount, const MyMoneySecurity& security)
{
  item->setText(column, MyMoneyUtils::formatMoney(amount, item->data(0, AccountRole).value<MyMoneyAccount>(), security));
  item->setTextAlignment(column, Qt::AlignRight | Qt::AlignVCenter);
  item->setFont(column, item->font(0));
  if (amount.isNegative()) {
    item->setForeground(column, KMyMoneyGlobalSettings::listNegativeValueColor());
  }
}
void KMyMoneyAccountTreeForecastItem::setValue(int column, MyMoneyMoney amount, QDate forecastDate)
{
  KMyMoneyAccountTreeForecastItem* p = dynamic_cast<KMyMoneyAccountTreeForecastItem*>(parent());

  //calculate the balance in base currency for the total row
  if(m_account.currencyId() != listView()->baseCurrency().id()) {
    ReportAccount repAcc = ReportAccount(m_account.id());
    MyMoneyMoney curPrice = repAcc.baseCurrencyPrice(forecastDate);
    MyMoneyMoney baseAmountMM = amount * curPrice;
    m_values[column] = baseAmountMM.convert(listView()->baseCurrency().smallestAccountFraction());

    if(p != 0) {
      p->adjustParentValue(column, m_values[column]);
    }
  } else {
    m_values[column] += amount;
    if(p != 0) {
      p->adjustParentValue(column, amount);
    }
  }
}
int KInvestmentListItem::compare(QListViewItem* i, int col, bool ascending) const
{
  KInvestmentListItem* item = dynamic_cast<KInvestmentListItem*>(i);
  // do special sorting only for numeric columns
  // in all other cases use the standard sorting
  if(item) {
    switch(col) {
      case COLUMN_VALUE_INDEX:
      case COLUMN_QUANTITY_INDEX:
      case COLUMN_PRICE_INDEX:
      {
        bool inv1 = text(col) == "---";
        bool inv2 = item->text(col) == "---";
        if(!inv1 && !inv2) {
          MyMoneyMoney result = MyMoneyMoney(text(col)) - MyMoneyMoney(item->text(col));
          if(result.isNegative())
            return -1;
          if(result.isZero())
            return 0;
          return 1;
        } else if(inv1 && inv2) {
          return 0;
        } else if(inv1) {
          return -1;
        }
        return 1;
      }
      break;

      default:
        break;
    }
  }

  // do standard sorting here
  return KListViewItem::compare(i, col, ascending);
}
Example #8
0
const QString PivotCell::formatMoney(const QString& currency, const int prec, bool showThousandSeparator) const
{
  // construct the result
  MyMoneyMoney res = (*this * m_stockSplit) + m_postSplit;
  return res.formatMoney(currency, prec, showThousandSeparator);
}
Example #9
0
void MyMoneyForecast::calculateAutoLoan(const MyMoneySchedule& schedule, MyMoneyTransaction& transaction, const QMap<QString, MyMoneyMoney>& balances)
{
  if (schedule.type() == MyMoneySchedule::TYPE_LOANPAYMENT) {

    //get amortization and interest autoCalc splits
    MyMoneySplit amortizationSplit = transaction.amortizationSplit();
    MyMoneySplit interestSplit = transaction.interestSplit();

    if(!amortizationSplit.id().isEmpty() && !interestSplit.id().isEmpty()) {
      MyMoneyAccountLoan acc(MyMoneyFile::instance()->account(amortizationSplit.accountId()));
      MyMoneyFinancialCalculator calc;
      QDate dueDate;

      // FIXME: setup dueDate according to when the interest should be calculated
      // current implementation: take the date of the next payment according to
      // the schedule. If the calculation is based on the payment reception, and
      // the payment is overdue then take the current date
      dueDate = schedule.nextDueDate();
      if(acc.interestCalculation() == MyMoneyAccountLoan::paymentReceived) {
        if(dueDate < QDate::currentDate())
          dueDate = QDate::currentDate();
      }

      // we need to calculate the balance at the time the payment is due

      MyMoneyMoney balance;
      if(balances.count() == 0)
        balance = MyMoneyFile::instance()->balance(acc.id(), dueDate.addDays(-1));
      else
        balance = balances[acc.id()];

      /*
         QValueList<MyMoneyTransaction> list;
         QValueList<MyMoneyTransaction>::ConstIterator it;
         MyMoneySplit split;
         MyMoneyTransactionFilter filter(acc.id());

         filter.setDateFilter(QDate(), dueDate.addDays(-1));
         list = MyMoneyFile::instance()->transactionList(filter);

         for(it = list.begin(); it != list.end(); ++it) {
         try {
         split = (*it).splitByAccount(acc.id());
         balance += split.value();

         } catch(MyMoneyException *e) {
      // account is not referenced within this transaction
      delete e;
      }
      }
      */

      // FIXME: for now, we only support interest calculation at the end of the period
      calc.setBep();
      // FIXME: for now, we only support periodic compounding
      calc.setDisc();

      calc.setPF(MyMoneySchedule::eventsPerYear(schedule.occurence()));
      MyMoneySchedule::occurenceE compoundingOccurence = static_cast<MyMoneySchedule::occurenceE>(acc.interestCompounding());
      if(compoundingOccurence == MyMoneySchedule::OCCUR_ANY)
        compoundingOccurence = schedule.occurence();

      calc.setCF(MyMoneySchedule::eventsPerYear(compoundingOccurence));

      calc.setPv(balance.toDouble());
      calc.setIr(static_cast<FCALC_DOUBLE> (acc.interestRate(dueDate).abs().toDouble()));
      calc.setPmt(acc.periodicPayment().toDouble());

      MyMoneyMoney interest(calc.interestDue()), amortization;
      interest = interest.abs();    // make sure it's positive for now
      amortization = acc.periodicPayment() - interest;

      if(acc.accountType() == MyMoneyAccount::AssetLoan) {
        interest = -interest;
        amortization = -amortization;
      }

      amortizationSplit.setShares(amortization);
      interestSplit.setShares(interest);

      // FIXME: for now we only assume loans to be in the currency of the transaction
      amortizationSplit.setValue(amortization);
      interestSplit.setValue(interest);

      transaction.modifySplit(amortizationSplit);
      transaction.modifySplit(interestSplit);
    }
  }
}
Example #10
0
void KForecastView::loadAdvancedView()
{
  MyMoneyFile* file = MyMoneyFile::instance();
  QList<MyMoneyAccount> accList;
  MyMoneySecurity baseCurrency = file->baseCurrency();
  MyMoneyForecast forecast = KMyMoneyGlobalSettings::forecast();
  int daysToBeginDay;

  //get the settings from current page
  forecast.setForecastDays(m_forecastDays->value());
  forecast.setAccountsCycle(m_accountsCycle->value());
  forecast.setBeginForecastDay(m_beginDay->value());
  forecast.setForecastCycles(m_forecastCycles->value());
  forecast.setHistoryMethod(m_historyMethod->checkedId());
  forecast.doForecast();

  //Get all accounts of the right type to calculate forecast
  m_nameIdx.clear();
  accList = forecast.accountList();
  QList<MyMoneyAccount>::const_iterator accList_t = accList.constBegin();
  for (; accList_t != accList.constEnd(); ++accList_t) {
    MyMoneyAccount acc = *accList_t;
    if (m_nameIdx[acc.id()] != acc.id()) { //Check if the account is there
      m_nameIdx[acc.id()] = acc.id();
    }
  }
  //clear the list, including columns
  m_advancedList->clear();
  m_advancedList->setColumnCount(0);
  m_advancedList->setIconSize(QSize(22, 22));

  QStringList headerLabels;

  //add first column of both lists
  headerLabels << i18n("Account");

  //if beginning of forecast is today, set the begin day to next cycle to avoid repeating the first cycle
  if (QDate::currentDate() < forecast.beginForecastDate()) {
    daysToBeginDay = QDate::currentDate().daysTo(forecast.beginForecastDate());
  } else {
    daysToBeginDay = forecast.accountsCycle();
  }

  //add columns
  for (int i = 1; ((i * forecast.accountsCycle()) + daysToBeginDay) <= forecast.forecastDays(); ++i) {
    headerLabels << i18n("Min Bal %1", i);
    headerLabels << i18n("Min Date %1", i);
  }
  for (int i = 1; ((i * forecast.accountsCycle()) + daysToBeginDay) <= forecast.forecastDays(); ++i) {
    headerLabels << i18n("Max Bal %1", i);
    headerLabels << i18n("Max Date %1", i);
  }
  headerLabels << i18nc("Average balance", "Average");

  m_advancedList->setHeaderLabels(headerLabels);

  QTreeWidgetItem *advancedItem = 0;

  QMap<QString, QString>::ConstIterator it_nc;
  for (it_nc = m_nameIdx.constBegin(); it_nc != m_nameIdx.constEnd(); ++it_nc) {
    const MyMoneyAccount& acc = file->account(*it_nc);
    QString amount;
    MyMoneyMoney amountMM;
    MyMoneySecurity currency;

    //change currency to deep currency if account is an investment
    if (acc.isInvest()) {
      MyMoneySecurity underSecurity = file->security(acc.currencyId());
      currency = file->security(underSecurity.tradingCurrency());
    } else {
      currency = file->security(acc.currencyId());
    }


    advancedItem = new QTreeWidgetItem(m_advancedList, advancedItem, false);
    advancedItem->setText(0, acc.name());
    advancedItem->setIcon(0, acc.accountPixmap());
    int it_c = 1; // iterator for the columns of the listview

    //get minimum balance list
    QList<QDate> minBalanceList = forecast.accountMinimumBalanceDateList(acc);
    QList<QDate>::Iterator t_min;
    for (t_min = minBalanceList.begin(); t_min != minBalanceList.end() ; ++t_min) {
      QDate minDate = *t_min;
      amountMM = forecast.forecastBalance(acc, minDate);

      amount = MyMoneyUtils::formatMoney(amountMM, acc, currency);
      advancedItem->setText(it_c, amount);
      advancedItem->setTextAlignment(it_c, Qt::AlignRight | Qt::AlignVCenter);
      if (amountMM.isNegative()) {
        advancedItem->setForeground(it_c, KMyMoneyGlobalSettings::listNegativeValueColor());
      }
      it_c++;

      QString dateString = QLocale().toString(minDate, QLocale::ShortFormat);
      advancedItem->setText(it_c, dateString);
      advancedItem->setTextAlignment(it_c, Qt::AlignRight | Qt::AlignVCenter);
      if (amountMM.isNegative()) {
        advancedItem->setForeground(it_c, KMyMoneyGlobalSettings::listNegativeValueColor());
      }
      it_c++;
    }

    //get maximum balance list
    QList<QDate> maxBalanceList = forecast.accountMaximumBalanceDateList(acc);
    QList<QDate>::Iterator t_max;
    for (t_max = maxBalanceList.begin(); t_max != maxBalanceList.end() ; ++t_max) {
      QDate maxDate = *t_max;
      amountMM = forecast.forecastBalance(acc, maxDate);

      amount = MyMoneyUtils::formatMoney(amountMM, acc, currency);
      advancedItem->setText(it_c, amount);
      advancedItem->setTextAlignment(it_c, Qt::AlignRight | Qt::AlignVCenter);
      if (amountMM.isNegative()) {
        advancedItem->setForeground(it_c, KMyMoneyGlobalSettings::listNegativeValueColor());
      }
      it_c++;

      QString dateString = QLocale().toString(maxDate, QLocale::ShortFormat);
      advancedItem->setText(it_c, dateString);
      advancedItem->setTextAlignment(it_c, Qt::AlignRight | Qt::AlignVCenter);
      if (amountMM.isNegative()) {
        advancedItem->setForeground(it_c, KMyMoneyGlobalSettings::listNegativeValueColor());
      }
      it_c++;
    }
    //get average balance
    amountMM = forecast.accountAverageBalance(acc);
    amount = MyMoneyUtils::formatMoney(amountMM, acc, currency);
    advancedItem->setText(it_c, amount);
    advancedItem->setTextAlignment(it_c, Qt::AlignRight | Qt::AlignVCenter);
    if (amountMM.isNegative()) {
      advancedItem->setForeground(it_c, KMyMoneyGlobalSettings::listNegativeValueColor());
    }
    it_c++;
  }

  // make sure all data is shown
  adjustHeadersAndResizeToContents(m_advancedList);

  m_advancedList->show();
}
Example #11
0
void KForecastView::loadSummaryView()
{
  MyMoneyForecast forecast = KMyMoneyGlobalSettings::forecast();
  QList<MyMoneyAccount> accList;
  int dropMinimum;
  int dropZero;

  MyMoneyFile* file = MyMoneyFile::instance();

  //get the settings from current page
  forecast.setForecastDays(m_forecastDays->value());
  forecast.setAccountsCycle(m_accountsCycle->value());
  forecast.setBeginForecastDay(m_beginDay->value());
  forecast.setForecastCycles(m_forecastCycles->value());
  forecast.setHistoryMethod(m_historyMethod->checkedId());
  forecast.doForecast();

  //add columns
  QStringList headerLabels;
  headerLabels << i18n("Account");
  headerLabels << i18nc("Today's forecast", "Current");

  //if beginning of forecast is today, set the begin day to next cycle to avoid repeating the first cycle
  int daysToBeginDay;
  if (QDate::currentDate() < forecast.beginForecastDate()) {
    daysToBeginDay = QDate::currentDate().daysTo(forecast.beginForecastDate());
  } else {
    daysToBeginDay = forecast.accountsCycle();
  }
  for (int i = 0; ((i*forecast.accountsCycle()) + daysToBeginDay) <= forecast.forecastDays(); ++i) {
    int intervalDays = ((i * forecast.accountsCycle()) + daysToBeginDay);
    headerLabels << i18np("1 day", "%1 days", intervalDays);
  }

  //add variation columns
  headerLabels << i18n("Total variation");

  m_summaryList->clear();
  //set the columns
  m_summaryList->setHeaderLabels(headerLabels);

  m_summaryList->setIconSize(QSize(22, 22));
  m_summaryList->setSortingEnabled(true);
  m_summaryList->sortByColumn(0, Qt::AscendingOrder);

  //add default rows
  addTotalRow(m_summaryList, forecast);
  addAssetLiabilityRows(forecast);

  loadAccounts(forecast, file->asset(), m_assetItem, eSummary);
  loadAccounts(forecast, file->liability(), m_liabilityItem, eSummary);

  adjustHeadersAndResizeToContents(m_summaryList);

  //Add comments to the advice list
  m_adviceText->clear();

  //Get all accounts of the right type to calculate forecast
  m_nameIdx.clear();
  accList = forecast.accountList();
  QList<MyMoneyAccount>::const_iterator accList_t = accList.constBegin();
  for (; accList_t != accList.constEnd(); ++accList_t) {
    MyMoneyAccount acc = *accList_t;
    if (m_nameIdx[acc.id()] != acc.id()) { //Check if the account is there
      m_nameIdx[acc.id()] = acc.id();
    }
  }

  QMap<QString, QString>::ConstIterator it_nc;
  for (it_nc = m_nameIdx.constBegin(); it_nc != m_nameIdx.constEnd(); ++it_nc) {

    const MyMoneyAccount& acc = file->account(*it_nc);
    MyMoneySecurity currency;

    //change currency to deep currency if account is an investment
    if (acc.isInvest()) {
      MyMoneySecurity underSecurity = file->security(acc.currencyId());
      currency = file->security(underSecurity.tradingCurrency());
    } else {
      currency = file->security(acc.currencyId());
    }

    //Check if the account is going to be below zero or below the minimal balance in the forecast period
    QString minimumBalance = acc.value("minimumBalance");
    MyMoneyMoney minBalance = MyMoneyMoney(minimumBalance);

    //Check if the account is going to be below minimal balance
    dropMinimum = forecast.daysToMinimumBalance(acc);

    //Check if the account is going to be below zero in the future
    dropZero = forecast.daysToZeroBalance(acc);

    // spit out possible warnings
    QString msg;

    // if a minimum balance has been specified, an appropriate warning will
    // only be shown, if the drop below 0 is on a different day or not present

    if (dropMinimum != -1
        && !minBalance.isZero()
        && (dropMinimum < dropZero
            || dropZero == -1)) {
      switch (dropMinimum) {
        case -1:
          break;
        case 0:
          msg = QString("<font color=\"%1\">").arg(KMyMoneyGlobalSettings::listNegativeValueColor().name());
          msg += i18n("The balance of %1 is below the minimum balance %2 today.", acc.name(), MyMoneyUtils::formatMoney(minBalance, acc, currency));
          msg += QString("</font>");
          break;
        default:
          msg = QString("<font color=\"%1\">").arg(KMyMoneyGlobalSettings::listNegativeValueColor().name());
          msg += i18np("The balance of %2 will drop below the minimum balance %3 in %1 day.",
                       "The balance of %2 will drop below the minimum balance %3 in %1 days.",
                       dropMinimum - 1, acc.name(), MyMoneyUtils::formatMoney(minBalance, acc, currency));
          msg += QString("</font>");
      }

      if (!msg.isEmpty()) {
        m_adviceText->append(msg);
      }
    }

    // a drop below zero is always shown
    msg.clear();
    switch (dropZero) {
      case -1:
        break;
      case 0:
        if (acc.accountGroup() == MyMoneyAccount::Asset) {
          msg = QString("<font color=\"%1\">").arg(KMyMoneyGlobalSettings::listNegativeValueColor().name());
          msg += i18n("The balance of %1 is below %2 today.", acc.name(), MyMoneyUtils::formatMoney(MyMoneyMoney(), acc, currency));
          msg += QString("</font>");
          break;
        }
        if (acc.accountGroup() == MyMoneyAccount::Liability) {
          msg = i18n("The balance of %1 is above %2 today.", acc.name(), MyMoneyUtils::formatMoney(MyMoneyMoney(), acc, currency));
          break;
        }
        break;
      default:
        if (acc.accountGroup() == MyMoneyAccount::Asset) {
          msg = QString("<font color=\"%1\">").arg(KMyMoneyGlobalSettings::listNegativeValueColor().name());
          msg += i18np("The balance of %2 will drop below %3 in %1 day.",
                       "The balance of %2 will drop below %3 in %1 days.",
                       dropZero, acc.name(), MyMoneyUtils::formatMoney(MyMoneyMoney(), acc, currency));
          msg += QString("</font>");
          break;
        }
        if (acc.accountGroup() == MyMoneyAccount::Liability) {
          msg = i18np("The balance of %2 will raise above %3 in %1 day.",
                      "The balance of %2 will raise above %3 in %1 days.",
                      dropZero, acc.name(), MyMoneyUtils::formatMoney(MyMoneyMoney(), acc, currency));
          break;
        }
    }
    if (!msg.isEmpty()) {
      m_adviceText->append(msg);
    }

    //advice about trends
    msg.clear();
    MyMoneyMoney accCycleVariation = forecast.accountCycleVariation(acc);
    if (accCycleVariation < MyMoneyMoney()) {
      msg = QString("<font color=\"%1\">").arg(KMyMoneyGlobalSettings::listNegativeValueColor().name());
      msg += i18n("The account %1 is decreasing %2 per cycle.", acc.name(), MyMoneyUtils::formatMoney(accCycleVariation, acc, currency));
      msg += QString("</font>");
    }

    if (!msg.isEmpty()) {
      m_adviceText->append(msg);
    }
  }
  m_adviceText->show();
}
void KMyMoneyBriefSchedule::loadSchedule()
{
  try
  {
    if (m_index < m_scheduleList.count())
    {
      MyMoneySchedule sched = m_scheduleList[m_index];

      m_indexLabel->setText(i18n("%1 of %2")
                              .arg(QString::number(m_index+1))
                              .arg(QString::number(m_scheduleList.count())));
      m_name->setText(sched.name());
      m_type->setText(KMyMoneyUtils::scheduleTypeToString(sched.type()));
      m_account->setText(sched.account().name());
      QString text;
      MyMoneyMoney amount = sched.transaction().splitByAccount(sched.account().id()).value();
      amount = amount.abs();

      if (sched.willEnd())
      {
        int transactions = sched.paymentDates(m_date, sched.endDate()).count()-1;
        text = i18n("Payment on %1 for %2 with %3 transactions remaining occuring %4.")
                .arg(KGlobal::locale()->formatDate(m_date, true))
                .arg(amount.formatMoney(sched.account().fraction()))
                .arg(QString::number(transactions))
                .arg(i18n(sched.occurenceToString()));
      } else {
        text = i18n("Payment on %1 for %2 occuring %4.")
                .arg(KGlobal::locale()->formatDate(m_date, true))
                .arg(amount.formatMoney(sched.account().fraction()))
                .arg(i18n(sched.occurenceToString()));
      }

      if (m_date < QDate::currentDate())
      {
        if (sched.isOverdue())
        {
          QDate startD = (sched.lastPayment().isValid()) ?
            sched.lastPayment() :
            sched.startDate();

          if (m_date.isValid())
            startD = m_date;

          int days = startD.daysTo(QDate::currentDate());
          int transactions = sched.paymentDates(startD, QDate::currentDate()).count();

          text += "<br><font color=red>";
          text += i18n("%1 days overdue (%2 occurences).")
                      .arg(QString::number(days))
                      .arg(QString::number(transactions));
          text += "</color>";
        }
      }

      m_details->setText(text);

      m_prevButton->setEnabled(true);
      m_nextButton->setEnabled(true);
      m_skipButton->setEnabled(sched.occurencePeriod() != MyMoneySchedule::OCCUR_ONCE);

      if (m_index == 0)
        m_prevButton->setEnabled(false);
      if (m_index == (m_scheduleList.count()-1))
        m_nextButton->setEnabled(false);
    }
  }
  catch (MyMoneyException *e)
  {
    delete e;
  }
}
void KMyMoneyAccountTreeForecastItem::showAmount(int column, const MyMoneyMoney amount, const MyMoneySecurity security)
{
  setText(column, amount.formatMoney(m_account, security), amount.isNegative() );
}
Example #14
0
PivotCell::PivotCell(const MyMoneyMoney& value) :
    MyMoneyMoney(value),
    m_stockSplit(MyMoneyMoney::ONE)
{
  m_cellUsed |= !value.isZero();
}
Example #15
0
void kMyMoneyEdit::setValue(const MyMoneyMoney& value)
{
  // load the value into the widget but don't use thousandsSeparators
  QString txt = value.formatMoney("", m_prec, false);
  loadText(txt);
}
Example #16
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()));
  }
}
Example #17
0
const QString CsvUtil::checkCategory(const QString& name, const MyMoneyMoney& value, const MyMoneyMoney& value2)
{
  //  Borrowed from MyMoneyQifReader::checkCategory()
  QString accountId;
  MyMoneyFile *file = MyMoneyFile::instance();
  MyMoneyAccount account;
  bool found = true;

  if (!name.isEmpty()) {
    // The category might be constructed with an arbitraty depth (number of
    // colon delimited fields). We try to find a parent account within this
    // hierarchy by searching the following sequence:
    //
    //    aaaa:bbbb:cccc:ddddd
    //
    // 1. search aaaa:bbbb:cccc:dddd, create nothing
    // 2. search aaaa:bbbb:cccc     , create dddd
    // 3. search aaaa:bbbb          , create cccc:dddd
    // 4. search aaaa               , create bbbb:cccc:dddd
    // 5. don't search              , create aaaa:bbbb:cccc:dddd

    account.setName(name);
    QString accName;      // part to be created (right side in above list)
    QString parent(name);    // a possible parent part (left side in above list)
    do {
      accountId = file->categoryToAccount(parent);
      if (accountId.isEmpty()) {
        found = false;
        // prepare next step
        if (!accName.isEmpty())
          accName.prepend(':');
        accName.prepend(parent.section(':', -1));
        account.setName(accName);
        parent = parent.section(':', 0, -2);
      } else if (!accName.isEmpty()) {
        account.setParentAccountId(accountId);
      }
    } while (!parent.isEmpty() && accountId.isEmpty());

    // if we did not find the category, we create it
    if (!found) {
      MyMoneyAccount parent;
      if (account.parentAccountId().isEmpty()) {
        if (!value.isNegative() && value2.isNegative())
          parent = file->income();
        else
          parent = file->expense();
      } else {
        parent = file->account(account.parentAccountId());
      }
      account.setAccountType((!value.isNegative() && value2.isNegative()) ? MyMoneyAccount::Income : MyMoneyAccount::Expense);
      MyMoneyAccount brokerage;
      // clear out the parent id, because createAccount() does not like that
      account.setParentAccountId(QString());
      createAccount(account, parent, brokerage, MyMoneyMoney());
      accountId = account.id();
    }
  }

  return accountId;
}
Example #18
0
void KTagsView::showTransactions()
{
  MyMoneyMoney balance;
  MyMoneyFile *file = MyMoneyFile::instance();
  MyMoneySecurity base = file->baseCurrency();

  // setup sort order
  m_register->setSortOrder(KMyMoneyGlobalSettings::sortSearchView());

  // clear the register
  m_register->clear();

  if (m_tag.id().isEmpty() || !m_tabWidget->isEnabled()) {
    m_balanceLabel->setText(i18n("Balance: %1", balance.formatMoney(file->baseCurrency().smallestAccountFraction())));
    return;
  }

  // setup the list and the pointer vector
  MyMoneyTransactionFilter filter;
  filter.addTag(m_tag.id());
  filter.setDateFilter(KMyMoneyGlobalSettings::startDate().date(), QDate());

  // retrieve the list from the engine
  file->transactionList(m_transactionList, filter);

  // create the elements for the register
  QList<QPair<MyMoneyTransaction, MyMoneySplit> >::const_iterator it;
  QMap<QString, int> uniqueMap;
  MyMoneyMoney deposit, payment;

  int splitCount = 0;
  bool balanceAccurate = true;
  for (it = m_transactionList.constBegin(); it != m_transactionList.constEnd(); ++it) {
    const MyMoneySplit& split = (*it).second;
    MyMoneyAccount acc = file->account(split.accountId());
    ++splitCount;
    uniqueMap[(*it).first.id()]++;

    KMyMoneyRegister::Register::transactionFactory(m_register, (*it).first, (*it).second, uniqueMap[(*it).first.id()]);

    // take care of foreign currencies
    MyMoneyMoney val = split.shares().abs();
    if (acc.currencyId() != base.id()) {
      const MyMoneyPrice &price = file->price(acc.currencyId(), base.id());
      // in case the price is valid, we use it. Otherwise, we keep
      // a flag that tells us that the balance is somewhat inaccurate
      if (price.isValid()) {
        val *= price.rate(base.id());
      } else {
        balanceAccurate = false;
      }
    }

    if (split.shares().isNegative()) {
      payment += val;
    } else {
      deposit += val;
    }
  }
  balance = deposit - payment;

  // add the group markers
  m_register->addGroupMarkers();

  // sort the transactions according to the sort setting
  m_register->sortItems();

  // remove trailing and adjacent markers
  m_register->removeUnwantedGroupMarkers();

  m_register->updateRegister(true);

  // we might end up here with updates disabled on the register so
  // make sure that we enable updates here
  m_register->setUpdatesEnabled(true);
  m_balanceLabel->setText(i18n("Balance: %1%2",
                               balanceAccurate ? "" : "~",
                               balance.formatMoney(file->baseCurrency().smallestAccountFraction())));
}