diff --git a/kmymoney/reports/listtable.h b/kmymoney/reports/listtable.h --- a/kmymoney/reports/listtable.h +++ b/kmymoney/reports/listtable.h @@ -61,31 +61,58 @@ void init(); public: + enum cellTypeE /*{*/ /*Money*/ + {ctValue, ctNetInvValue, ctMarketValue, + ctPrice, ctLastPrice, ctBuyPrice, + ctBuys, ctSells, ctBuysST, ctSellsST, ctBuysLT, ctSellsLT, + ctCapitalGain, ctCapitalGainST,ctCapitalGainLT, + ctCashIncome, ctReinvestIncome, + ctFees, ctInterest, + ctStartingBalance, ctEndingBalance, ctBalance, ctCurrentBalance, + ctBalanceWarning, ctMaxBalanceLimit, ctOpeningBalance, + ctCreditWarning, ctMaxCreditLimit, + ctLoanAmount, ctPeriodicPayment, ctFinalPayment, ctPayment, + /*Shares*/ + ctShares, + /*Percent*/ + ctReturn, ctReturnInvestment, ctInterestRate, ctPercentageGain, + /*Date*/ + ctPostDate, ctEntryDate, ctNextDueDate, ctOpeningDate, ctNextInterestChange, + ctMonth, ctWeek, ctReconcileDate, + /*Misc*/ + ctCurrency, ctCurrencyName, ctCommodity, ctID, + ctRank, ctSplit, ctMemo, + ctAccount, ctAccountID, ctTopAccount, ctInvestAccount, ctInstitution, + ctCategory, ctTopCategory, ctCategoryType, + ctNumber, ctReconcileFlag, + ctAction, ctTag, ctPayee, ctEquityType, ctType, ctName, + ctDepth, ctRowsCount, ctTax, ctFavorite, ctDescription, ctOccurence, ctPaymentType + }; /** * Contains a single row in the table. * * Each column is a key/value pair, both strings. This class is just * a QMap with the added ability to specify which columns you'd like to * use as a sort key when you qHeapSort a list of these TableRows */ - class TableRow: public QMap + class TableRow: public QMap { public: bool operator< (const TableRow&) const; bool operator<= (const TableRow&) const; bool operator> (const TableRow&) const; bool operator== (const TableRow&) const; - static void setSortCriteria(const QString& _criteria) { - m_sortCriteria = _criteria.split(","); + static void setSortCriteria(const QVector& _criteria) { + m_sortCriteria = _criteria; } private: - static QStringList m_sortCriteria; + static QVector m_sortCriteria; }; const QList& rows() { return m_rows; - }; + } protected: void render(QString&, QString&) const; @@ -100,25 +127,25 @@ QList m_rows; - QString m_group; + QList m_group; /** * Comma-separated list of columns to place BEFORE the subtotal column */ - QString m_columns; + QList m_columns; /** * Name of the subtotal column */ - QString m_subtotal; + QList m_subtotal; /** * Comma-separated list of columns to place AFTER the subtotal column */ - QString m_postcolumns; - QString m_summarize; - QString m_propagate; + QList m_postcolumns; MyMoneyReport m_config; - - +private: + enum cellGroupE { cgMoney, cgShares, cgPercent, cgDate, cgPrice, cgMisc }; + static cellGroupE cellGroup(const cellTypeE cellType); + static QString tableHeader(const cellTypeE cellType); }; } diff --git a/kmymoney/reports/listtable.cpp b/kmymoney/reports/listtable.cpp --- a/kmymoney/reports/listtable.cpp +++ b/kmymoney/reports/listtable.cpp @@ -45,7 +45,7 @@ namespace reports { -QStringList ListTable::TableRow::m_sortCriteria; +QVector ListTable::TableRow::m_sortCriteria; // **************************************************************************** // @@ -56,16 +56,13 @@ bool ListTable::TableRow::operator< (const TableRow& _compare) const { bool result = false; - - QStringList::const_iterator it_criterion = m_sortCriteria.constBegin(); - while (it_criterion != m_sortCriteria.constEnd()) { - if (this->operator[](*it_criterion) < _compare[ *it_criterion ]) { + foreach (const auto criterion, m_sortCriteria) { + if (this->operator[](criterion) < _compare[criterion]) { result = true; break; - } else if (this->operator[](*it_criterion) > _compare[ *it_criterion ]) + } else if (this->operator[](criterion) > _compare[criterion]) { break; - - ++it_criterion; + } } return result; } @@ -106,143 +103,62 @@ { MyMoneyFile* file = MyMoneyFile::instance(); - result = ""; - csv = ""; - result += QString("

%1

\n").arg(m_config.name()); - csv += "\"Report: " + m_config.name() + "\"\n"; + result.clear(); + csv.clear(); + result.append(QString::fromLatin1("

%1

\n").arg(m_config.name())); + csv.append(QString::fromLatin1("\"Report: %1\"\n").arg(m_config.name())); + //actual dates of the report - result += QString("
"); + result.append(QLatin1String("
")); if (!m_config.fromDate().isNull()) { result += i18nc("Report date range", "%1 through %2", QLocale().toString(m_config.fromDate(), QLocale::ShortFormat), QLocale().toString(m_config.toDate(), QLocale::ShortFormat)); - result += QString("
\n"); - result += QString("
 
\n"); + result.append(QLatin1String("
\n")); + result.append(QLatin1String("
 
\n")); csv += i18nc("Report date range", "%1 through %2", QLocale().toString(m_config.fromDate(), QLocale::ShortFormat), QLocale().toString(m_config.toDate(), QLocale::ShortFormat)); - csv += QString("\n"); + csv.append(QLatin1Char('\n')); } - - result += QString("
"); + result.append(QLatin1String("
")); if (m_config.isConvertCurrency()) { result += i18n("All currencies converted to %1" , file->baseCurrency().name()); - csv += i18n("All currencies converted to %1\n" , file->baseCurrency().name()); + csv += i18n("All currencies converted to %1" , file->baseCurrency().name()); } else { result += i18n("All values shown in %1 unless otherwise noted" , file->baseCurrency().name()); - csv += i18n("All values shown in %1 unless otherwise noted\n" , file->baseCurrency().name()); + csv += i18n("All values shown in %1 unless otherwise noted" , file->baseCurrency().name()); } - result += QString("
\n"); - result += QString("
 
\n"); + result.append(QLatin1String("
\n")); + result.append(QLatin1String("
 
\n")); + csv.append(QLatin1Char('\n')); // retrieve the configuration parameters from the report definition. // the things that we care about for query reports are: // how to group the rows, what columns to display, and what field // to subtotal on - QStringList groups = m_group.split(','); - QStringList columns = m_columns.split(','); - if (!m_subtotal.isEmpty() && m_subtotal.split(',').count() == 1) // constructPerformanceRow has subtotal columns already in columns - columns += m_subtotal; - QStringList postcolumns = m_postcolumns.split(','); + QList columns = m_columns; + if (!m_subtotal.isEmpty() && m_subtotal.count() == 1) // constructPerformanceRow has subtotal columns already in columns + columns.append(m_subtotal); + QList postcolumns = m_postcolumns; if (!m_postcolumns.isEmpty()) // prevent creation of empty column - columns += postcolumns; + columns.append(postcolumns); + + result.append(QLatin1String("\n")); // // Table header // - QMap i18nHeaders; - i18nHeaders["postdate"] = i18n("Date"); - i18nHeaders["value"] = i18n("Amount"); - i18nHeaders["number"] = i18n("Num"); - i18nHeaders["payee"] = i18n("Payee"); - i18nHeaders["tag"] = i18n("Tags"); - i18nHeaders["category"] = i18n("Category"); - i18nHeaders["account"] = i18n("Account"); - i18nHeaders["memo"] = i18n("Memo"); - i18nHeaders["topcategory"] = i18n("Top Category"); - i18nHeaders["categorytype"] = i18n("Category Type"); - i18nHeaders["month"] = i18n("Month"); - i18nHeaders["week"] = i18n("Week"); - i18nHeaders["reconcileflag"] = i18n("Reconciled"); - i18nHeaders["action"] = i18n("Action"); - i18nHeaders["shares"] = i18n("Shares"); - i18nHeaders["price"] = i18n("Price"); - i18nHeaders["lastprice"] = i18n("Last Price"); - i18nHeaders["buyprice"] = i18n("Buy Price"); - i18nHeaders["netinvvalue"] = i18n("Net Value"); - i18nHeaders["buys"] = i18n("Buy Value"); - i18nHeaders["sells"] = i18n("Sell Value"); - i18nHeaders["buysST"] = i18n("Short-term Buy Value"); - i18nHeaders["sellsST"] = i18n("Short-term Sell Value"); - i18nHeaders["buysLT"] = i18n("Long-term Buy Value"); - i18nHeaders["sellsLT"] = i18n("Long-term Sell Value"); - i18nHeaders["reinvestincome"] = i18n("Dividends Reinvested"); - i18nHeaders["cashincome"] = i18n("Dividends Paid Out"); - i18nHeaders["startingbal"] = i18n("Starting Balance"); - i18nHeaders["endingbal"] = i18n("Ending Balance"); - i18nHeaders["marketvalue"] = i18n("Market Value"); - i18nHeaders["return"] = i18n("Annualized Return"); - i18nHeaders["returninvestment"] = i18n("Return On Investment"); - i18nHeaders["fees"] = i18n("Fees"); - i18nHeaders["interest"] = i18n("Interest"); - i18nHeaders["payment"] = i18n("Payment"); - i18nHeaders["balance"] = i18n("Balance"); - i18nHeaders["type"] = i18n("Type"); - i18nHeaders["name"] = i18nc("Account name", "Name"); - i18nHeaders["nextduedate"] = i18n("Next Due Date"); - i18nHeaders["occurence"] = i18n("Occurrence"); // krazy:exclude=spelling - i18nHeaders["paymenttype"] = i18n("Payment Method"); - i18nHeaders["institution"] = i18n("Institution"); - i18nHeaders["description"] = i18n("Description"); - i18nHeaders["openingdate"] = i18n("Opening Date"); - i18nHeaders["currencyname"] = i18n("Currency"); - i18nHeaders["balancewarning"] = i18n("Balance Early Warning"); - i18nHeaders["maxbalancelimit"] = i18n("Balance Max Limit"); - i18nHeaders["creditwarning"] = i18n("Credit Early Warning"); - i18nHeaders["maxcreditlimit"] = i18n("Credit Max Limit"); - i18nHeaders["tax"] = i18n("Tax"); - i18nHeaders["favorite"] = i18n("Preferred"); - i18nHeaders["loanamount"] = i18n("Loan Amount"); - i18nHeaders["interestrate"] = i18n("Interest Rate"); - i18nHeaders["nextinterestchange"] = i18n("Next Interest Change"); - i18nHeaders["periodicpayment"] = i18n("Periodic Payment"); - i18nHeaders["finalpayment"] = i18n("Final Payment"); - i18nHeaders["currentbalance"] = i18n("Current Balance"); - i18nHeaders["capitalgain"] = i18n("Capital Gain"); - i18nHeaders["percentagegain"] = i18n("Percentage Gain"); - i18nHeaders["capitalgainST"] = i18n("Short-term Gain"); - i18nHeaders["capitalgainLT"] = i18n("Long-term Gain"); - - // the list of columns which represent money, so we can display them correctly - QStringList moneyColumns = QString("value,price,lastprice,buyprice,netinvvalue,buys,buysST,buysLT,sells,sellsST,sellsLT,cashincome,reinvestincome,startingbal,fees,interest,payment,balance,balancewarning,maxbalancelimit,creditwarning,maxcreditlimit,loanamount,periodicpayment,finalpayment,currentbalance,startingbal,endingbal,capitalgain,capitalgainST,capitalgainLT,marketvalue").split(','); - - // the list of columns which represent shares, which is like money except the - // transaction currency will not be displayed - QStringList sharesColumns = QString("shares").split(','); - - // the list of columns which represent a percentage, so we can display them correctly - QStringList percentColumns = QString("return,returninvestment,interestrate,percentagegain").split(','); - - // the list of columns which represent dates, so we can display them correctly - QStringList dateColumns = QString("postdate,entrydate,nextduedate,openingdate,nextinterestchange").split(','); - - result += "
\n"; - - QStringList::const_iterator it_column = columns.constBegin(); - while (it_column != columns.constEnd()) { - QString i18nName = i18nHeaders[*it_column]; - if (i18nName.isEmpty()) - i18nName = *it_column; - result += ""; - csv += i18nName + ','; - ++it_column; + foreach (const auto cellType, columns) { + result.append(QString::fromLatin1("").arg(tableHeader(cellType))); + csv.append(tableHeader(cellType) + QLatin1Char(',')); } + csv.chop(1); // remove last ',' character - result += "\n"; - csv = csv.left(csv.length() - 1); - csv += '\n'; + result.append(QLatin1String("\n")); + csv.append(QLatin1Char('\n')); // initialize group names to empty, so any group will have to display its header QStringList prevGrpNames; - for (int i = 0; i < groups.count(); ++i) { + for (int i = 0; i < m_group.count(); ++i) { prevGrpNames.append(QString()); } @@ -256,35 +172,35 @@ // ***DV*** MyMoneyMoney startingBalance; MyMoneyMoney balanceChange = MyMoneyMoney(); - for (QList::const_iterator it_row = m_rows.begin(); - it_row != m_rows.end(); + for (QList::ConstIterator it_row = m_rows.constBegin(); + it_row != m_rows.constEnd(); ++it_row) { - - /** rank can be: + /* rank can be: * 0 - opening balance * 1 - major split of transaction * 2 - minor split of transaction * 3 - closing balance * 4 - first totals row * 5 - middle totals row */ - const QString rowRank = (*it_row)["rank"]; + const int rowRank = (*it_row).value(ctRank).toInt(); // detect whether any of groups changed and display new group header in that case - for (int i = 0; i < groups.count(); ++i) { - QString curGrpName = (*it_row).value(groups.at(i)); + for (int i = 0; i < m_group.count(); ++i) { + QString curGrpName = (*it_row).value(m_group.at(i)); if (curGrpName.isEmpty()) // it could be grand total continue; if (prevGrpNames.at(i) != curGrpName) { // group header of lowest group doesn't bring any useful information // if hide transaction is enabled, so don't display it - int lowestGroup = groups.count() - 1; + int lowestGroup = m_group.count() - 1; if (!m_config.isHideTransactions() || i != lowestGroup) { row_odd = true; - result += "" - "\n"; - csv += "\"" + curGrpName + "\"\n"; + result.append(QString::fromLatin1("" + "\n").arg(QString::number(i), + QString::number(columns.count()), + curGrpName)); + csv.append(QString::fromLatin1("\"%1\"\n")).arg(curGrpName); } if (i == lowestGroup) // lowest group has been switched... isLowestGroupTotal = true; // ...so expect lowest group total @@ -296,125 +212,129 @@ QString tlink; // link information to account and transaction - if (!m_config.isHideTransactions() || rowRank == "4" || rowRank == "5") { // if hide transaction is enabled display only total rows i.e. rank = 4 || rank = 5 - if (rowRank == "0" || rowRank == "3") { + if (!m_config.isHideTransactions() || rowRank == 4 || rowRank == 5) { // if hide transaction is enabled display only total rows i.e. rank = 4 || rank = 5 + if (rowRank == 0 || rowRank == 3) { // skip the opening and closing balance row, // if the balance column is not shown // rank = 0 for opening balance, rank = 3 for closing balance - if (!columns.contains("balance")) + if (!columns.contains(ctBalance)) continue; - result += QString("").arg((* it_row)["id"]); - // ***DV*** - } else if (rowRank == "1") { + result.append(QString::fromLatin1("").arg((*it_row).value(ctID))); + // ***DV*** + } else if (rowRank == 1) { row_odd = ! row_odd; - tlink = QString("id=%1&tid=%2") - .arg((* it_row)["accountid"], (* it_row)["id"]); - result += QString("").arg(row_odd ? "row-odd " : "row-even"); - } else if (rowRank == "2") - result += QString("").arg(row_odd ? "item1" : "item0"); - else if (rowRank == "4" || rowRank == "5") { + tlink = QString::fromLatin1("id=%1&tid=%2").arg((*it_row).value(ctAccountID), (*it_row).value(ctID)); + result.append(QString::fromLatin1("").arg(row_odd ? QLatin1String("odd") : QLatin1String("even"))); + } else if (rowRank == 2) { + result.append(QString::fromLatin1("").arg(row_odd ? QLatin1Char('1') : QLatin1Char('0'))); + } else if (rowRank == 4 || rowRank == 5) { QList::const_iterator nextRow = std::next(it_row); - if ((m_config.rowType() == MyMoneyReport::eTag)) //If we order by Tags don't show the Grand total as we can have multiple tags per transaction + if ((m_config.rowType() == MyMoneyReport::eTag)) { //If we order by Tags don't show the Grand total as we can have multiple tags per transaction continue; - else if (rowRank == "4") { + } else if (rowRank == 4) { if (nextRow != m_rows.end()) { if (isLowestGroupTotal && m_config.isHideTransactions()) { - result += QString(""); + result.append(QLatin1String("")); isLowestGroupTotal = false; - } else if ((*nextRow)["rank"] == "5") - result += QString(""); - else - result += QString(""); - } else - result += QString(""); - } else if (rowRank == "5") { + } else if ((*nextRow).value(ctRank) == QLatin1String("5")) { + result.append(QLatin1String("")); + } else { + result.append(QLatin1String("")); + } + } else { + result.append(QLatin1String("")); + } + } else if (rowRank == 5) { if (nextRow != m_rows.end()) { - if ((*nextRow)["rank"] == "5") - result += QString(""); + if ((*nextRow).value(ctRank) == QLatin1String("5")) + result.append(QLatin1String("")); else - result += QString(""); + result.append(QLatin1String("")); } - } else - result += QString(""); - } else - result += QString("").arg(row_odd ? "row-odd " : "row-even"); - } else + } else { + result.append(QLatin1String("")); + } + } else { + result.append(QString::fromLatin1("").arg(row_odd ? QLatin1String("odd") : QLatin1String("even"))); + } + } else { continue; + } // // Columns // - QStringList::const_iterator it_column = columns.constBegin(); + QList::ConstIterator it_column = columns.constBegin(); while (it_column != columns.constEnd()) { - QString data = (*it_row)[*it_column]; + QString data = (*it_row).value(*it_column); // ***DV*** - if (rowRank == "2") { - if (* it_column == "value") - data = (* it_row)["split"]; - else if (*it_column == "postdate" - || *it_column == "number" - || *it_column == "payee" - || *it_column == "tag" - || *it_column == "action" - || *it_column == "shares" - || *it_column == "price" - || *it_column == "nextduedate" - || *it_column == "balance" - || *it_column == "account" - || *it_column == "name") - data = ""; + if (rowRank == 2) { + if (*it_column == ctValue) + data = (*it_row).value(ctSplit); + else if (*it_column == ctPostDate + || *it_column == ctNumber + || *it_column == ctPayee + || *it_column == ctTag + || *it_column == ctAction + || *it_column == ctShares + || *it_column == ctPrice + || *it_column == ctNextDueDate + || *it_column == ctBalance + || *it_column == ctAccount + || *it_column == ctName) + data.clear(); } // ***DV*** - else if (rowRank == "0" || rowRank == "3") { - if (*it_column == "balance") { - data = (* it_row)["balance"]; - if ((* it_row)["id"] == "A") { // opening balance? + else if (rowRank == 0 || rowRank == 3) { + if (*it_column == ctBalance) { + data = (*it_row).value(ctBalance); + if ((*it_row).value(ctID) == QLatin1String("A")) { // opening balance? startingBalance = MyMoneyMoney(data); balanceChange = MyMoneyMoney(); } } if (need_label) { - if ((*it_column == "payee") || - (*it_column == "category") || - (*it_column == "memo")) { - if (!(*it_row)["shares"].isEmpty()) { - data = ((* it_row)["id"] == "A") - ? i18n("Initial Market Value") - : i18n("Ending Market Value"); + if ((*it_column == ctPayee) || + (*it_column == ctCategory) || + (*it_column == ctMemo)) { + if (!(*it_row).value(ctShares).isEmpty()) { + data = ((*it_row).value(ctID) == QLatin1String("A")) + ? i18n("Initial Market Value") + : i18n("Ending Market Value"); } else { - data = ((* it_row)["id"] == "A") - ? i18n("Opening Balance") - : i18n("Closing Balance"); + data = ((*it_row).value(ctID) == QLatin1String("A")) + ? i18n("Opening Balance") + : i18n("Closing Balance"); } need_label = false; } } } // The 'balance' column is calculated at render-time // but not printed on split lines - else if (*it_column == "balance" && rowRank == "1") { + else if (*it_column == ctBalance && rowRank == 1) { // Take the balance off the deepest group iterator - balanceChange += MyMoneyMoney((*it_row).value("value", "0")); + balanceChange += MyMoneyMoney((*it_row).value(ctValue, QLatin1String("0"))); data = (balanceChange + startingBalance).toString(); - } else if ((rowRank == "4" || rowRank == "5")) { + } else if ((rowRank == 4 || rowRank == 5)) { // display total title but only if first column doesn't contain any data if (it_column == columns.constBegin() && data.isEmpty()) { - result += "")); + result.append(QLatin1String("")); ++it_column; continue; } else if (!m_subtotal.contains(*it_column)) { // don't display e.g. account in totals row - result.append(QLatin1Literal("")); + result.append(QLatin1String("")); ++it_column; continue; } @@ -428,83 +348,96 @@ // vector of a properties class. QString tlinkBegin, tlinkEnd; if (!tlink.isEmpty()) { - tlinkBegin = QString("").arg(tlink); - tlinkEnd = QLatin1String(""); + tlinkBegin = QString::fromLatin1("").arg(tlink); + tlinkEnd = QLatin1String(""); } - QString currencyID = (*it_row)["currency"]; + QString currencyID = (*it_row).value(ctCurrency); if (currencyID.isEmpty()) currencyID = file->baseCurrency().id(); int fraction = file->currency(currencyID).smallestAccountFraction(); if (m_config.isConvertCurrency()) // don't show currency id, if there is only single currency currencyID.clear(); - if (sharesColumns.contains(*it_column)) { - if (data.isEmpty()) { - result += QString(""); - csv += "\"\","; - } else { - int sharesPrecision = MyMoneyMoney::denomToPrec(file->security(file->account((*it_row)["accountid"]).currencyId()).smallestAccountFraction()); - result += QString("").arg(MyMoneyMoney(data).formatMoney("", sharesPrecision), tlinkBegin, tlinkEnd); - csv += "\"" + MyMoneyMoney(data).formatMoney("", sharesPrecision, false) + "\","; - } - } else if (moneyColumns.contains(*it_column)) { - if (data.isEmpty()) { - result += QString("") - .arg((*it_column == "value") ? " class=\"value\"" : ""); - csv += "\"\","; - } else if (MyMoneyMoney(data) == MyMoneyMoney::autoCalc) { - result += QString("%3%2%4") - .arg((*it_column == "value") ? " class=\"value\"" : "") - .arg(i18n("Calculated"), tlinkBegin, tlinkEnd); - csv += "\"" + i18n("Calculated") + "\","; - } else if ((*it_column).endsWith(QLatin1String("price"))) { - int pricePrecision = file->security(file->account((*it_row)["accountid"]).currencyId()).pricePrecision(); - result += QString("") - .arg(MyMoneyMoney(data).formatMoney(QString(), pricePrecision), currencyID, tlinkBegin, tlinkEnd); - csv += "\"" + currencyID + " " + MyMoneyMoney(data).formatMoney(QString(), pricePrecision, false) + "\","; - } else { - result += QString("%4%2 %3%5") - .arg((*it_column == "value") ? " class=\"value\"" : "") - .arg(currencyID) - .arg(MyMoneyMoney(data).formatMoney(fraction)) - .arg(tlinkBegin, tlinkEnd); - csv += "\"" + currencyID + " " + MyMoneyMoney(data).formatMoney(fraction, false) + "\","; - } - } else if (percentColumns.contains(*it_column)) { - if (data.isEmpty()) { - result += QString(""); - csv += "\"\","; - } else { - data = (MyMoneyMoney(data) * MyMoneyMoney(100, 1)).formatMoney(fraction); - result += QString("").arg(data, tlinkBegin, tlinkEnd); - csv += data + "%,"; - } - } else if (dateColumns.contains(*it_column)) { - // do this before we possibly change data - csv += "\"" + data + "\","; - - // if we have a locale() then use its date formatter - if (!data.isEmpty()) { - QDate qd = QDate::fromString(data, Qt::ISODate); - data = QLocale().toString(qd, QLocale::ShortFormat); + switch (cellGroup(*it_column)) { + case cgMoney: + if (data.isEmpty()) { + result.append(QString::fromLatin1("") + .arg((*it_column == ctValue) ? QLatin1String(" class=\"value\"") : QString())); + csv.append(QLatin1String("\"\",")); + } else if (MyMoneyMoney(data) == MyMoneyMoney::autoCalc) { + result.append(QString::fromLatin1("%3%2%4") + .arg((*it_column == ctValue) ? QLatin1String(" class=\"value\"") : QString(), + i18n("Calculated"), tlinkBegin, tlinkEnd)); + csv.append(QString::fromLatin1("\"%1\",").arg(i18n("Calculated"))); + } else { + result.append(QString::fromLatin1("%4%2 %3%5") + .arg((*it_column == ctValue) ? QLatin1String(" class=\"value\"") : QString(), + currencyID, + MyMoneyMoney(data).formatMoney(fraction), + tlinkBegin, tlinkEnd)); + csv.append(QString::fromLatin1("\"%1 %2\",").arg(currencyID, + MyMoneyMoney(data).formatMoney(fraction, false))); + } + break; + case cgPercent: + if (data.isEmpty()) { + result.append(QLatin1String("")); + csv.append(QLatin1String("\"\",")); + } else { + data = (MyMoneyMoney(data) * MyMoneyMoney(100, 1)).formatMoney(fraction); + result.append(QString::fromLatin1("").arg(data, tlinkBegin, tlinkEnd)); + csv.append(QString::fromLatin1("%1%,").arg(data)); + } + break; + case cgPrice: + { + int pricePrecision = file->security(file->account((*it_row).value(ctAccountID)).currencyId()).pricePrecision(); + result.append(QString::fromLatin1("") + .arg(MyMoneyMoney(data).formatMoney(QString(), pricePrecision), + currencyID, tlinkBegin, tlinkEnd)); + csv.append(QString::fromLatin1("\"%1 %2\",").arg(currencyID, + MyMoneyMoney(data).formatMoney(QString(), pricePrecision, false))); } - result += QString("").arg(data, tlinkBegin, tlinkEnd); - } else { - result += QString("").arg(data, tlinkBegin, tlinkEnd); - csv += "\"" + data + "\","; + break; + case cgShares: + if (data.isEmpty()) { + result.append(QLatin1String("")); + csv.append(QLatin1String("\"\",")); + } else { + int sharesPrecision = MyMoneyMoney::denomToPrec(file->security(file->account((*it_row).value(ctAccountID)).currencyId()).smallestAccountFraction()); + result += QString::fromLatin1("").arg(MyMoneyMoney(data).formatMoney(QString(), sharesPrecision), + tlinkBegin, tlinkEnd); + csv.append(QString::fromLatin1("\"%1\",").arg(MyMoneyMoney(data).formatMoney(QString(), sharesPrecision, false))); + } + break; + case cgDate: + // do this before we possibly change data + csv.append(QString::fromLatin1("\"%1\",").arg(data)); + + // if we have a locale() then use its date formatter + if (!data.isEmpty()) { + QDate qd = QDate::fromString(data, Qt::ISODate); + data = QLocale().toString(qd, QLocale::ShortFormat); + } + result.append(QString::fromLatin1("").arg(data, tlinkBegin, tlinkEnd, QString::number(prevGrpNames.count() - 1))); + break; + default: + result.append(QString::fromLatin1("").arg(data, tlinkBegin, tlinkEnd, QString::number(prevGrpNames.count() - 1))); + csv.append(QString::fromLatin1("\"%1\",").arg(data)); + break; } ++it_column; tlink.clear(); } - result += "\n"; - csv = csv.left(csv.length() - 1); // remove final comma - csv += '\n'; + result.append(QLatin1String("\n")); + csv.chop(1); // remove final comma + csv.append(QLatin1Char('\n')); } - result += "
" + i18nName + "%1
" + - curGrpName + "
%3
"; - if (rowRank == "4") { - if (!(*it_row)["depth"].isEmpty()) - result += i18nc("Total balance", "Total") + ' ' + prevGrpNames.at((*it_row)["depth"].toInt()); + result.append(QString::fromLatin1("").arg((*it_row).value(ctDepth))); + if (rowRank == 4) { + if (!(*it_row).value(ctDepth).isEmpty()) + result += i18nc("Total balance", "Total") + QLatin1Char(' ') + prevGrpNames.at((*it_row).value(ctDepth).toInt()); else result += i18n("Grand Total"); } - result.append(QLatin1Literal("%2%1%3%3%2 %1%4%2%1%%3%2%1%%3%3%2 %1%4%2%1%3%2%1%3%2%1%3%2%1%3%2%1%3
\n"; + result.append(QLatin1String("\n")); } QString ListTable::renderBody() const @@ -619,4 +552,194 @@ } } +ListTable::cellGroupE ListTable::cellGroup(const cellTypeE cellType) +{ + switch (cellType) { + // the list of columns which represent money, so we can display them correctly + case ctValue: + case ctNetInvValue: + case ctMarketValue: + case ctBuys: + case ctSells: + case ctBuysST: + case ctSellsST: + case ctBuysLT: + case ctSellsLT: + case ctCapitalGain: + case ctCapitalGainST: + case ctCapitalGainLT: + case ctCashIncome: + case ctReinvestIncome: + case ctFees: + case ctInterest: + case ctStartingBalance: + case ctEndingBalance: + case ctBalance: + case ctCurrentBalance: + case ctBalanceWarning: + case ctMaxBalanceLimit: + case ctCreditWarning: + case ctMaxCreditLimit: + case ctLoanAmount: + case ctPeriodicPayment: + case ctFinalPayment: + case ctPayment: + return cgMoney; + case ctPrice: + case ctLastPrice: + case ctBuyPrice: + return cgPrice; + /* the list of columns which represent shares, which is like money except the + transaction currency will not be displayed*/ + case ctShares: + return cgShares; + // the list of columns which represent a percentage, so we can display them correctly + case ctReturn: + case ctReturnInvestment: + case ctInterestRate: + case ctPercentageGain: + return cgPercent; + // the list of columns which represent dates, so we can display them correctly + case ctPostDate: + case ctEntryDate: + case ctNextDueDate: + case ctOpeningDate: + case ctNextInterestChange: + return cgDate; + default: + break; + } + return cgMisc; +} + +QString ListTable::tableHeader(const cellTypeE cellType) +{ + switch (cellType) { + case ctPostDate: + return i18n("Date"); + case ctValue: + return i18n("Amount"); + case ctNumber: + return i18n("Num"); + case ctPayee: + return i18n("Payee"); + case ctTag: + return i18n("Tags"); + case ctCategory: + return i18n("Category"); + case ctAccount: + return i18n("Account"); + case ctMemo: + return i18n("Memo"); + case ctTopCategory: + return i18n("Top Category"); + case ctCategoryType: + return i18n("Category Type"); + case ctMonth: + return i18n("Month"); + case ctWeek: + return i18n("Week"); + case ctReconcileFlag: + return i18n("Reconciled"); + case ctAction: + return i18n("Action"); + case ctShares: + return i18n("Shares"); + case ctPrice: + return i18n("Price"); + case ctLastPrice: + return i18n("Last Price"); + case ctBuyPrice: + return i18n("Buy Price"); + case ctNetInvValue: + return i18n("Net Value"); + case ctBuys: + return i18n("Buy Value"); + case ctSells: + return i18n("Sell Value"); + case ctBuysST: + return i18n("Short-term Buy Value"); + case ctSellsST: + return i18n("Short-term Sell Value"); + case ctBuysLT: + return i18n("Long-term Buy Value"); + case ctSellsLT: + return i18n("Long-term Sell Value"); + case ctReinvestIncome: + return i18n("Dividends Reinvested"); + case ctCashIncome: + return i18n("Dividends Paid Out"); + case ctStartingBalance: + return i18n("Starting Balance"); + case ctEndingBalance: + return i18n("Ending Balance"); + case ctMarketValue: + return i18n("Market Value"); + case ctReturn: + return i18n("Annualized Return"); + case ctReturnInvestment: + return i18n("Return On Investment"); + case ctFees: + return i18n("Fees"); + case ctInterest: + return i18n("Interest"); + case ctPayment: + return i18n("Payment"); + case ctBalance: + return i18n("Balance"); + case ctType: + return i18n("Type"); + case ctName: + return i18nc("Account name", "Name"); + case ctNextDueDate: + return i18n("Next Due Date"); + case ctOccurence: + return i18n("Occurrence"); // krazy:exclude=spelling + case ctPaymentType: + return i18n("Payment Method"); + case ctInstitution: + return i18n("Institution"); + case ctDescription: + return i18n("Description"); + case ctOpeningDate: + return i18n("Opening Date"); + case ctCurrencyName: + return i18n("Currency"); + case ctBalanceWarning: + return i18n("Balance Early Warning"); + case ctMaxBalanceLimit: + return i18n("Balance Max Limit"); + case ctCreditWarning: + return i18n("Credit Early Warning"); + case ctMaxCreditLimit: + return i18n("Credit Max Limit"); + case ctTax: + return i18n("Tax"); + case ctFavorite: + return i18n("Preferred"); + case ctLoanAmount: + return i18n("Loan Amount"); + case ctInterestRate: + return i18n("Interest Rate"); + case ctNextInterestChange: + return i18n("Next Interest Change"); + case ctPeriodicPayment: + return i18n("Periodic Payment"); + case ctFinalPayment: + return i18n("Final Payment"); + case ctCurrentBalance: + return i18n("Current Balance"); + case ctCapitalGain: + return i18n("Capital Gain"); + case ctPercentageGain: + return i18n("Percentage Gain"); + case ctCapitalGainST: + return i18n("Short-term Gain"); + case ctCapitalGainLT: + return i18n("Long-term Gain"); + default: + break; + } + return QLatin1String("None"); +} } diff --git a/kmymoney/reports/objectinfotable.cpp b/kmymoney/reports/objectinfotable.cpp --- a/kmymoney/reports/objectinfotable.cpp +++ b/kmymoney/reports/objectinfotable.cpp @@ -68,58 +68,69 @@ void ObjectInfoTable::init() { + m_columns.clear(); + m_group.clear(); + m_subtotal.clear(); switch (m_config.rowType()) { case MyMoneyReport::eSchedule: constructScheduleTable(); - m_columns = "nextduedate,name"; + m_columns << ctNextDueDate << ctName; break; case MyMoneyReport::eAccountInfo: constructAccountTable(); - m_columns = "institution,type,name"; + m_columns << ctInstitution << ctType << ctName; break; case MyMoneyReport::eAccountLoanInfo: constructAccountLoanTable(); - m_columns = "institution,type,name"; + m_columns << ctInstitution << ctType << ctName; break; default: break; } // Sort the data to match the report definition - m_subtotal = "value"; + m_subtotal << ctValue; switch (m_config.rowType()) { case MyMoneyReport::eSchedule: - m_group = "type"; - m_subtotal = "value"; + m_group << ctType; + m_subtotal << ctValue; break; case MyMoneyReport::eAccountInfo: case MyMoneyReport::eAccountLoanInfo: - m_group = "topcategory,institution"; - m_subtotal = "currentbalance"; + m_group << ctTopCategory << ctInstitution; + m_subtotal << ctCurrentBalance; break; default: throw MYMONEYEXCEPTION("ObjectInfoTable::ObjectInfoTable(): unhandled row type"); } - QString sort = m_group + ',' + m_columns + ",id,rank"; + QVector sort = QVector::fromList(m_group) << QVector::fromList(m_columns) << ctID << ctRank; switch (m_config.rowType()) { case MyMoneyReport::eSchedule: if (m_config.detailLevel() == MyMoneyReport::eDetailAll) { - m_columns = "name,payee,paymenttype,occurence,nextduedate,category"; // krazy:exclude=spelling + m_columns << ctName << ctPayee << ctPaymentType << ctOccurence + << ctNextDueDate << ctCategory; // krazy:exclude=spelling } else { - m_columns = "name,payee,paymenttype,occurence,nextduedate"; // krazy:exclude=spelling + m_columns << ctName << ctPayee << ctPaymentType << ctOccurence + << ctNextDueDate; // krazy:exclude=spelling } break; case MyMoneyReport::eAccountInfo: - m_columns = "type,name,number,description,openingdate,currencyname,balancewarning,maxbalancelimit,creditwarning,maxcreditlimit,tax,favorite"; + m_columns << ctType << ctName << ctNumber << ctDescription + << ctOpeningDate << ctCurrencyName << ctBalanceWarning + << ctCreditWarning << ctMaxCreditLimit + << ctTax << ctFavorite; break; case MyMoneyReport::eAccountLoanInfo: - m_columns = "type,name,number,description,openingdate,currencyname,payee,loanamount,interestrate,nextinterestchange,periodicpayment,finalpayment,favorite"; + m_columns << ctType << ctName << ctNumber << ctDescription + << ctOpeningDate << ctCurrencyName << ctPayee + << ctLoanAmount << ctInterestRate << ctNextInterestChange + << ctPeriodicPayment << ctFinalPayment << ctFavorite; break; default: - m_columns = ""; + m_columns.clear(); } TableRow::setSortCriteria(sort); @@ -157,24 +168,24 @@ } // help for sort and render functions - scheduleRow["rank"] = '0'; + scheduleRow[ctRank] = QLatin1Char('0'); //schedule data - scheduleRow["id"] = schedule.id(); - scheduleRow["name"] = schedule.name(); - scheduleRow["nextduedate"] = schedule.nextDueDate().toString(Qt::ISODate); - scheduleRow["type"] = KMyMoneyUtils::scheduleTypeToString(schedule.type()); - scheduleRow["occurence"] = i18nc("Frequency of schedule", schedule.occurrenceToString().toLatin1()); // krazy:exclude=spelling - scheduleRow["paymenttype"] = KMyMoneyUtils::paymentMethodToString(schedule.paymentType()); + scheduleRow[ctID] = schedule.id(); + scheduleRow[ctName] = schedule.name(); + scheduleRow[ctNextDueDate] = schedule.nextDueDate().toString(Qt::ISODate); + scheduleRow[ctType] = KMyMoneyUtils::scheduleTypeToString(schedule.type()); + scheduleRow[ctOccurence] = i18nc("Frequency of schedule", schedule.occurrenceToString().toLatin1()); // krazy:exclude=spelling + scheduleRow[ctPaymentType] = KMyMoneyUtils::paymentMethodToString(schedule.paymentType()); //scheduleRow["category"] = account.name(); //to get the payee we must look into the splits of the transaction MyMoneyTransaction transaction = schedule.transaction(); MyMoneySplit split = transaction.splitByAccount(account.id(), true); - scheduleRow["value"] = (split.value() * xr).toString(); + scheduleRow[ctValue] = (split.value() * xr).toString(); MyMoneyPayee payee = file->payee(split.payeeId()); - scheduleRow["payee"] = payee.name(); + scheduleRow[ctPayee] = payee.name(); m_rows += scheduleRow; //the text matches the main split @@ -188,27 +199,27 @@ TableRow splitRow; ReportAccount splitAcc = (*split_it).accountId(); - splitRow["rank"] = '1'; - splitRow["id"] = schedule.id(); - splitRow["name"] = schedule.name(); - splitRow["type"] = KMyMoneyUtils::scheduleTypeToString(schedule.type()); - splitRow["nextduedate"] = schedule.nextDueDate().toString(Qt::ISODate); + splitRow[ctRank] = QLatin1Char('1'); + splitRow[ctID] = schedule.id(); + splitRow[ctName] = schedule.name(); + splitRow[ctType] = KMyMoneyUtils::scheduleTypeToString(schedule.type()); + splitRow[ctNextDueDate] = schedule.nextDueDate().toString(Qt::ISODate); if ((*split_it).value() == MyMoneyMoney::autoCalc) { - splitRow["split"] = MyMoneyMoney::autoCalc.toString(); + splitRow[ctSplit] = MyMoneyMoney::autoCalc.toString(); } else if (! splitAcc.isIncomeExpense()) { - splitRow["split"] = (*split_it).value().toString(); + splitRow[ctSplit] = (*split_it).value().toString(); } else { - splitRow["split"] = (- (*split_it).value()).toString(); + splitRow[ctSplit] = (- (*split_it).value()).toString(); } //if it is an assett account, mark it as a transfer if (! splitAcc.isIncomeExpense()) { - splitRow["category"] = ((* split_it).value().isNegative()) + splitRow[ctCategory] = ((* split_it).value().isNegative()) ? i18n("Transfer from %1" , splitAcc.fullName()) : i18n("Transfer to %1" , splitAcc.fullName()); } else { - splitRow ["category"] = splitAcc.fullName(); + splitRow [ctCategory] = splitAcc.fullName(); } //add the split only if it matches the text or it matches the main split @@ -240,23 +251,23 @@ && account.accountType() != MyMoneyAccount::Stock && !account.isClosed()) { MyMoneyMoney value; - accountRow["rank"] = '0'; - accountRow["topcategory"] = KMyMoneyUtils::accountTypeToString(account.accountGroup()); - accountRow["institution"] = (file->institution(account.institutionId())).name(); - accountRow["type"] = KMyMoneyUtils::accountTypeToString(account.accountType()); - accountRow["name"] = account.name(); - accountRow["number"] = account.number(); - accountRow["description"] = account.description(); - accountRow["openingdate"] = account.openingDate().toString(Qt::ISODate); + accountRow[ctRank] = QLatin1Char('0'); + accountRow[ctTopCategory] = KMyMoneyUtils::accountTypeToString(account.accountGroup()); + accountRow[ctInstitution] = (file->institution(account.institutionId())).name(); + accountRow[ctType] = KMyMoneyUtils::accountTypeToString(account.accountType()); + accountRow[ctName] = account.name(); + accountRow[ctNumber] = account.number(); + accountRow[ctDescription] = account.description(); + accountRow[ctOpeningDate] = account.openingDate().toString(Qt::ISODate); //accountRow["currency"] = (file->currency(account.currencyId())).tradingSymbol(); - accountRow["currencyname"] = (file->currency(account.currencyId())).name(); - accountRow["balancewarning"] = account.value("minBalanceEarly"); - accountRow["maxbalancelimit"] = account.value("minBalanceAbsolute"); - accountRow["creditwarning"] = account.value("maxCreditEarly"); - accountRow["maxcreditlimit"] = account.value("maxCreditAbsolute"); - accountRow["tax"] = account.value("Tax") == QLatin1String("Yes") ? i18nc("Is this a tax account?", "Yes") : QString(); - accountRow["openingbalance"] = account.value("OpeningBalanceAccount") == QLatin1String("Yes") ? i18nc("Is this an opening balance account?", "Yes") : QString(); - accountRow["favorite"] = account.value("PreferredAccount") == QLatin1String("Yes") ? i18nc("Is this a favorite account?", "Yes") : QString(); + accountRow[ctCurrencyName] = (file->currency(account.currencyId())).name(); + accountRow[ctBalanceWarning] = account.value("minBalanceEarly"); + accountRow[ctMaxBalanceLimit] = account.value("minBalanceAbsolute"); + accountRow[ctCreditWarning] = account.value("maxCreditEarly"); + accountRow[ctMaxCreditLimit] = account.value("maxCreditAbsolute"); + accountRow[ctTax] = account.value("Tax") == QLatin1String("Yes") ? i18nc("Is this a tax account?", "Yes") : QString(); + accountRow[ctOpeningBalance] = account.value("OpeningBalanceAccount") == QLatin1String("Yes") ? i18nc("Is this an opening balance account?", "Yes") : QString(); + accountRow[ctFavorite] = account.value("PreferredAccount") == QLatin1String("Yes") ? i18nc("Is this a favorite account?", "Yes") : QString(); //investment accounts show the balances of all its subaccounts if (account.accountType() == MyMoneyAccount::Investment) { @@ -270,7 +281,7 @@ MyMoneyMoney xr = account.baseCurrencyPrice(QDate::currentDate()).reduce(); value = value * xr; } - accountRow["currentbalance"] = value.toString(); + accountRow[ctCurrentBalance] = value.toString(); m_rows += accountRow; } @@ -297,27 +308,27 @@ xr = account.baseCurrencyPrice(QDate::currentDate()).reduce(); } - accountRow["rank"] = '0'; - accountRow["topcategory"] = KMyMoneyUtils::accountTypeToString(account.accountGroup()); - accountRow["institution"] = (file->institution(account.institutionId())).name(); - accountRow["type"] = KMyMoneyUtils::accountTypeToString(account.accountType()); - accountRow["name"] = account.name(); - accountRow["number"] = account.number(); - accountRow["description"] = account.description(); - accountRow["openingdate"] = account.openingDate().toString(Qt::ISODate); + accountRow[ctRank] = QLatin1Char('0'); + accountRow[ctTopCategory] = KMyMoneyUtils::accountTypeToString(account.accountGroup()); + accountRow[ctInstitution] = (file->institution(account.institutionId())).name(); + accountRow[ctType] = KMyMoneyUtils::accountTypeToString(account.accountType()); + accountRow[ctName] = account.name(); + accountRow[ctNumber] = account.number(); + accountRow[ctDescription] = account.description(); + accountRow[ctOpeningDate] = account.openingDate().toString(Qt::ISODate); //accountRow["currency"] = (file->currency(account.currencyId())).tradingSymbol(); - accountRow["currencyname"] = (file->currency(account.currencyId())).name(); - accountRow["payee"] = file->payee(loan.payee()).name(); - accountRow["loanamount"] = (loan.loanAmount() * xr).toString(); - accountRow["interestrate"] = (loan.interestRate(QDate::currentDate()) / MyMoneyMoney(100, 1) * xr).toString(); - accountRow["nextinterestchange"] = loan.nextInterestChange().toString(Qt::ISODate); - accountRow["periodicpayment"] = (loan.periodicPayment() * xr).toString(); - accountRow["finalpayment"] = (loan.finalPayment() * xr).toString(); - accountRow["favorite"] = account.value("PreferredAccount") == QLatin1String("Yes") ? i18nc("Is this a favorite account?", "Yes") : QString(); + accountRow[ctCurrencyName] = (file->currency(account.currencyId())).name(); + accountRow[ctPayee] = file->payee(loan.payee()).name(); + accountRow[ctLoanAmount] = (loan.loanAmount() * xr).toString(); + accountRow[ctInterestRate] = (loan.interestRate(QDate::currentDate()) / MyMoneyMoney(100, 1) * xr).toString(); + accountRow[ctNextInterestChange] = loan.nextInterestChange().toString(Qt::ISODate); + accountRow[ctPeriodicPayment] = (loan.periodicPayment() * xr).toString(); + accountRow[ctFinalPayment] = (loan.finalPayment() * xr).toString(); + accountRow[ctFavorite] = account.value("PreferredAccount") == QLatin1String("Yes") ? i18nc("Is this a favorite account?", "Yes") : QString(); MyMoneyMoney value = file->balance(account.id()); value = value * xr; - accountRow["currentbalance"] = value.toString(); + accountRow[ctCurrentBalance] = value.toString(); m_rows += accountRow; } ++it_account; diff --git a/kmymoney/reports/querytable.cpp b/kmymoney/reports/querytable.cpp --- a/kmymoney/reports/querytable.cpp +++ b/kmymoney/reports/querytable.cpp @@ -258,166 +258,189 @@ void QueryTable::init() { + m_columns.clear(); + m_group.clear(); + m_subtotal.clear(); + m_postcolumns.clear(); switch (m_config.rowType()) { case MyMoneyReport::eAccountByTopAccount: case MyMoneyReport::eEquityType: case MyMoneyReport::eAccountType: case MyMoneyReport::eInstitution: constructAccountTable(); - m_columns = "account"; + m_columns << ctAccount; break; case MyMoneyReport::eAccount: constructTransactionTable(); - m_columns = "accountid,postdate"; + m_columns << ctAccountID << ctPostDate; break; case MyMoneyReport::ePayee: case MyMoneyReport::eTag: case MyMoneyReport::eMonth: case MyMoneyReport::eWeek: constructTransactionTable(); - m_columns = "postdate,account"; + m_columns << ctPostDate << ctAccount; break; case MyMoneyReport::eCashFlow: constructSplitsTable(); - m_columns = "postdate"; + m_columns << ctPostDate; break; default: constructTransactionTable(); - m_columns = "postdate"; + m_columns << ctPostDate; } // Sort the data to match the report definition - m_subtotal = "value"; + m_subtotal << ctValue; switch (m_config.rowType()) { case MyMoneyReport::eCashFlow: - m_group = "categorytype,topcategory,category"; + m_group << ctCategoryType << ctTopCategory << ctCategory; break; case MyMoneyReport::eCategory: - m_group = "categorytype,topcategory,category"; + m_group << ctCategoryType << ctTopCategory << ctCategory; break; case MyMoneyReport::eTopCategory: - m_group = "categorytype,topcategory"; + m_group << ctCategoryType << ctTopCategory; break; case MyMoneyReport::eTopAccount: - m_group = "topaccount,account"; + m_group << ctTopAccount << ctAccount; break; case MyMoneyReport::eAccount: - m_group = "account"; + m_group << ctAccount; break; case MyMoneyReport::eAccountReconcile: - m_group = "account,reconcileflag"; + m_group << ctAccount << ctReconcileFlag; break; case MyMoneyReport::ePayee: - m_group = "payee"; + m_group << ctPayee; break; case MyMoneyReport::eTag: - m_group = "tag"; + m_group << ctTag; break; case MyMoneyReport::eMonth: - m_group = "month"; + m_group << ctMonth; break; case MyMoneyReport::eWeek: - m_group = "week"; + m_group << ctWeek; break; case MyMoneyReport::eAccountByTopAccount: - m_group = "topaccount"; + m_group << ctTopAccount; break; case MyMoneyReport::eEquityType: - m_group = "equitytype"; + m_group << ctEquityType; break; case MyMoneyReport::eAccountType: - m_group = "type"; + m_group << ctType; break; case MyMoneyReport::eInstitution: - m_group = "institution,topaccount"; + m_group << ctInstitution << ctTopAccount; break; default: throw MYMONEYEXCEPTION("QueryTable::QueryTable(): unhandled row type"); } - QString sort = m_group + ",id,rank," + m_columns; + QVector sort = QVector::fromList(m_group) << QVector::fromList(m_columns) << ctID << ctRank; + m_columns.clear(); switch (m_config.rowType()) { case MyMoneyReport::eAccountByTopAccount: case MyMoneyReport::eEquityType: case MyMoneyReport::eAccountType: case MyMoneyReport::eInstitution: - m_columns = "account"; + m_columns << ctAccount; break; default: - m_columns = "postdate"; + m_columns << ctPostDate; } unsigned qc = m_config.queryColumns(); if (qc & MyMoneyReport::eQCnumber) - m_columns += ",number"; + m_columns << ctNumber; if (qc & MyMoneyReport::eQCpayee) - m_columns += ",payee"; + m_columns << ctPayee; if (qc & MyMoneyReport::eQCtag) - m_columns += ",tag"; + m_columns << ctTag; if (qc & MyMoneyReport::eQCcategory) - m_columns += ",category"; + m_columns << ctCategory; if (qc & MyMoneyReport::eQCaccount) - m_columns += ",account"; + m_columns << ctAccount; if (qc & MyMoneyReport::eQCreconciled) - m_columns += ",reconcileflag"; + m_columns << ctReconcileFlag; if (qc & MyMoneyReport::eQCmemo) - m_columns += ",memo"; + m_columns << ctMemo; if (qc & MyMoneyReport::eQCaction) - m_columns += ",action"; + m_columns << ctAction; if (qc & MyMoneyReport::eQCshares) - m_columns += ",shares"; + m_columns << ctShares; if (qc & MyMoneyReport::eQCprice) - m_columns += ",price"; + m_columns << ctPrice; if (qc & MyMoneyReport::eQCperformance) { + m_subtotal.clear(); switch (m_config.investmentSum()) { - case MyMoneyReport::eSumOwnedAndSold: - m_columns += ",buys,sells,reinvestincome,cashincome,endingbal,return,returninvestment"; - m_subtotal = "buys,sells,reinvestincome,cashincome,endingbal,return,returninvestment"; - break; - case MyMoneyReport::eSumOwned: - m_columns += ",buys,reinvestincome,marketvalue,return,returninvestment"; - m_subtotal = "buys,reinvestincome,marketvalue,return,returninvestment"; - break; - case MyMoneyReport::eSumSold: - m_columns += ",buys,sells,cashincome,return,returninvestment"; - m_subtotal = "buys,sells,cashincome,return,returninvestment"; - break; - case MyMoneyReport::eSumPeriod: - default: - m_columns += ",startingbal,buys,sells,reinvestincome,cashincome,endingbal,return,returninvestment"; - m_subtotal = "startingbal,buys,sells,reinvestincome,cashincome,endingbal,return,returninvestment"; - break; + case MyMoneyReport::eSumOwnedAndSold: + m_columns << ctBuys << ctSells << ctReinvestIncome << ctCashIncome + << ctEndingBalance << ctReturn << ctReturnInvestment; + m_subtotal << ctBuys << ctSells << ctReinvestIncome << ctCashIncome + << ctEndingBalance << ctReturn << ctReturnInvestment; + break; + case MyMoneyReport::eSumOwned: + m_columns << ctBuys << ctReinvestIncome << ctMarketValue + << ctReturn << ctReturnInvestment; + m_subtotal << ctBuys << ctReinvestIncome << ctMarketValue + << ctReturn << ctReturnInvestment; + break; + case MyMoneyReport::eSumSold: + m_columns << ctBuys << ctSells << ctCashIncome + << ctReturn << ctReturnInvestment; + m_subtotal << ctBuys << ctSells << ctCashIncome + << ctReturn << ctReturnInvestment; + break; + case MyMoneyReport::eSumPeriod: + default: + m_columns << ctStartingBalance << ctBuys << ctSells + << ctReinvestIncome << ctCashIncome << ctEndingBalance + << ctReturn << ctReturnInvestment; + m_subtotal << ctStartingBalance << ctBuys << ctSells + << ctReinvestIncome << ctCashIncome << ctEndingBalance + << ctReturn << ctReturnInvestment; + break; } } if (qc & MyMoneyReport::eQCcapitalgain) { + m_subtotal.clear(); switch (m_config.investmentSum()) { - case MyMoneyReport::eSumOwned: - m_columns += ",shares,buyprice,lastprice,buys,marketvalue,percentagegain,capitalgain"; - m_subtotal = "buys,marketvalue,percentagegain,capitalgain"; - break; - case MyMoneyReport::eSumSold: - default: - m_columns += ",buys,sells,capitalgain"; - m_subtotal = "buys,sells,capitalgain"; - if (m_config.isShowingSTLTCapitalGains()) { - m_columns += ",buysST,sellsST,capitalgainST,buysLT,sellsLT,capitalgainLT"; - m_subtotal += ",buysST,sellsST,capitalgainST,buysLT,sellsLT,capitalgainLT"; - } - break; + case MyMoneyReport::eSumOwned: + m_columns << ctShares << ctBuyPrice << ctLastPrice + << ctBuys << ctMarketValue << ctPercentageGain + << ctCapitalGain; + m_subtotal << ctShares << ctBuyPrice << ctLastPrice + << ctBuys << ctMarketValue << ctPercentageGain + << ctCapitalGain; + break; + case MyMoneyReport::eSumSold: + default: + m_columns << ctBuys << ctSells << ctCapitalGain; + m_subtotal << ctBuys << ctSells << ctCapitalGain; + if (m_config.isShowingSTLTCapitalGains()) { + m_columns << ctBuysST << ctSellsST << ctCapitalGainST + << ctBuysLT << ctSellsLT << ctCapitalGainLT; + m_subtotal << ctBuysST << ctSellsST << ctCapitalGainST + << ctBuysLT << ctSellsLT << ctCapitalGainLT; + } + break; } } if (qc & MyMoneyReport::eQCloan) { - m_columns += ",payment,interest,fees"; - m_postcolumns = "balance"; + m_columns << ctPayment << ctInterest << ctFees; + m_postcolumns << ctBalance; } if (qc & MyMoneyReport::eQCbalance) - m_postcolumns = "balance"; + m_postcolumns << ctBalance; TableRow::setSortCriteria(sort); qSort(m_rows); @@ -432,31 +455,31 @@ // qSort places grand total at last position, because it doesn't belong to any group for (int i = 0; i < m_rows.count(); ++i) { - if (m_rows.at(0)["rank"] == "4" || m_rows.at(0)["rank"] == "5") // it should be unlikely that total row is at the top of rows, so... + if (m_rows.at(0)[ctRank] == QLatin1String("4") || m_rows.at(0)[ctRank] == QLatin1String("5")) // it should be unlikely that total row is at the top of rows, so... m_rows.move(0, m_rows.count() - 1 - i); // ...move it at the bottom else break; } MyMoneyFile* file = MyMoneyFile::instance(); - QStringList subtotals = m_subtotal.split(','); - QStringList groups = m_group.split(','); - QStringList columns = m_columns.split(','); + QList subtotals = m_subtotal; + QList groups = m_group; + QList columns = m_columns; if (!m_subtotal.isEmpty() && subtotals.count() == 1) columns.append(m_subtotal); - QStringList postcolumns = m_postcolumns.split(','); + QList postcolumns = m_postcolumns; if (!m_postcolumns.isEmpty()) columns.append(postcolumns); - QMap>> totalCurrency; - QList> totalGroups; - QMap totalsValues; + QMap>> totalCurrency; + QList> totalGroups; + QMap totalsValues; // initialize all total values under summed columns to be zero foreach (auto subtotal, subtotals) { totalsValues.insert(subtotal, MyMoneyMoney()); } - totalsValues.insert("rows_count", MyMoneyMoney()); + totalsValues.insert(ctRowsCount, MyMoneyMoney()); // create total groups containing totals row for each group totalGroups.append(totalsValues); // prepend with extra group for grand total @@ -470,35 +493,35 @@ iNextRow = iCurrentRow + 1; // total rows are useless at summing so remove whole block of them at once - while (iNextRow != m_rows.count() && (m_rows.at(iNextRow)["rank"] == "4" || m_rows.at(iNextRow)["rank"] == "5")) { + while (iNextRow != m_rows.count() && (m_rows.at(iNextRow).value(ctRank) == QLatin1String("4") || m_rows.at(iNextRow).value(ctRank) == QLatin1String("5"))) { stashedTotalRows.append(m_rows.takeAt(iNextRow)); // ...but stash them just in case } bool lastRow = (iNextRow == m_rows.count()); // sum all subtotal values for lowest group - QString currencyID = m_rows.at(iCurrentRow).value("currency"); - if (m_rows.at(iCurrentRow)["rank"] == "1") { // don't sum up on balance (rank = 0 || rank = 3) and minor split (rank = 2) + QString currencyID = m_rows.at(iCurrentRow).value(ctCurrency); + if (m_rows.at(iCurrentRow).value(ctRank) == QLatin1String("1")) { // don't sum up on balance (rank = 0 || rank = 3) and minor split (rank = 2) foreach (auto subtotal, subtotals) { if (!totalCurrency.contains(currencyID)) totalCurrency[currencyID].append(totalGroups); totalCurrency[currencyID].last()[subtotal] += MyMoneyMoney(m_rows.at(iCurrentRow)[subtotal]); } - totalCurrency[currencyID].last()["rows_count"] += MyMoneyMoney::ONE; + totalCurrency[currencyID].last()[ctRowsCount] += MyMoneyMoney::ONE; } // iterate over groups from the lowest to the highest to find group change for (int i = groups.count() - 1; i >= 0 ; --i) { // if any of groups from next row changes (or next row is the last row), then it's time to put totals row if (lastRow || m_rows.at(iCurrentRow)[groups.at(i)] != m_rows.at(iNextRow)[groups.at(i)]) { bool isMainCurrencyTotal = true; - QMap>>::iterator currencyGrp = totalCurrency.begin(); + QMap>>::iterator currencyGrp = totalCurrency.begin(); while (currencyGrp != totalCurrency.end()) { - if (!MyMoneyMoney((*currencyGrp).at(i + 1).value("rows_count")).isZero()) { // if no rows summed up, then no totals row + if (!MyMoneyMoney((*currencyGrp).at(i + 1).value(ctRowsCount)).isZero()) { // if no rows summed up, then no totals row TableRow totalsRow; // sum all subtotal values for higher groups (excluding grand total) and reset lowest group values - QMap::iterator upperGrp = (*currencyGrp)[i].begin(); - QMap::iterator lowerGrp = (*currencyGrp)[i + 1].begin(); + QMap::iterator upperGrp = (*currencyGrp)[i].begin(); + QMap::iterator lowerGrp = (*currencyGrp)[i + 1].begin(); while(upperGrp != (*currencyGrp)[i].end()) { totalsRow[lowerGrp.key()] = lowerGrp.value().toString(); // fill totals row with subtotal values... @@ -510,24 +533,24 @@ // custom total values calculations foreach (auto subtotal, subtotals) { - if (subtotal == "returninvestment") - totalsRow[subtotal] = helperROI((*currencyGrp).at(i + 1).value("buys") - (*currencyGrp).at(i + 1).value("reinvestincome"), (*currencyGrp).at(i + 1).value("sells"), - (*currencyGrp).at(i + 1).value("startingbal"), (*currencyGrp).at(i + 1).value("endingbal") + (*currencyGrp).at(i + 1).value("marketvalue"), - (*currencyGrp).at(i + 1).value("cashincome")).toString(); - else if (subtotal == "percentagegain") - totalsRow[subtotal] = (((*currencyGrp).at(i + 1).value("buys") + (*currencyGrp).at(i + 1).value("marketvalue")) / (*currencyGrp).at(i + 1).value("buys").abs()).toString(); - else if (subtotal == "price") - totalsRow[subtotal] = MyMoneyMoney((*currencyGrp).at(i + 1).value("price") / (*currencyGrp).at(i + 1).value("rows_count")).toString(); + if (subtotal == ctReturnInvestment) + totalsRow[subtotal] = helperROI((*currencyGrp).at(i + 1).value(ctBuys) - (*currencyGrp).at(i + 1).value(ctReinvestIncome), (*currencyGrp).at(i + 1).value(ctSells), + (*currencyGrp).at(i + 1).value(ctStartingBalance), (*currencyGrp).at(i + 1).value(ctEndingBalance) + (*currencyGrp).at(i + 1).value(ctMarketValue), + (*currencyGrp).at(i + 1).value(ctCashIncome)).toString(); + else if (subtotal == ctPercentageGain) + totalsRow[subtotal] = (((*currencyGrp).at(i + 1).value(ctBuys) + (*currencyGrp).at(i + 1).value(ctMarketValue)) / (*currencyGrp).at(i + 1).value(ctBuys).abs()).toString(); + else if (subtotal == ctPrice) + totalsRow[subtotal] = MyMoneyMoney((*currencyGrp).at(i + 1).value(ctPrice) / (*currencyGrp).at(i + 1).value(ctRowsCount)).toString(); } // total values that aren't calculated here, but are taken untouched from external source, e.g. constructPerformanceRow if (!stashedTotalRows.isEmpty()) { for (int j = 0; j < stashedTotalRows.count(); ++j) { - if (stashedTotalRows.at(j).value("currency") != currencyID) + if (stashedTotalRows.at(j).value(ctCurrency) != currencyID) continue; foreach (auto subtotal, subtotals) { - if (subtotal == "return") - totalsRow["return"] = stashedTotalRows.takeAt(j)["return"]; + if (subtotal == ctReturn) + totalsRow[ctReturn] = stashedTotalRows.takeAt(j)[ctReturn]; } break; } @@ -541,14 +564,14 @@ QString currencyID = currencyGrp.key(); if (currencyID.isEmpty() && totalCurrency.count() > 1) currencyID = file->baseCurrency().id(); - totalsRow["currency"] = currencyID; + totalsRow[ctCurrency] = currencyID; if (isMainCurrencyTotal) { - totalsRow["rank"] = "4"; + totalsRow[ctRank] = QLatin1Char('4'); isMainCurrencyTotal = false; } else - totalsRow["rank"] = "5"; - totalsRow["depth"] = QString::number(i); - totalsRow.remove("rows_count"); + totalsRow[ctRank] = QLatin1Char('5'); + totalsRow[ctDepth] = QString::number(i); + totalsRow.remove(ctRowsCount); m_rows.insert(iNextRow++, totalsRow); // iCurrentRow and iNextRow can diverge here by more than one } @@ -560,31 +583,31 @@ // code to put grand total row if (lastRow) { bool isMainCurrencyTotal = true; - QMap>>::iterator currencyGrp = totalCurrency.begin(); + QMap>>::iterator currencyGrp = totalCurrency.begin(); while (currencyGrp != totalCurrency.end()) { TableRow totalsRow; - QMap::const_iterator grandTotalGrp = (*currencyGrp)[0].constBegin(); + QMap::const_iterator grandTotalGrp = (*currencyGrp)[0].constBegin(); while(grandTotalGrp != (*currencyGrp)[0].constEnd()) { totalsRow[grandTotalGrp.key()] = grandTotalGrp.value().toString(); ++grandTotalGrp; } foreach (auto subtotal, subtotals) { - if (subtotal == "returninvestment") - totalsRow[subtotal] = helperROI((*currencyGrp).at(0).value("buys") - (*currencyGrp).at(0).value("reinvestincome"), (*currencyGrp).at(0).value("sells"), - (*currencyGrp).at(0).value("startingbal"), (*currencyGrp).at(0).value("endingbal") + (*currencyGrp).at(0).value("marketvalue"), - (*currencyGrp).at(0).value("cashincome")).toString(); - else if (subtotal == "percentagegain") - totalsRow[subtotal] = (((*currencyGrp).at(0).value("buys") + (*currencyGrp).at(0).value("marketvalue")) / (*currencyGrp).at(0).value("buys").abs()).toString(); - else if (subtotal == "price") - totalsRow[subtotal] = MyMoneyMoney((*currencyGrp).at(0).value("price") / (*currencyGrp).at(0).value("rows_count")).toString(); + if (subtotal == ctReturnInvestment) + totalsRow[subtotal] = helperROI((*currencyGrp).at(0).value(ctBuys) - (*currencyGrp).at(0).value(ctReinvestIncome), (*currencyGrp).at(0).value(ctSells), + (*currencyGrp).at(0).value(ctStartingBalance), (*currencyGrp).at(0).value(ctEndingBalance) + (*currencyGrp).at(0).value(ctMarketValue), + (*currencyGrp).at(0).value(ctCashIncome)).toString(); + else if (subtotal == ctPercentageGain) + totalsRow[subtotal] = (((*currencyGrp).at(0).value(ctBuys) + (*currencyGrp).at(0).value(ctMarketValue)) / (*currencyGrp).at(0).value(ctBuys).abs()).toString(); + else if (subtotal == ctPrice) + totalsRow[subtotal] = MyMoneyMoney((*currencyGrp).at(0).value(ctPrice) / (*currencyGrp).at(0).value(ctRowsCount)).toString(); } if (!stashedTotalRows.isEmpty()) { for (int j = 0; j < stashedTotalRows.count(); ++j) { foreach (auto subtotal, subtotals) { - if (subtotal == "return") - totalsRow["return"] = stashedTotalRows.takeAt(j)["return"]; + if (subtotal == ctReturn) + totalsRow[ctReturn] = stashedTotalRows.takeAt(j)[ctReturn]; } } } @@ -596,13 +619,13 @@ QString currencyID = currencyGrp.key(); if (currencyID.isEmpty() && totalCurrency.count() > 1) currencyID = file->baseCurrency().id(); - totalsRow["currency"] = currencyID; + totalsRow[ctCurrency] = currencyID; if (isMainCurrencyTotal) { - totalsRow["rank"] = "4"; + totalsRow[ctRank] = QLatin1Char('4'); isMainCurrencyTotal = false; } else - totalsRow["rank"] = "5"; - totalsRow["depth"] = ""; + totalsRow[ctRank] = QLatin1Char('5'); + totalsRow[ctDepth] = QString(); m_rows.append(totalsRow); ++currencyGrp; @@ -665,19 +688,19 @@ QDate pd; QList tagIdListCache; - qA["id"] = qS["id"] = (* it_transaction).id(); - qA["entrydate"] = qS["entrydate"] = (* it_transaction).entryDate().toString(Qt::ISODate); - qA["postdate"] = qS["postdate"] = (* it_transaction).postDate().toString(Qt::ISODate); - qA["commodity"] = qS["commodity"] = (* it_transaction).commodity(); + qA[ctID] = qS[ctID] = (* it_transaction).id(); + qA[ctEntryDate] = qS[ctEntryDate] = (* it_transaction).entryDate().toString(Qt::ISODate); + qA[ctPostDate] = qS[ctPostDate] = (* it_transaction).postDate().toString(Qt::ISODate); + qA[ctCommodity] = qS[ctCommodity] = (* it_transaction).commodity(); pd = (* it_transaction).postDate(); - qA["month"] = qS["month"] = i18n("Month of %1", QDate(pd.year(), pd.month(), 1).toString(Qt::ISODate)); - qA["week"] = qS["week"] = i18n("Week of %1", pd.addDays(1 - pd.dayOfWeek()).toString(Qt::ISODate)); + qA[ctMonth] = qS[ctMonth] = i18n("Month of %1", QDate(pd.year(), pd.month(), 1).toString(Qt::ISODate)); + qA[ctWeek] = qS[ctWeek] = i18n("Week of %1", pd.addDays(1 - pd.dayOfWeek()).toString(Qt::ISODate)); if (report.isConvertCurrency()) - qA["currency"] = qS["currency"] = file->baseCurrency().id(); + qA[ctCurrency] = qS[ctCurrency] = file->baseCurrency().id(); else - qA["currency"] = qS["currency"] = (*it_transaction).commodity(); + qA[ctCurrency] = qS[ctCurrency] = (*it_transaction).commodity(); // to handle splits, we decide on which account to base the split // (a reference point or point of view so to speak). here we take the @@ -738,8 +761,8 @@ bool include_me = true; bool transaction_text = false; //indicates whether a text should be considered as a match for the transaction or for a split only - QString a_fullname = ""; - QString a_memo = ""; + QString a_fullname; + QString a_memo; int pass = 1; QString myBeginCurrency; @@ -782,9 +805,9 @@ (*it_transaction).postDate()); // ...so check conversion rate... if (price.isValid()) { xr *= price.rate(baseCurrency); // ...and multiply it by current price... - qA["currency"] = qS["currency"] = baseCurrency; + qA[ctCurrency] = qS[ctCurrency] = baseCurrency; } else - qA["currency"] = qS["currency"] = myBeginCurrency; // ...and set information about non-baseCurrency + qA[ctCurrency] = qS[ctCurrency] = myBeginCurrency; // ...and set information about non-baseCurrency } } else if (splitAcc.isInvest()) xr = (*it_split).price(); @@ -799,24 +822,24 @@ //balances but no transactions if the splits are all filtered out -- asoliverez accts.insert(splitAcc.id(), splitAcc); - qA["account"] = splitAcc.name(); - qA["accountid"] = splitAcc.id(); - qA["topaccount"] = splitAcc.topParentName(); + qA[ctAccount] = splitAcc.name(); + qA[ctAccountID] = splitAcc.id(); + qA[ctTopAccount] = splitAcc.topParentName(); if (splitAcc.isInvest()) { // use the institution of the parent for stock accounts institution = splitAcc.parent().institutionId(); MyMoneyMoney shares = (*it_split).shares(); int pricePrecision = file->security(splitAcc.currencyId()).pricePrecision(); - qA["action"] = (*it_split).action(); - qA["shares"] = shares.isZero() ? "" : shares.toString(); - qA["price"] = shares.isZero() ? "" : xr.convertPrecision(pricePrecision).toString(); + qA[ctAction] = (*it_split).action(); + qA[ctShares] = shares.isZero() ? QString() : shares.toString(); + qA[ctPrice] = shares.isZero() ? QString() : xr.convertPrecision(pricePrecision).toString(); if (((*it_split).action() == MyMoneySplit::ActionBuyShares) && shares.isNegative()) - qA["action"] = "Sell"; + qA[ctAction] = "Sell"; - qA["investaccount"] = splitAcc.parent().name(); + qA[ctInvestAccount] = splitAcc.parent().name(); MyMoneySplit stockSplit = (*it_split); MyMoneySplit assetAccountSplit; @@ -837,13 +860,13 @@ MyMoneyPrice price = file->price(myBeginCurrency, baseCurrency, (*it_transaction).postDate()); if (price.isValid()) { xr = price.rate(baseCurrency); - qA["currency"] = qS["currency"] = baseCurrency; + qA[ctCurrency] = qS[ctCurrency] = baseCurrency; } else - qA["currency"] = qS["currency"] = myBeginCurrency; + qA[ctCurrency] = qS[ctCurrency] = myBeginCurrency; } else xr = MyMoneyMoney::ONE; - qA["price"] = shares.isZero() ? "" : (stockSplit.price() * xr / (*it_split).price()).toString(); + qA[ctPrice] = shares.isZero() ? QString() : (stockSplit.price() * xr / (*it_split).price()).toString(); // put conversion rate for all splits with this currency, so... // every split of transaction have the same conversion rate xrMap.insert(splitCurrency, MyMoneyMoney::ONE / (*it_split).price()); @@ -854,66 +877,66 @@ } } } else - qA["price"] = xr.toString(); + qA[ctPrice] = xr.toString(); a_fullname = splitAcc.fullName(); a_memo = (*it_split).memo(); transaction_text = m_config.match(&(*it_split)); - qA["institution"] = institution.isEmpty() + qA[ctInstitution] = institution.isEmpty() ? i18n("No Institution") : file->institution(institution).name(); - qA["payee"] = payee.isEmpty() + qA[ctPayee] = payee.isEmpty() ? i18n("[Empty Payee]") : file->payee(payee).name().simplified(); if (tag_special_case) { tagIdListCache = tagIdList; } else { - QString delimiter = ""; - for (int i = 0; i < tagIdList.size(); i++) { - qA["tag"] += delimiter + file->tag(tagIdList[i]).name().simplified(); - delimiter = ", "; + QString delimiter; + foreach(const auto tagId, tagIdList) { + qA[ctTag] += delimiter + file->tag(tagId).name().simplified(); + delimiter = QLatin1Char(','); } } - qA["reconciledate"] = (*it_split).reconcileDate().toString(Qt::ISODate); - qA["reconcileflag"] = KMyMoneyUtils::reconcileStateToString((*it_split).reconcileFlag(), true); - qA["number"] = (*it_split).number(); + qA[ctReconcileDate] = (*it_split).reconcileDate().toString(Qt::ISODate); + qA[ctReconcileFlag] = KMyMoneyUtils::reconcileStateToString((*it_split).reconcileFlag(), true); + qA[ctNumber] = (*it_split).number(); - qA["memo"] = a_memo; + qA[ctMemo] = a_memo; - qA["value"] = ((*it_split).shares() * xr).convert(fraction).toString(); + qA[ctValue] = ((*it_split).shares() * xr).convert(fraction).toString(); - qS["reconciledate"] = qA["reconciledate"]; - qS["reconcileflag"] = qA["reconcileflag"]; - qS["number"] = qA["number"]; + qS[ctReconcileDate] = qA[ctReconcileDate]; + qS[ctReconcileFlag] = qA[ctReconcileFlag]; + qS[ctNumber] = qA[ctNumber]; - qS["topcategory"] = splitAcc.topParentName(); - qS["categorytype"] = i18n("Transfer"); + qS[ctTopCategory] = splitAcc.topParentName(); + qS[ctCategoryType] = i18n("Transfer"); // only include the configured accounts if (include_me) { if (loan_special_case) { // put the principal amount in the "value" column and convert to lowest fraction - qA["value"] = (-(*it_split).shares() * xr).convert(fraction).toString(); + qA[ctValue] = (-(*it_split).shares() * xr).convert(fraction).toString(); - qA["rank"] = '1'; - qA["split"] = ""; + qA[ctRank] = QLatin1Char('1'); + qA[ctSplit].clear(); } else { if ((splits.count() > 2) && use_summary) { // add the "summarized" split transaction // this is the sub-total of the split detail // convert to lowest fraction - qA["rank"] = '1'; - qA["category"] = i18n("[Split Transaction]"); - qA["topcategory"] = i18nc("Split transaction", "Split"); - qA["categorytype"] = i18nc("Split transaction", "Split"); + qA[ctRank] = QLatin1Char('1'); + qA[ctCategory] = i18n("[Split Transaction]"); + qA[ctTopCategory] = i18nc("Split transaction", "Split"); + qA[ctCategoryType] = i18nc("Split transaction", "Split"); m_rows += qA; } @@ -929,10 +952,10 @@ if ((*it_split).action() == MyMoneySplit::ActionAmortization) { // put the payment in the "payment" column and convert to lowest fraction - qA["payment"] = value.toString(); + qA[ctPayee] = value.toString(); } else if ((*it_split).action() == MyMoneySplit::ActionInterest) { // put the interest in the "interest" column and convert to lowest fraction - qA["interest"] = value.toString(); + qA[ctInterest] = value.toString(); } else if (splits.count() > 2) { // [dv: This comment carried from the original code. I am // not exactly clear on what it means or why we do this.] @@ -942,8 +965,8 @@ // the transaction. I wish there was a better way. } else { // accumulate everything else in the "fees" column - MyMoneyMoney n0 = MyMoneyMoney(qA["fees"]); - qA["fees"] = (n0 + value).toString(); + MyMoneyMoney n0 = MyMoneyMoney(qA[ctFees]); + qA[ctFees] = (n0 + value).toString(); } // we don't add qA here for a loan transaction. we'll add one // qA afer all of the split components have been processed. @@ -960,36 +983,36 @@ //this is when the splits are going to be shown as children of the main split if ((splits.count() > 2) && use_summary) { - qA["value"] = ""; + qA[ctValue].clear(); //convert to lowest fraction - qA["split"] = (-(*it_split).shares() * xr).convert(fraction).toString(); - qA["rank"] = '2'; + qA[ctSplit] = (-(*it_split).shares() * xr).convert(fraction).toString(); + qA[ctRank] = QLatin1Char('2'); } else { //this applies when the transaction has only 2 splits, or each split is going to be //shown separately, eg. transactions by category - qA["split"] = ""; - qA["rank"] = '1'; + qA[ctSplit].clear(); + qA[ctRank] = QLatin1Char('1'); } - qA ["memo"] = (*it_split).memo(); + qA [ctMemo] = (*it_split).memo(); if (report.isConvertCurrency()) - qS["currency"] = file->baseCurrency().id(); + qS[ctCurrency] = file->baseCurrency().id(); else - qS["currency"] = splitAcc.currencyId(); + qS[ctCurrency] = splitAcc.currency().id(); if (! splitAcc.isIncomeExpense()) { - qA["category"] = ((*it_split).shares().isNegative()) ? + qA[ctCategory] = ((*it_split).shares().isNegative()) ? i18n("Transfer from %1", splitAcc.fullName()) : i18n("Transfer to %1", splitAcc.fullName()); - qA["topcategory"] = splitAcc.topParentName(); - qA["categorytype"] = i18n("Transfer"); + qA[ctTopCategory] = splitAcc.topParentName(); + qA[ctCategoryType] = i18n("Transfer"); } else { - qA ["category"] = splitAcc.fullName(); - qA ["topcategory"] = splitAcc.topParentName(); - qA ["categorytype"] = KMyMoneyUtils::accountTypeToString(splitAcc.accountGroup()); + qA [ctCategory] = splitAcc.fullName(); + qA [ctTopCategory] = splitAcc.topParentName(); + qA [ctCategoryType] = KMyMoneyUtils::accountTypeToString(splitAcc.accountGroup()); } if (use_transfers || (splitAcc.isIncomeExpense() && m_config.includes(splitAcc))) { @@ -1005,10 +1028,10 @@ || m_config.match(&(*it_split))))) { if (tag_special_case) { if (!tagIdListCache.size()) - qA["tag"] = i18n("[No Tag]"); + qA[ctTag] = i18n("[No Tag]"); else for (int i = 0; i < tagIdListCache.size(); i++) { - qA["tag"] = file->tag(tagIdListCache[i]).name().simplified(); + qA[ctTag] = file->tag(tagIdListCache[i]).name().simplified(); m_rows += qA; } } else { @@ -1023,35 +1046,35 @@ !(splitAcc.isInvest() && include_me)) { // otherwise stock split is displayed twice in report if (! splitAcc.isIncomeExpense()) { //multiply by currency and convert to lowest fraction - qS["value"] = ((*it_split).shares() * xr).convert(fraction).toString(); + qS[ctValue] = ((*it_split).shares() * xr).convert(fraction).toString(); - qS["rank"] = '1'; + qS[ctRank] = QLatin1Char('1'); - qS["account"] = splitAcc.name(); - qS["accountid"] = splitAcc.id(); - qS["topaccount"] = splitAcc.topParentName(); + qS[ctAccount] = splitAcc.name(); + qS[ctAccountID] = splitAcc.id(); + qS[ctTopAccount] = splitAcc.topParentName(); - qS["category"] = ((*it_split).shares().isNegative()) + qS[ctCategory] = ((*it_split).shares().isNegative()) ? i18n("Transfer to %1", a_fullname) : i18n("Transfer from %1", a_fullname); - qS["institution"] = institution.isEmpty() + qS[ctInstitution] = institution.isEmpty() ? i18n("No Institution") : file->institution(institution).name(); - qS["memo"] = (*it_split).memo().isEmpty() + qS[ctMemo] = (*it_split).memo().isEmpty() ? a_memo : (*it_split).memo(); //FIXME-ALEX When is used this? I can't find in which condition we arrive here... maybe this code is useless? - QString delimiter = ""; + QString delimiter; for (int i = 0; i < tagIdList.size(); i++) { - qA["tag"] += delimiter + file->tag(tagIdList[i]).name().simplified(); - delimiter = '+'; + qA[ctTag] += delimiter + file->tag(tagIdList[i]).name().simplified(); + delimiter = "+"; } - qS["payee"] = payee.isEmpty() - ? qA["payee"] + qS[ctPayee] = payee.isEmpty() + ? qA[ctPayee] : file->payee(payee).name().simplified(); //check the specific split against the filter for text and amount @@ -1157,38 +1180,38 @@ //starting balance // don't show currency if we're converting or if it's not foreign if (m_config.isConvertCurrency()) - qA["currency"] = file->baseCurrency().id(); + qA[ctCurrency] = file->baseCurrency().id(); else - qA["currency"] = account.currency().id(); + qA[ctCurrency] = account.currency().id(); - qA["accountid"] = account.id(); - qA["account"] = account.name(); - qA["topaccount"] = account.topParentName(); - qA["institution"] = institution.isEmpty() ? i18n("No Institution") : file->institution(institution).name(); - qA["rank"] = "0"; + qA[ctAccountID] = account.id(); + qA[ctAccount] = account.name(); + qA[ctTopAccount] = account.topParentName(); + qA[ctInstitution] = institution.isEmpty() ? i18n("No Institution") : file->institution(institution).name(); + qA[ctRank] = QLatin1Char('0'); - qA["price"] = startPrice.convertPrecision(account.currency().pricePrecision()).toString(); + qA[ctPrice] = startPrice.convertPrecision(account.currency().pricePrecision()).toString(); if (account.isInvest()) { - qA["shares"] = startShares.toString(); + qA[ctShares] = startShares.toString(); } - qA["postdate"] = strStartDate; - qA["balance"] = startBalance.convert(fraction).toString(); - qA["value"].clear(); - qA["id"] = 'A'; + qA[ctPostDate] = strStartDate; + qA[ctBalance] = startBalance.convert(fraction).toString(); + qA[ctValue].clear(); + qA[ctID] = QLatin1Char('A'); m_rows += qA; //ending balance - qA["price"] = endPrice.convertPrecision(account.currency().pricePrecision()).toString(); + qA[ctPrice] = endPrice.convertPrecision(account.currency().pricePrecision()).toString(); if (account.isInvest()) { - qA["shares"] = endShares.toString(); + qA[ctShares] = endShares.toString(); } - qA["postdate"] = strEndDate; - qA["balance"] = endBalance.toString(); - qA["rank"] = "3"; - qA["id"] = 'Z'; + qA[ctPostDate] = strEndDate; + qA[ctBalance] = endBalance.toString(); + qA[ctRank] = QLatin1Char('3'); + qA[ctID] = QLatin1Char('Z'); m_rows += qA; } } @@ -1358,7 +1381,6 @@ cfList[BuysOfOwned].append(CashFlowListItem(postDate, (shList.at(BuysOfOwned) / shares) * value)); shList[BuysOfOwned] = MyMoneyMoney(); } - qDebug() << "szeres: " << shares.toDouble() << "prais: " << price.toDouble() << "value:" << value.toDouble(); if (transactionType == MyMoneySplit::ReinvestDividend) { value = MyMoneyMoney(); foreach (const auto split, interestSplits) @@ -1493,10 +1515,10 @@ all.append(cfList.at(Sells)); all.append(cfList.at(CashIncome)); - result[QLatin1String("sells")] = sellsTotal.toString(); - result[QLatin1String("cashincome")] = cashIncomeTotal.toString(); - result[QLatin1String("reinvestincome")] = reinvestIncomeTotal.toString(); - result[QLatin1String("endingbal")] = endingBal.toString(); + result[ctSells] = sellsTotal.toString(); + result[ctCashIncome] = cashIncomeTotal.toString(); + result[ctReinvestIncome] = reinvestIncomeTotal.toString(); + result[ctEndingBalance] = endingBal.toString(); break; case MyMoneyReport::eSumOwned: buysTotal = cfList.at(BuysOfOwned).total(); @@ -1506,8 +1528,8 @@ all.append(cfList.at(BuysOfOwned)); all.append(CashFlowListItem(endingDate, endingBal)); - result[QLatin1String("reinvestincome")] = reinvestIncomeTotal.toString(); - result[QLatin1String("marketvalue")] = endingBal.toString(); + result[ctReinvestIncome] = reinvestIncomeTotal.toString(); + result[ctMarketValue] = endingBal.toString(); break; case MyMoneyReport::eSumSold: buysTotal = cfList.at(BuysOfSells).total(); @@ -1521,8 +1543,8 @@ all.append(cfList.at(Sells)); all.append(cfList.at(CashIncome)); - result[QLatin1String("sells")] = sellsTotal.toString(); - result[QLatin1String("cashincome")] = cashIncomeTotal.toString(); + result[ctSells] = sellsTotal.toString(); + result[ctCashIncome] = cashIncomeTotal.toString(); break; case MyMoneyReport::eSumPeriod: default: @@ -1541,21 +1563,21 @@ all.append(CashFlowListItem(startingDate, -startingBal)); all.append(CashFlowListItem(endingDate, endingBal)); - result[QLatin1String("sells")] = sellsTotal.toString(); - result[QLatin1String("cashincome")] = cashIncomeTotal.toString(); - result[QLatin1String("reinvestincome")] = reinvestIncomeTotal.toString(); - result[QLatin1String("startingbal")] = startingBal.toString(); - result[QLatin1String("endingbal")] = endingBal.toString(); + result[ctSells] = sellsTotal.toString(); + result[ctCashIncome] = cashIncomeTotal.toString(); + result[ctReinvestIncome] = reinvestIncomeTotal.toString(); + result[ctStartingBalance] = startingBal.toString(); + result[ctEndingBalance] = endingBal.toString(); break; } MyMoneyMoney returnInvestment = helperROI(buysTotal - reinvestIncomeTotal, sellsTotal, startingBal, endingBal, cashIncomeTotal); MyMoneyMoney annualReturn = helperIRR(all); - result[QLatin1String("buys")] = buysTotal.toString(); - result[QLatin1String("return")] = annualReturn.toString(); - result[QLatin1String("returninvestment")] = returnInvestment.toString(); - result[QLatin1String("equitytype")] = KMyMoneyUtils::securityTypeToString(file->security(account.currencyId()).securityType()); + result[ctBuys] = buysTotal.toString(); + result[ctReturn] = annualReturn.toString(); + result[ctReturnInvestment] = returnInvestment.toString(); + result[ctEquityType] = KMyMoneyUtils::securityTypeToString(file->security(account.currencyId()).securityType()); } void QueryTable::constructCapitalGainRow(const ReportAccount& account, TableRow& result) const @@ -1599,13 +1621,13 @@ buysTotal = cfList.at(BuysOfOwned).total() - cfList.at(ReinvestIncome).total(); int pricePrecision = file->security(account.currencyId()).pricePrecision(); - result[QLatin1String("buys")] = buysTotal.toString(); - result[QLatin1String("shares")] = shList.at(BuysOfOwned).toString(); - result[QLatin1String("buyprice")] = (buysTotal.abs() / shList.at(BuysOfOwned)).convertPrecision(pricePrecision).toString(); - result[QLatin1String("lastprice")] = price.toString(); - result[QLatin1String("marketvalue")] = endingBal.toString(); - result[QLatin1String("capitalgain")] = (buysTotal + endingBal).toString(); - result[QLatin1String("percentagegain")] = ((buysTotal + endingBal)/buysTotal.abs()).toString(); + result[ctBuys] = buysTotal.toString(); + result[ctShares] = shList.at(BuysOfOwned).toString(); + result[ctBuyPrice] = (buysTotal.abs() / shList.at(BuysOfOwned)).convertPrecision(pricePrecision).toString(); + result[ctLastPrice] = price.toString(); + result[ctMarketValue] = endingBal.toString(); + result[ctCapitalGain] = (buysTotal + endingBal).toString(); + result[ctPercentageGain] = ((buysTotal + endingBal)/buysTotal.abs()).toString(); break; } case MyMoneyReport::eSumSold: @@ -1619,21 +1641,21 @@ longTermBuysOfSellsTotal.isZero() && longTermSellsOfBuys.isZero()) return; - result[QLatin1String("buys")] = buysTotal.toString(); - result[QLatin1String("sells")] = sellsTotal.toString(); - result[QLatin1String("capitalgain")] = (buysTotal + sellsTotal).toString(); + result[ctBuys] = buysTotal.toString(); + result[ctSells] = sellsTotal.toString(); + result[ctCapitalGain] = (buysTotal + sellsTotal).toString(); if (m_config.isShowingSTLTCapitalGains()) { - result[QLatin1String("buysLT")] = longTermBuysOfSellsTotal.toString(); - result[QLatin1String("sellsLT")] = longTermSellsOfBuys.toString(); - result[QLatin1String("capitalgainLT")] = (longTermBuysOfSellsTotal + longTermSellsOfBuys).toString(); - result[QLatin1String("buysST")] = (buysTotal - longTermBuysOfSellsTotal).toString(); - result[QLatin1String("sellsST")] = (sellsTotal - longTermSellsOfBuys).toString(); - result[QLatin1String("capitalgainST")] = ((buysTotal - longTermBuysOfSellsTotal) + (sellsTotal - longTermSellsOfBuys)).toString(); + result[ctBuysLT] = longTermBuysOfSellsTotal.toString(); + result[ctSellsLT] = longTermSellsOfBuys.toString(); + result[ctCapitalGainLT] = (longTermBuysOfSellsTotal + longTermSellsOfBuys).toString(); + result[ctBuysST] = (buysTotal - longTermBuysOfSellsTotal).toString(); + result[ctSellsST] = (sellsTotal - longTermSellsOfBuys).toString(); + result[ctCapitalGainST] = ((buysTotal - longTermBuysOfSellsTotal) + (sellsTotal - longTermSellsOfBuys)).toString(); } break; } - result[QLatin1String("equitytype")] = KMyMoneyUtils::securityTypeToString(file->security(account.currencyId()).securityType()); + result[ctEquityType] = KMyMoneyUtils::securityTypeToString(file->security(account.currencyId()).securityType()); } void QueryTable::constructAccountTable() @@ -1667,16 +1689,16 @@ constructPerformanceRow(account, qaccountrow, accountCashflow); if (!qaccountrow.isEmpty()) { // assuming that that report is grouped by topaccount - qaccountrow["topaccount"] = account.topParentName(); + qaccountrow[ctTopAccount] = account.topParentName(); if (m_config.isConvertCurrency()) - qaccountrow["currency"] = file->baseCurrency().id(); + qaccountrow[ctCurrency] = file->baseCurrency().id(); else - qaccountrow["currency"] = account.currency().id(); + qaccountrow[ctCurrency] = account.currency().id(); - if (!currencyCashFlow.value(qaccountrow.value("currency")).contains(qaccountrow.value("topaccount"))) - currencyCashFlow[qaccountrow.value("currency")].insert(qaccountrow.value("topaccount"), accountCashflow); // create cashflow for unknown account... + if (!currencyCashFlow.value(qaccountrow.value(ctCurrency)).contains(qaccountrow.value(ctTopAccount))) + currencyCashFlow[qaccountrow.value(ctCurrency)].insert(qaccountrow.value(ctTopAccount), accountCashflow); // create cashflow for unknown account... else - currencyCashFlow[qaccountrow.value("currency")][qaccountrow.value("topaccount")] += accountCashflow; // ...or add cashflow for known account + currencyCashFlow[qaccountrow.value(ctCurrency)][qaccountrow.value(ctTopAccount)] += accountCashflow; // ...or add cashflow for known account } break; } @@ -1696,62 +1718,62 @@ netprice = netprice.reduce(); shares = shares.reduce(); int pricePrecision = file->security(account.currencyId()).pricePrecision(); - qaccountrow["price"] = netprice.convertPrecision(pricePrecision).toString(); - qaccountrow["value"] = (netprice * shares).convert(fraction).toString(); - qaccountrow["shares"] = shares.toString(); + qaccountrow[ctPrice] = netprice.convertPrecision(pricePrecision).toString(); + qaccountrow[ctValue] = (netprice * shares).convert(fraction).toString(); + qaccountrow[ctShares] = shares.toString(); QString iid = account.institutionId(); // If an account does not have an institution, get it from the top-parent. if (iid.isEmpty() && !account.isTopLevel()) iid = account.topParent().institutionId(); if (iid.isEmpty()) - qaccountrow["institution"] = i18nc("No institution", "None"); + qaccountrow[ctInstitution] = i18nc("No institution", "None"); else - qaccountrow["institution"] = file->institution(iid).name(); + qaccountrow[ctInstitution] = file->institution(iid).name(); - qaccountrow["type"] = KMyMoneyUtils::accountTypeToString(account.accountType()); + qaccountrow[ctType] = KMyMoneyUtils::accountTypeToString(account.accountType()); } } if (qaccountrow.isEmpty()) // don't add the account if there are no calculated values continue; - qaccountrow["rank"] = '1'; - qaccountrow["account"] = account.name(); - qaccountrow["accountid"] = account.id(); - qaccountrow["topaccount"] = account.topParentName(); + qaccountrow[ctRank] = QLatin1Char('1'); + qaccountrow[ctAccount] = account.name(); + qaccountrow[ctAccountID] = account.id(); + qaccountrow[ctTopAccount] = account.topParentName(); if (m_config.isConvertCurrency()) - qaccountrow["currency"] = file->baseCurrency().id(); + qaccountrow[ctCurrency] = file->baseCurrency().id(); else - qaccountrow["currency"] = account.currency().id(); + qaccountrow[ctCurrency] = account.currency().id(); m_rows.append(qaccountrow); } } if (m_config.queryColumns() == MyMoneyReport::eQCperformance && m_config.isShowingColumnTotals()) { TableRow qtotalsrow; - qtotalsrow["rank"] = "4"; // add identification of row as total + qtotalsrow[ctRank] = QLatin1Char('4'); // add identification of row as total QMap currencyGrandCashFlow; QMap>::iterator currencyAccGrp = currencyCashFlow.begin(); while (currencyAccGrp != currencyCashFlow.end()) { // convert map of top accounts with cashflows to TableRow for (QMap::iterator topAccount = (*currencyAccGrp).begin(); topAccount != (*currencyAccGrp).end(); ++topAccount) { - qtotalsrow["topaccount"] = topAccount.key(); - qtotalsrow["return"] = helperIRR(topAccount.value()).toString(); - qtotalsrow["currency"] = currencyAccGrp.key(); + qtotalsrow[ctTopAccount] = topAccount.key(); + qtotalsrow[ctReturn] = helperIRR(topAccount.value()).toString(); + qtotalsrow[ctCurrency] = currencyAccGrp.key(); currencyGrandCashFlow[currencyAccGrp.key()] += topAccount.value(); // cumulative sum of cashflows of each topaccount m_rows.append(qtotalsrow); // rows aren't sorted yet, so no problem with adding them randomly at the end } ++currencyAccGrp; } QMap::iterator currencyGrp = currencyGrandCashFlow.begin(); - qtotalsrow["topaccount"] = ""; // empty topaccount because it's grand cashflow + qtotalsrow[ctTopAccount].clear(); // empty topaccount because it's grand cashflow while (currencyGrp != currencyGrandCashFlow.end()) { - qtotalsrow["return"] = helperIRR(currencyGrp.value()).toString(); - qtotalsrow["currency"] = currencyGrp.key(); + qtotalsrow[ctReturn] = helperIRR(currencyGrp.value()).toString(); + qtotalsrow[ctCurrency] = currencyGrp.key(); m_rows.append(qtotalsrow); ++currencyGrp; } @@ -1779,19 +1801,19 @@ TableRow qA, qS; QDate pd; - qA["id"] = qS["id"] = (* it_transaction).id(); - qA["entrydate"] = qS["entrydate"] = (* it_transaction).entryDate().toString(Qt::ISODate); - qA["postdate"] = qS["postdate"] = (* it_transaction).postDate().toString(Qt::ISODate); - qA["commodity"] = qS["commodity"] = (* it_transaction).commodity(); + qA[ctID] = qS[ctID] = (* it_transaction).id(); + qA[ctEntryDate] = qS[ctEntryDate] = (* it_transaction).entryDate().toString(Qt::ISODate); + qA[ctPostDate] = qS[ctPostDate] = (* it_transaction).postDate().toString(Qt::ISODate); + qA[ctCommodity] = qS[ctCommodity] = (* it_transaction).commodity(); pd = (* it_transaction).postDate(); - qA["month"] = qS["month"] = i18n("Month of %1", QDate(pd.year(), pd.month(), 1).toString(Qt::ISODate)); - qA["week"] = qS["week"] = i18n("Week of %1", pd.addDays(1 - pd.dayOfWeek()).toString(Qt::ISODate)); + qA[ctMonth] = qS[ctMonth] = i18n("Month of %1", QDate(pd.year(), pd.month(), 1).toString(Qt::ISODate)); + qA[ctWeek] = qS[ctWeek] = i18n("Week of %1", pd.addDays(1 - pd.dayOfWeek()).toString(Qt::ISODate)); if (report.isConvertCurrency()) - qA["currency"] = qS["currency"] = file->baseCurrency().id(); + qA[ctCurrency] = qS[ctCurrency] = file->baseCurrency().id(); else - qA["currency"] = qS["currency"] = (*it_transaction).commodity(); + qA[ctCurrency] = qS[ctCurrency] = (*it_transaction).commodity(); // to handle splits, we decide on which account to base the split // (a reference point or point of view so to speak). here we take the @@ -1855,8 +1877,8 @@ ReportAccount myBeginAcc = (*myBegin).accountId(); bool include_me = true; - QString a_fullname = ""; - QString a_memo = ""; + QString a_fullname; + QString a_memo; int pass = 1; do { @@ -1892,71 +1914,71 @@ institution = splitAcc.parent().institutionId(); MyMoneyMoney shares = (*it_split).shares(); int pricePrecision = file->security(splitAcc.currencyId()).pricePrecision(); - qA["action"] = (*it_split).action(); - qA["shares"] = shares.isZero() ? "" : (*it_split).shares().toString(); - qA["price"] = shares.isZero() ? "" : xr.convertPrecision(pricePrecision).toString(); + qA[ctAction] = (*it_split).action(); + qA[ctShares] = shares.isZero() ? QString() : (*it_split).shares().toString(); + qA[ctPrice] = shares.isZero() ? QString() : xr.convertPrecision(pricePrecision).toString(); if (((*it_split).action() == MyMoneySplit::ActionBuyShares) && (*it_split).shares().isNegative()) - qA["action"] = "Sell"; + qA[ctAction] = "Sell"; - qA["investaccount"] = splitAcc.parent().name(); + qA[ctInvestAccount] = splitAcc.parent().name(); } include_me = m_config.includes(splitAcc); a_fullname = splitAcc.fullName(); a_memo = (*it_split).memo(); int pricePrecision = file->security(splitAcc.currencyId()).pricePrecision(); - qA["price"] = xr.convertPrecision(pricePrecision).toString(); - qA["account"] = splitAcc.name(); - qA["accountid"] = splitAcc.id(); - qA["topaccount"] = splitAcc.topParentName(); + qA[ctPrice] = xr.convertPrecision(pricePrecision).toString(); + qA[ctAccount] = splitAcc.name(); + qA[ctAccountID] = splitAcc.id(); + qA[ctTopAccount] = splitAcc.topParentName(); - qA["institution"] = institution.isEmpty() + qA[ctInstitution] = institution.isEmpty() ? i18n("No Institution") : file->institution(institution).name(); //FIXME-ALEX Is this useless? Isn't constructSplitsTable called only for cashflow type report? - QString delimiter = ""; - for (int i = 0; i < tagIdList.size(); i++) { - qA["tag"] += delimiter + file->tag(tagIdList[i]).name().simplified(); - delimiter = ','; + QString delimiter; + foreach(const auto tagId, tagIdList) { + qA[ctTag] += delimiter + file->tag(tagId).name().simplified(); + delimiter = QLatin1Char(','); } - qA["payee"] = payee.isEmpty() + qA[ctPayee] = payee.isEmpty() ? i18n("[Empty Payee]") : file->payee(payee).name().simplified(); - qA["reconciledate"] = (*it_split).reconcileDate().toString(Qt::ISODate); - qA["reconcileflag"] = KMyMoneyUtils::reconcileStateToString((*it_split).reconcileFlag(), true); - qA["number"] = (*it_split).number(); + qA[ctReconcileDate] = (*it_split).reconcileDate().toString(Qt::ISODate); + qA[ctReconcileFlag] = KMyMoneyUtils::reconcileStateToString((*it_split).reconcileFlag(), true); + qA[ctNumber] = (*it_split).number(); - qA["memo"] = a_memo; + qA[ctMemo] = a_memo; - qS["reconciledate"] = qA["reconciledate"]; - qS["reconcileflag"] = qA["reconcileflag"]; - qS["number"] = qA["number"]; + qS[ctReconcileDate] = qA[ctReconcileDate]; + qS[ctReconcileFlag] = qA[ctReconcileFlag]; + qS[ctNumber] = qA[ctNumber]; - qS["topcategory"] = splitAcc.topParentName(); + qS[ctTopCategory] = splitAcc.topParentName(); // only include the configured accounts if (include_me) { // add the "summarized" split transaction // this is the sub-total of the split detail // convert to lowest fraction - qA["value"] = ((*it_split).shares() * xr).convert(fraction).toString(); - qA["rank"] = '1'; + qA[ctValue] = ((*it_split).shares() * xr).convert(fraction).toString(); + qA[ctRank] = QLatin1Char('1'); //fill in account information if (! splitAcc.isIncomeExpense() && it_split != myBegin) { - qA["account"] = ((*it_split).shares().isNegative()) ? + qA[ctAccount] = ((*it_split).shares().isNegative()) ? i18n("Transfer to %1", myBeginAcc.fullName()) : i18n("Transfer from %1", myBeginAcc.fullName()); } else if (it_split == myBegin) { //handle the main split if ((splits.count() > 2)) { //if it is the main split and has multiple splits, note that - qA["account"] = i18n("[Split Transaction]"); + qA[ctAccount] = i18n("[Split Transaction]"); } else { //fill the account name of the second split QList::const_iterator tempSplit = splits.constBegin(); @@ -1968,22 +1990,22 @@ //show the name of the category, or "transfer to/from" if it as an account ReportAccount tempSplitAcc = (*tempSplit).accountId(); if (! tempSplitAcc.isIncomeExpense()) { - qA["account"] = ((*it_split).shares().isNegative()) ? + qA[ctAccount] = ((*it_split).shares().isNegative()) ? i18n("Transfer to %1", tempSplitAcc.fullName()) : i18n("Transfer from %1", tempSplitAcc.fullName()); } else { - qA["account"] = tempSplitAcc.fullName(); + qA[ctAccount] = tempSplitAcc.fullName(); } } } else { //in any other case, fill in the account name of the main split - qA["account"] = myBeginAcc.fullName(); + qA[ctAccount] = myBeginAcc.fullName(); } //category data is always the one of the split - qA ["category"] = splitAcc.fullName(); - qA ["topcategory"] = splitAcc.topParentName(); - qA ["categorytype"] = KMyMoneyUtils::accountTypeToString(splitAcc.accountGroup()); + qA [ctCategory] = splitAcc.fullName(); + qA [ctTopCategory] = splitAcc.topParentName(); + qA [ctCategoryType] = KMyMoneyUtils::accountTypeToString(splitAcc.accountGroup()); m_rows += qA; @@ -2072,39 +2094,39 @@ //starting balance // don't show currency if we're converting or if it's not foreign if (m_config.isConvertCurrency()) - qA["currency"] = file->baseCurrency().id(); + qA[ctCurrency] = file->baseCurrency().id(); else - qA["currency"] = account.currency().id(); + qA[ctCurrency] = account.currency().id(); - qA["accountid"] = account.id(); - qA["account"] = account.name(); - qA["topaccount"] = account.topParentName(); - qA["institution"] = institution.isEmpty() ? i18n("No Institution") : file->institution(institution).name(); - qA["rank"] = "0"; + qA[ctAccountID] = account.id(); + qA[ctAccount] = account.name(); + qA[ctTopAccount] = account.topParentName(); + qA[ctInstitution] = institution.isEmpty() ? i18n("No Institution") : file->institution(institution).name(); + qA[ctRank] = QLatin1Char('0'); int pricePrecision = file->security(account.currencyId()).pricePrecision(); - qA["price"] = startPrice.convertPrecision(pricePrecision).toString(); + qA[ctPrice] = startPrice.convertPrecision(pricePrecision).toString(); if (account.isInvest()) { - qA["shares"] = startShares.toString(); + qA[ctShares] = startShares.toString(); } - qA["postdate"] = strStartDate; - qA["balance"] = startBalance.convert(fraction).toString(); - qA["value"].clear(); - qA["id"] = 'A'; + qA[ctPostDate] = strStartDate; + qA[ctBalance] = startBalance.convert(fraction).toString(); + qA[ctValue].clear(); + qA[ctID] = QLatin1Char('A'); m_rows += qA; - qA["rank"] = "3"; + qA[ctRank] = QLatin1Char('3'); //ending balance - qA["price"] = endPrice.convertPrecision(pricePrecision).toString(); + qA[ctPrice] = endPrice.convertPrecision(pricePrecision).toString(); if (account.isInvest()) { - qA["shares"] = endShares.toString(); + qA[ctShares] = endShares.toString(); } - qA["postdate"] = strEndDate; - qA["balance"] = endBalance.toString(); - qA["id"] = 'Z'; + qA[ctPostDate] = strEndDate; + qA[ctBalance] = endBalance.toString(); + qA[ctID] = QLatin1Char('Z'); m_rows += qA; } } diff --git a/kmymoney/reports/tests/querytable-test.cpp b/kmymoney/reports/tests/querytable-test.cpp --- a/kmymoney/reports/tests/querytable-test.cpp +++ b/kmymoney/reports/tests/querytable-test.cpp @@ -111,18 +111,18 @@ QList rows = qtbl_1.rows(); QVERIFY(rows.count() == 19); - QVERIFY(rows[0]["categorytype"] == "Expense"); - QVERIFY(rows[0]["category"] == "Parent"); - QVERIFY(rows[0]["postdate"] == "2004-02-01"); - QVERIFY(rows[14]["categorytype"] == "Expense"); - QVERIFY(rows[14]["category"] == "Solo"); - QVERIFY(rows[14]["postdate"] == "2005-01-01"); - - QVERIFY(MyMoneyMoney(rows[6]["value"]) == -(moParent1 + moParent2) * 3); - QVERIFY(MyMoneyMoney(rows[10]["value"]) == -(moChild) * 3); - QVERIFY(MyMoneyMoney(rows[16]["value"]) == -(moSolo) * 3); - QVERIFY(MyMoneyMoney(rows[17]["value"]) == -(moParent1 + moParent2 + moSolo + moChild) * 3); - QVERIFY(MyMoneyMoney(rows[18]["value"]) == -(moParent1 + moParent2 + moSolo + moChild) * 3 + moCheckingOpen + moCreditOpen); + QVERIFY(rows[0][ListTable::ctCategoryType] == "Expense"); + QVERIFY(rows[0][ListTable::ctCategory] == "Parent"); + QVERIFY(rows[0][ListTable::ctPostDate] == "2004-02-01"); + QVERIFY(rows[14][ListTable::ctCategoryType] == "Expense"); + QVERIFY(rows[14][ListTable::ctCategory] == "Solo"); + QVERIFY(rows[14][ListTable::ctPostDate] == "2005-01-01"); + + QVERIFY(MyMoneyMoney(rows[6][ListTable::ctValue]) == -(moParent1 + moParent2) * 3); + QVERIFY(MyMoneyMoney(rows[10][ListTable::ctValue]) == -(moChild) * 3); + QVERIFY(MyMoneyMoney(rows[16][ListTable::ctValue]) == -(moSolo) * 3); + QVERIFY(MyMoneyMoney(rows[17][ListTable::ctValue]) == -(moParent1 + moParent2 + moSolo + moChild) * 3); + QVERIFY(MyMoneyMoney(rows[18][ListTable::ctValue]) == -(moParent1 + moParent2 + moSolo + moChild) * 3 + moCheckingOpen + moCreditOpen); filter.setRowType(MyMoneyReport::eTopCategory); cols = MyMoneyReport::eQCnumber | MyMoneyReport::eQCpayee | MyMoneyReport::eQCaccount; @@ -136,20 +136,20 @@ rows = qtbl_2.rows(); QVERIFY(rows.count() == 16); - QVERIFY(rows[0]["categorytype"] == "Expense"); - QVERIFY(rows[0]["topcategory"] == "Parent"); - QVERIFY(rows[0]["postdate"] == "2004-02-01"); - QVERIFY(rows[7]["categorytype"] == "Expense"); - QVERIFY(rows[7]["topcategory"] == "Parent"); - QVERIFY(rows[7]["postdate"] == "2005-09-01"); - QVERIFY(rows[12]["categorytype"] == "Expense"); - QVERIFY(rows[12]["topcategory"] == "Solo"); - QVERIFY(rows[12]["postdate"] == "2005-01-01"); - - QVERIFY(MyMoneyMoney(rows[9]["value"]) == -(moParent1 + moParent2 + moChild) * 3); - QVERIFY(MyMoneyMoney(rows[13]["value"]) == -(moSolo) * 3); - QVERIFY(MyMoneyMoney(rows[14]["value"]) == -(moParent1 + moParent2 + moSolo + moChild) * 3); - QVERIFY(MyMoneyMoney(rows[15]["value"]) == -(moParent1 + moParent2 + moSolo + moChild) * 3 + moCheckingOpen + moCreditOpen); + QVERIFY(rows[0][ListTable::ctCategoryType] == "Expense"); + QVERIFY(rows[0][ListTable::ctTopCategory] == "Parent"); + QVERIFY(rows[0][ListTable::ctPostDate] == "2004-02-01"); + QVERIFY(rows[8][ListTable::ctCategoryType] == "Expense"); + QVERIFY(rows[8][ListTable::ctTopCategory] == "Parent"); + QVERIFY(rows[8][ListTable::ctPostDate] == "2005-09-01"); + QVERIFY(rows[12][ListTable::ctCategoryType] == "Expense"); + QVERIFY(rows[12][ListTable::ctTopCategory] == "Solo"); + QVERIFY(rows[12][ListTable::ctPostDate] == "2005-01-01"); + + QVERIFY(MyMoneyMoney(rows[9][ListTable::ctValue]) == -(moParent1 + moParent2 + moChild) * 3); + QVERIFY(MyMoneyMoney(rows[13][ListTable::ctValue]) == -(moSolo) * 3); + QVERIFY(MyMoneyMoney(rows[14][ListTable::ctValue]) == -(moParent1 + moParent2 + moSolo + moChild) * 3); + QVERIFY(MyMoneyMoney(rows[15][ListTable::ctValue]) == -(moParent1 + moParent2 + moSolo + moChild) * 3 + moCheckingOpen + moCreditOpen); filter.setRowType(MyMoneyReport::eAccount); filter.setName("Transactions by Account"); @@ -164,25 +164,25 @@ #if 1 QVERIFY(rows.count() == 19); - QVERIFY(rows[1]["account"] == "Checking Account"); - QVERIFY(rows[1]["category"] == "Solo"); - QVERIFY(rows[1]["postdate"] == "2004-01-01"); - QVERIFY(rows[14]["account"] == "Credit Card"); - QVERIFY(rows[14]["category"] == "Parent"); - QVERIFY(rows[14]["postdate"] == "2005-09-01"); + QVERIFY(rows[1][ListTable::ctAccount] == "Checking Account"); + QVERIFY(rows[1][ListTable::ctCategory] == "Solo"); + QVERIFY(rows[1][ListTable::ctPostDate] == "2004-01-01"); + QVERIFY(rows[15][ListTable::ctAccount] == "Credit Card"); + QVERIFY(rows[15][ListTable::ctCategory] == "Parent"); + QVERIFY(rows[15][ListTable::ctPostDate] == "2005-09-01"); #else QVERIFY(rows.count() == 12); - QVERIFY(rows[0]["account"] == "Checking Account"); - QVERIFY(rows[0]["category"] == "Solo"); - QVERIFY(rows[0]["postdate"] == "2004-01-01"); - QVERIFY(rows[11]["account"] == "Credit Card"); - QVERIFY(rows[11]["category"] == "Parent"); - QVERIFY(rows[11]["postdate"] == "2005-09-01"); + QVERIFY(rows[0][ListTable::ctAccount] == "Checking Account"); + QVERIFY(rows[0][ListTable::ctCategory] == "Solo"); + QVERIFY(rows[0][ListTable::ctPostDate] == "2004-01-01"); + QVERIFY(rows[11][ListTable::ctAccount] == "Credit Card"); + QVERIFY(rows[11][ListTable::ctCategory] == "Parent"); + QVERIFY(rows[11][ListTable::ctPostDate] == "2005-09-01"); #endif - QVERIFY(MyMoneyMoney(rows[5]["value"]) == -(moSolo) * 3 + moCheckingOpen); - QVERIFY(MyMoneyMoney(rows[17]["value"]) == -(moParent1 + moParent2 + moChild) * 3 + moCreditOpen); - QVERIFY(MyMoneyMoney(rows[18]["value"]) == -(moParent1 + moParent2 + moSolo + moChild) * 3 + moCheckingOpen + moCreditOpen); + QVERIFY(MyMoneyMoney(rows[5][ListTable::ctValue]) == -(moSolo) * 3 + moCheckingOpen); + QVERIFY(MyMoneyMoney(rows[17][ListTable::ctValue]) == -(moParent1 + moParent2 + moChild) * 3 + moCreditOpen); + QVERIFY(MyMoneyMoney(rows[18][ListTable::ctValue]) == -(moParent1 + moParent2 + moSolo + moChild) * 3 + moCheckingOpen + moCreditOpen); filter.setRowType(MyMoneyReport::ePayee); filter.setName("Transactions by Payee"); @@ -196,18 +196,18 @@ rows = qtbl_4.rows(); QVERIFY(rows.count() == 14); - QVERIFY(rows[0]["payee"] == "Test Payee"); - QVERIFY(rows[0]["category"] == "Solo"); - QVERIFY(rows[0]["postdate"] == "2004-01-01"); - QVERIFY(rows[7]["payee"] == "Test Payee"); - QVERIFY(rows[7]["category"] == "Parent: Child"); - QVERIFY(rows[7]["postdate"] == "2004-11-07"); - QVERIFY(rows[10]["payee"] == "Test Payee"); - QVERIFY(rows[10]["category"] == "Parent"); - QVERIFY(rows[10]["postdate"] == "2005-09-01"); - - QVERIFY(MyMoneyMoney(rows[12]["value"]) == -(moParent1 + moParent2 + moSolo + moChild) * 3); - QVERIFY(MyMoneyMoney(rows[13]["value"]) == -(moParent1 + moParent2 + moSolo + moChild) * 3 + moCheckingOpen + moCreditOpen); + QVERIFY(rows[0][ListTable::ctPayee] == "Test Payee"); + QVERIFY(rows[0][ListTable::ctCategory] == "Solo"); + QVERIFY(rows[0][ListTable::ctPostDate] == "2004-01-01"); + QVERIFY(rows[7][ListTable::ctPayee] == "Test Payee"); + QVERIFY(rows[7][ListTable::ctCategory] == "Parent: Child"); + QVERIFY(rows[7][ListTable::ctPostDate] == "2004-11-07"); + QVERIFY(rows[11][ListTable::ctPayee] == "Test Payee"); + QVERIFY(rows[11][ListTable::ctCategory] == "Parent"); + QVERIFY(rows[11][ListTable::ctPostDate] == "2005-09-01"); + + QVERIFY(MyMoneyMoney(rows[12][ListTable::ctValue]) == -(moParent1 + moParent2 + moSolo + moChild) * 3); + QVERIFY(MyMoneyMoney(rows[13][ListTable::ctValue]) == -(moParent1 + moParent2 + moSolo + moChild) * 3 + moCheckingOpen + moCreditOpen); filter.setRowType(MyMoneyReport::eMonth); filter.setName("Transactions by Month"); @@ -221,20 +221,20 @@ rows = qtbl_5.rows(); QVERIFY(rows.count() == 23); - QVERIFY(rows[0]["payee"] == "Test Payee"); - QVERIFY(rows[0]["category"] == "Solo"); - QVERIFY(rows[0]["postdate"] == "2004-01-01"); - QVERIFY(rows[12]["payee"] == "Test Payee"); - QVERIFY(rows[12]["category"] == "Parent: Child"); - QVERIFY(rows[12]["postdate"] == "2004-11-07"); - QVERIFY(rows[20]["payee"] == "Test Payee"); - QVERIFY(rows[20]["category"] == "Parent"); - QVERIFY(rows[20]["postdate"] == "2005-09-01"); - - QVERIFY(MyMoneyMoney(rows[1]["value"]) == -moSolo); - QVERIFY(MyMoneyMoney(rows[15]["value"]) == -(moChild) * 3); - QVERIFY(MyMoneyMoney(rows[9]["value"]) == -moParent1 + moCheckingOpen); - QVERIFY(MyMoneyMoney(rows[22]["value"]) == -(moParent1 + moParent2 + moSolo + moChild) * 3 + moCheckingOpen + moCreditOpen); + QVERIFY(rows[0][ListTable::ctPayee] == "Test Payee"); + QVERIFY(rows[0][ListTable::ctCategory] == "Solo"); + QVERIFY(rows[0][ListTable::ctPostDate] == "2004-01-01"); + QVERIFY(rows[12][ListTable::ctPayee] == "Test Payee"); + QVERIFY(rows[12][ListTable::ctCategory] == "Parent: Child"); + QVERIFY(rows[12][ListTable::ctPostDate] == "2004-11-07"); + QVERIFY(rows[20][ListTable::ctPayee] == "Test Payee"); + QVERIFY(rows[20][ListTable::ctCategory] == "Parent"); + QVERIFY(rows[20][ListTable::ctPostDate] == "2005-09-01"); + + QVERIFY(MyMoneyMoney(rows[1][ListTable::ctValue]) == -moSolo); + QVERIFY(MyMoneyMoney(rows[15][ListTable::ctValue]) == -(moChild) * 3); + QVERIFY(MyMoneyMoney(rows[9][ListTable::ctValue]) == -moParent1 + moCheckingOpen); + QVERIFY(MyMoneyMoney(rows[22][ListTable::ctValue]) == -(moParent1 + moParent2 + moSolo + moChild) * 3 + moCheckingOpen + moCreditOpen); filter.setRowType(MyMoneyReport::eWeek); filter.setName("Transactions by Week"); @@ -248,34 +248,34 @@ rows = qtbl_6.rows(); QVERIFY(rows.count() == 23); - QVERIFY(rows[0]["payee"] == "Test Payee"); - QVERIFY(rows[0]["category"] == "Solo"); - QVERIFY(rows[0]["postdate"] == "2004-01-01"); - QVERIFY(rows[20]["payee"] == "Test Payee"); - QVERIFY(rows[20]["category"] == "Parent"); - QVERIFY(rows[20]["postdate"] == "2005-09-01"); - - QVERIFY(MyMoneyMoney(rows[1]["value"]) == -moSolo); - QVERIFY(MyMoneyMoney(rows[15]["value"]) == -(moChild) * 3); - QVERIFY(MyMoneyMoney(rows[21]["value"]) == -moParent2); - QVERIFY(MyMoneyMoney(rows[22]["value"]) == -(moParent1 + moParent2 + moSolo + moChild) * 3 + moCheckingOpen + moCreditOpen); + QVERIFY(rows[0][ListTable::ctPayee] == "Test Payee"); + QVERIFY(rows[0][ListTable::ctCategory] == "Solo"); + QVERIFY(rows[0][ListTable::ctPostDate] == "2004-01-01"); + QVERIFY(rows[20][ListTable::ctPayee] == "Test Payee"); + QVERIFY(rows[20][ListTable::ctCategory] == "Parent"); + QVERIFY(rows[20][ListTable::ctPostDate] == "2005-09-01"); + + QVERIFY(MyMoneyMoney(rows[1][ListTable::ctValue]) == -moSolo); + QVERIFY(MyMoneyMoney(rows[15][ListTable::ctValue]) == -(moChild) * 3); + QVERIFY(MyMoneyMoney(rows[21][ListTable::ctValue]) == -moParent2); + QVERIFY(MyMoneyMoney(rows[22][ListTable::ctValue]) == -(moParent1 + moParent2 + moSolo + moChild) * 3 + moCheckingOpen + moCreditOpen); } catch (const MyMoneyException &e) { QFAIL(qPrintable(e.what())); } // Test querytable::TableRow::operator> and operator== QueryTable::TableRow low; - low["first"] = 'A'; - low["second"] = 'B'; - low["third"] = 'C'; + low[ListTable::ctPrice] = 'A'; + low[ListTable::ctLastPrice] = 'B'; + low[ListTable::ctBuyPrice] = 'C'; QueryTable::TableRow high; - high["first"] = 'A'; - high["second"] = 'C'; - high["third"] = 'B'; + high[ListTable::ctPrice] = 'A'; + high[ListTable::ctLastPrice] = 'C'; + high[ListTable::ctBuyPrice] = 'B'; - QueryTable::TableRow::setSortCriteria("first,second,third"); + QueryTable::TableRow::setSortCriteria({ListTable::ctPrice, ListTable::ctLastPrice, ListTable::ctBuyPrice}); QVERIFY(low < high); QVERIFY(low <= high); QVERIFY(high > low); @@ -334,15 +334,15 @@ QList rows = qtbl_1.rows(); QVERIFY(rows.count() == 6); - QVERIFY(rows[0]["account"] == "Checking Account"); - QVERIFY(MyMoneyMoney(rows[0]["value"]) == moCheckingOpen); - QVERIFY(rows[0]["equitytype"].isEmpty()); - QVERIFY(rows[2]["account"] == "Credit Card"); - QVERIFY(MyMoneyMoney(rows[1]["value"]) == moCreditOpen); - QVERIFY(rows[2]["equitytype"].isEmpty()); + QVERIFY(rows[0][ListTable::ctAccount] == "Checking Account"); + QVERIFY(MyMoneyMoney(rows[0][ListTable::ctValue]) == moCheckingOpen); + QVERIFY(rows[0][ListTable::ctEquityType].isEmpty()); + QVERIFY(rows[2][ListTable::ctAccount] == "Credit Card"); + QVERIFY(MyMoneyMoney(rows[1][ListTable::ctValue]) == moCreditOpen); + QVERIFY(rows[2][ListTable::ctEquityType].isEmpty()); - QVERIFY(MyMoneyMoney(rows[4]["value"]) == moCheckingOpen + moCreditOpen); - QVERIFY(MyMoneyMoney(rows[5]["value"]) == moCheckingOpen + moCreditOpen); + QVERIFY(MyMoneyMoney(rows[4][ListTable::ctValue]) == moCheckingOpen + moCreditOpen); + QVERIFY(MyMoneyMoney(rows[5][ListTable::ctValue]) == moCheckingOpen + moCreditOpen); // // Adding in transactions @@ -371,12 +371,12 @@ rows = qtbl_2.rows(); QVERIFY(rows.count() == 6); - QVERIFY(rows[0]["account"] == "Checking Account"); - QVERIFY(MyMoneyMoney(rows[0]["value"]) == (moCheckingOpen - moSolo*3)); - QVERIFY(rows[2]["account"] == "Credit Card"); - QVERIFY(MyMoneyMoney(rows[2]["value"]) == (moCreditOpen - (moParent1 + moParent2 + moChild) * 3)); + QVERIFY(rows[0][ListTable::ctAccount] == "Checking Account"); + QVERIFY(MyMoneyMoney(rows[0][ListTable::ctValue]) == (moCheckingOpen - moSolo*3)); + QVERIFY(rows[2][ListTable::ctAccount] == "Credit Card"); + QVERIFY(MyMoneyMoney(rows[2][ListTable::ctValue]) == (moCreditOpen - (moParent1 + moParent2 + moChild) * 3)); - QVERIFY(MyMoneyMoney(rows[5]["value"]) == moCheckingOpen + moCreditOpen - (moParent1 + moParent2 + moSolo + moChild) * 3); + QVERIFY(MyMoneyMoney(rows[5][ListTable::ctValue]) == moCheckingOpen + moCreditOpen - (moParent1 + moParent2 + moSolo + moChild) * 3); // // Account TYPES @@ -390,14 +390,14 @@ rows = qtbl_3.rows(); QVERIFY(rows.count() == 5); - QVERIFY(rows[0]["account"] == "Checking Account"); - QVERIFY(MyMoneyMoney(rows[0]["value"]) == (moCheckingOpen - moSolo * 3)); - QVERIFY(rows[2]["account"] == "Credit Card"); - QVERIFY(MyMoneyMoney(rows[2]["value"]) == (moCreditOpen - (moParent1 + moParent2 + moChild) * 3)); - - QVERIFY(MyMoneyMoney(rows[1]["value"]) == moCheckingOpen - moSolo * 3); - QVERIFY(MyMoneyMoney(rows[3]["value"]) == moCreditOpen - (moParent1 + moParent2 + moChild) * 3); - QVERIFY(MyMoneyMoney(rows[4]["value"]) == moCheckingOpen + moCreditOpen - (moParent1 + moParent2 + moSolo + moChild) * 3); + QVERIFY(rows[0][ListTable::ctAccount] == "Checking Account"); + QVERIFY(MyMoneyMoney(rows[0][ListTable::ctValue]) == (moCheckingOpen - moSolo * 3)); + QVERIFY(rows[2][ListTable::ctAccount] == "Credit Card"); + QVERIFY(MyMoneyMoney(rows[2][ListTable::ctValue]) == (moCreditOpen - (moParent1 + moParent2 + moChild) * 3)); + + QVERIFY(MyMoneyMoney(rows[1][ListTable::ctValue]) == moCheckingOpen - moSolo * 3); + QVERIFY(MyMoneyMoney(rows[3][ListTable::ctValue]) == moCreditOpen - (moParent1 + moParent2 + moChild) * 3); + QVERIFY(MyMoneyMoney(rows[4][ListTable::ctValue]) == moCheckingOpen + moCreditOpen - (moParent1 + moParent2 + moSolo + moChild) * 3); } catch (const MyMoneyException &e) { QFAIL(qPrintable(e.what())); } @@ -465,78 +465,78 @@ QList rows = invtran.rows(); QVERIFY(rows.count() == 32); - QVERIFY(MyMoneyMoney(rows[1]["value"]) == MyMoneyMoney(-100000.00)); - QVERIFY(MyMoneyMoney(rows[2]["value"]) == MyMoneyMoney(-110000.00)); - QVERIFY(MyMoneyMoney(rows[3]["value"]) == MyMoneyMoney(24000.00)); - QVERIFY(MyMoneyMoney(rows[4]["value"]) == MyMoneyMoney(20000.00)); - QVERIFY(MyMoneyMoney(rows[5]["value"]) == MyMoneyMoney(5000.00)); - QVERIFY(MyMoneyMoney(rows[6]["value"]) == MyMoneyMoney(4000.00)); - QVERIFY(MyMoneyMoney(rows[19]["value"]) == MyMoneyMoney(-50100.00)); - QVERIFY(MyMoneyMoney(rows[22]["value"]) == MyMoneyMoney(-45100.00)); + QVERIFY(MyMoneyMoney(rows[1][ListTable::ctValue]) == MyMoneyMoney(-100000.00)); + QVERIFY(MyMoneyMoney(rows[2][ListTable::ctValue]) == MyMoneyMoney(-110000.00)); + QVERIFY(MyMoneyMoney(rows[3][ListTable::ctValue]) == MyMoneyMoney(24000.00)); + QVERIFY(MyMoneyMoney(rows[4][ListTable::ctValue]) == MyMoneyMoney(20000.00)); + QVERIFY(MyMoneyMoney(rows[5][ListTable::ctValue]) == MyMoneyMoney(5000.00)); + QVERIFY(MyMoneyMoney(rows[6][ListTable::ctValue]) == MyMoneyMoney(4000.00)); + QVERIFY(MyMoneyMoney(rows[19][ListTable::ctValue]) == MyMoneyMoney(-50100.00)); + QVERIFY(MyMoneyMoney(rows[22][ListTable::ctValue]) == MyMoneyMoney(-45100.00)); // need to fix these... fundamentally different from the original test - //QVERIFY(MyMoneyMoney(invtran.m_rows[8]["value"])==MyMoneyMoney( -1000.00)); - //QVERIFY(MyMoneyMoney(invtran.m_rows[11]["value"])==MyMoneyMoney( -1200.00)); - //QVERIFY(MyMoneyMoney(invtran.m_rows[14]["value"])==MyMoneyMoney( -1100.00)); - - QVERIFY(MyMoneyMoney(rows[1]["price"]) == MyMoneyMoney(100.00)); - QVERIFY(MyMoneyMoney(rows[3]["price"]) == MyMoneyMoney(120.00)); - QVERIFY(MyMoneyMoney(rows[5]["price"]) == MyMoneyMoney(100.00)); - QVERIFY(MyMoneyMoney(rows[7]["price"]) == MyMoneyMoney()); - QVERIFY(MyMoneyMoney(rows[10]["price"]) == MyMoneyMoney()); - QVERIFY(MyMoneyMoney(rows[19]["price"]) == MyMoneyMoney(100.00)); - QVERIFY(MyMoneyMoney(rows[22]["price"]) == MyMoneyMoney(90.00)); - - QVERIFY(MyMoneyMoney(rows[2]["shares"]) == MyMoneyMoney(1000.00)); - QVERIFY(MyMoneyMoney(rows[4]["shares"]) == MyMoneyMoney(-200.00)); - QVERIFY(MyMoneyMoney(rows[6]["shares"]) == MyMoneyMoney(50.00)); - QVERIFY(MyMoneyMoney(rows[8]["shares"]) == MyMoneyMoney(0.00)); - QVERIFY(MyMoneyMoney(rows[11]["shares"]) == MyMoneyMoney(0.00)); - QVERIFY(MyMoneyMoney(rows[19]["shares"]) == MyMoneyMoney(500.00)); - QVERIFY(MyMoneyMoney(rows[22]["shares"]) == MyMoneyMoney(500.00)); - - QVERIFY(rows[1]["action"] == "Buy"); - QVERIFY(rows[3]["action"] == "Sell"); - QVERIFY(rows[5]["action"] == "Reinvest"); - QVERIFY(rows[7]["action"] == "Dividend"); - QVERIFY(rows[13]["action"] == "Yield"); - QVERIFY(rows[19]["action"] == "Buy"); - QVERIFY(rows[22]["action"] == "Buy"); + //QVERIFY(MyMoneyMoney(invtran.m_rows[8][ListTable::ctValue])==MyMoneyMoney( -1000.00)); + //QVERIFY(MyMoneyMoney(invtran.m_rows[11][ListTable::ctValue])==MyMoneyMoney( -1200.00)); + //QVERIFY(MyMoneyMoney(invtran.m_rows[14][ListTable::ctValue])==MyMoneyMoney( -1100.00)); + + QVERIFY(MyMoneyMoney(rows[1][ListTable::ctPrice]) == MyMoneyMoney(100.00)); + QVERIFY(MyMoneyMoney(rows[3][ListTable::ctPrice]) == MyMoneyMoney(120.00)); + QVERIFY(MyMoneyMoney(rows[5][ListTable::ctPrice]) == MyMoneyMoney(100.00)); + QVERIFY(MyMoneyMoney(rows[7][ListTable::ctPrice]) == MyMoneyMoney()); + QVERIFY(MyMoneyMoney(rows[10][ListTable::ctPrice]) == MyMoneyMoney()); + QVERIFY(MyMoneyMoney(rows[19][ListTable::ctPrice]) == MyMoneyMoney(100.00)); + QVERIFY(MyMoneyMoney(rows[22][ListTable::ctPrice]) == MyMoneyMoney(90.00)); + + QVERIFY(MyMoneyMoney(rows[2][ListTable::ctShares]) == MyMoneyMoney(1000.00)); + QVERIFY(MyMoneyMoney(rows[4][ListTable::ctShares]) == MyMoneyMoney(-200.00)); + QVERIFY(MyMoneyMoney(rows[6][ListTable::ctShares]) == MyMoneyMoney(50.00)); + QVERIFY(MyMoneyMoney(rows[8][ListTable::ctShares]) == MyMoneyMoney(0.00)); + QVERIFY(MyMoneyMoney(rows[11][ListTable::ctShares]) == MyMoneyMoney(0.00)); + QVERIFY(MyMoneyMoney(rows[19][ListTable::ctShares]) == MyMoneyMoney(500.00)); + QVERIFY(MyMoneyMoney(rows[22][ListTable::ctShares]) == MyMoneyMoney(500.00)); + + QVERIFY(rows[1][ListTable::ctAction] == "Buy"); + QVERIFY(rows[3][ListTable::ctAction] == "Sell"); + QVERIFY(rows[5][ListTable::ctAction] == "Reinvest"); + QVERIFY(rows[7][ListTable::ctAction] == "Dividend"); + QVERIFY(rows[13][ListTable::ctAction] == "Yield"); + QVERIFY(rows[19][ListTable::ctAction] == "Buy"); + QVERIFY(rows[22][ListTable::ctAction] == "Buy"); #else QVERIFY(rows.count() == 9); - QVERIFY(MyMoneyMoney(rows[0]["value"]) == MyMoneyMoney(100000.00)); - QVERIFY(MyMoneyMoney(rows[1]["value"]) == MyMoneyMoney(110000.00)); - QVERIFY(MyMoneyMoney(rows[2]["value"]) == MyMoneyMoney(-24000.00)); - QVERIFY(MyMoneyMoney(rows[3]["value"]) == MyMoneyMoney(-20000.00)); - QVERIFY(MyMoneyMoney(rows[4]["value"]) == MyMoneyMoney(5000.00)); - QVERIFY(MyMoneyMoney(rows[5]["value"]) == MyMoneyMoney(4000.00)); - QVERIFY(MyMoneyMoney(rows[6]["value"]) == MyMoneyMoney(-1000.00)); - QVERIFY(MyMoneyMoney(rows[7]["value"]) == MyMoneyMoney(-1200.00)); - QVERIFY(MyMoneyMoney(rows[8]["value"]) == MyMoneyMoney(-1100.00)); - - QVERIFY(MyMoneyMoney(rows[0]["price"]) == MyMoneyMoney(100.00)); - QVERIFY(MyMoneyMoney(rows[2]["price"]) == MyMoneyMoney(120.00)); - QVERIFY(MyMoneyMoney(rows[4]["price"]) == MyMoneyMoney(100.00)); - QVERIFY(MyMoneyMoney(rows[6]["price"]) == MyMoneyMoney(0.00)); - QVERIFY(MyMoneyMoney(rows[8]["price"]) == MyMoneyMoney(0.00)); - - QVERIFY(MyMoneyMoney(rows[1]["shares"]) == MyMoneyMoney(1000.00)); - QVERIFY(MyMoneyMoney(rows[3]["shares"]) == MyMoneyMoney(-200.00)); - QVERIFY(MyMoneyMoney(rows[5]["shares"]) == MyMoneyMoney(50.00)); - QVERIFY(MyMoneyMoney(rows[7]["shares"]) == MyMoneyMoney(0.00)); - QVERIFY(MyMoneyMoney(rows[8]["shares"]) == MyMoneyMoney(0.00)); - - QVERIFY(rows[0]["action"] == "Buy"); - QVERIFY(rows[2]["action"] == "Sell"); - QVERIFY(rows[4]["action"] == "Reinvest"); - QVERIFY(rows[6]["action"] == "Dividend"); - QVERIFY(rows[8]["action"] == "Yield"); + QVERIFY(MyMoneyMoney(rows[0][ListTable::ctValue]) == MyMoneyMoney(100000.00)); + QVERIFY(MyMoneyMoney(rows[1][ListTable::ctValue]) == MyMoneyMoney(110000.00)); + QVERIFY(MyMoneyMoney(rows[2][ListTable::ctValue]) == MyMoneyMoney(-24000.00)); + QVERIFY(MyMoneyMoney(rows[3][ListTable::ctValue]) == MyMoneyMoney(-20000.00)); + QVERIFY(MyMoneyMoney(rows[4][ListTable::ctValue]) == MyMoneyMoney(5000.00)); + QVERIFY(MyMoneyMoney(rows[5][ListTable::ctValue]) == MyMoneyMoney(4000.00)); + QVERIFY(MyMoneyMoney(rows[6][ListTable::ctValue]) == MyMoneyMoney(-1000.00)); + QVERIFY(MyMoneyMoney(rows[7][ListTable::ctValue]) == MyMoneyMoney(-1200.00)); + QVERIFY(MyMoneyMoney(rows[8][ListTable::ctValue]) == MyMoneyMoney(-1100.00)); + + QVERIFY(MyMoneyMoney(rows[0][ListTable::ctPrice]) == MyMoneyMoney(100.00)); + QVERIFY(MyMoneyMoney(rows[2][ListTable::ctPrice]) == MyMoneyMoney(120.00)); + QVERIFY(MyMoneyMoney(rows[4][ListTable::ctPrice]) == MyMoneyMoney(100.00)); + QVERIFY(MyMoneyMoney(rows[6][ListTable::ctPrice]) == MyMoneyMoney(0.00)); + QVERIFY(MyMoneyMoney(rows[8][ListTable::ctPrice]) == MyMoneyMoney(0.00)); + + QVERIFY(MyMoneyMoney(rows[1][ListTable::ctShares]) == MyMoneyMoney(1000.00)); + QVERIFY(MyMoneyMoney(rows[3][ListTable::ctShares]) == MyMoneyMoney(-200.00)); + QVERIFY(MyMoneyMoney(rows[5][ListTable::ctShares]) == MyMoneyMoney(50.00)); + QVERIFY(MyMoneyMoney(rows[7][ListTable::ctShares]) == MyMoneyMoney(0.00)); + QVERIFY(MyMoneyMoney(rows[8][ListTable::ctShares]) == MyMoneyMoney(0.00)); + + QVERIFY(rows[0][ListTable::ctAction] == "Buy"); + QVERIFY(rows[2][ListTable::ctAction] == "Sell"); + QVERIFY(rows[4][ListTable::ctAction] == "Reinvest"); + QVERIFY(rows[6][ListTable::ctAction] == "Dividend"); + QVERIFY(rows[8][ListTable::ctAction] == "Yield"); #endif #if 1 // i think this is the correct amount. different treatment of dividend and yield - QVERIFY(MyMoneyMoney(rows[17]["value"]) == MyMoneyMoney(-153700.00)); - QVERIFY(MyMoneyMoney(rows[29]["value"]) == MyMoneyMoney(24600.00)); - QVERIFY(MyMoneyMoney(rows[31]["value"]) == MyMoneyMoney(-129100.00)); + QVERIFY(MyMoneyMoney(rows[17][ListTable::ctValue]) == MyMoneyMoney(-153700.00)); + QVERIFY(MyMoneyMoney(rows[29][ListTable::ctValue]) == MyMoneyMoney(24600.00)); + QVERIFY(MyMoneyMoney(rows[31][ListTable::ctValue]) == MyMoneyMoney(-129100.00)); #else QVERIFY(searchHTML(html, i18n("Total Stock 1")) == MyMoneyMoney(171700.00)); QVERIFY(searchHTML(html, i18n("Grand Total")) == MyMoneyMoney(171700.00)); @@ -564,24 +564,24 @@ rows = invhold.rows(); QVERIFY(rows.count() == 5); - QVERIFY(MyMoneyMoney(rows[0]["return"]) == MyMoneyMoney("669/10000")); - QVERIFY(MyMoneyMoney(rows[0]["returninvestment"]) == MyMoneyMoney("-39/5000")); - QVERIFY(MyMoneyMoney(rows[0]["buys"]) == MyMoneyMoney(-210000.00)); - QVERIFY(MyMoneyMoney(rows[0]["sells"]) == MyMoneyMoney(44000.00)); - QVERIFY(MyMoneyMoney(rows[0]["reinvestincome"]) == MyMoneyMoney(9000.00)); - QVERIFY(MyMoneyMoney(rows[0]["cashincome"]) == MyMoneyMoney(3300.00)); + QVERIFY(MyMoneyMoney(rows[0][ListTable::ctReturn]) == MyMoneyMoney("669/10000")); + QVERIFY(MyMoneyMoney(rows[0][ListTable::ctReturnInvestment]) == MyMoneyMoney("-39/5000")); + QVERIFY(MyMoneyMoney(rows[0][ListTable::ctBuys]) == MyMoneyMoney(-210000.00)); + QVERIFY(MyMoneyMoney(rows[0][ListTable::ctSells]) == MyMoneyMoney(44000.00)); + QVERIFY(MyMoneyMoney(rows[0][ListTable::ctReinvestIncome]) == MyMoneyMoney(9000.00)); + QVERIFY(MyMoneyMoney(rows[0][ListTable::ctCashIncome]) == MyMoneyMoney(3300.00)); - QVERIFY(MyMoneyMoney(rows[1]["return"]) == MyMoneyMoney("1349/10000")); - QVERIFY(MyMoneyMoney(rows[1]["returninvestment"]) == MyMoneyMoney("1/10")); - QVERIFY(MyMoneyMoney(rows[1]["startingbal"]) == MyMoneyMoney(100000.00)); // this should stay non-zero to check if investment performance is calculated at non-zero starting balance + QVERIFY(MyMoneyMoney(rows[1][ListTable::ctReturn]) == MyMoneyMoney("1349/10000")); + QVERIFY(MyMoneyMoney(rows[1][ListTable::ctReturnInvestment]) == MyMoneyMoney("1/10")); + QVERIFY(MyMoneyMoney(rows[1][ListTable::ctStartingBalance]) == MyMoneyMoney(100000.00)); // this should stay non-zero to check if investment performance is calculated at non-zero starting balance - QVERIFY(MyMoneyMoney(rows[2]["return"]) == MyMoneyMoney("2501/2500")); - QVERIFY(MyMoneyMoney(rows[2]["returninvestment"]) == MyMoneyMoney("323/1250")); - QVERIFY(MyMoneyMoney(rows[2]["buys"]) == MyMoneyMoney(-95200.00)); - QVERIFY(MyMoneyMoney(rows[2]["sells"]) == MyMoneyMoney(119800.00)); - QVERIFY(MyMoneyMoney(rows[2]["endingbal"]) == MyMoneyMoney(0.00)); // this should stay zero to check if investment performance is calculated at zero ending balance + QVERIFY(MyMoneyMoney(rows[2][ListTable::ctReturn]) == MyMoneyMoney("2501/2500")); + QVERIFY(MyMoneyMoney(rows[2][ListTable::ctReturnInvestment]) == MyMoneyMoney("323/1250")); + QVERIFY(MyMoneyMoney(rows[2][ListTable::ctBuys]) == MyMoneyMoney(-95200.00)); + QVERIFY(MyMoneyMoney(rows[2][ListTable::ctSells]) == MyMoneyMoney(119800.00)); + QVERIFY(MyMoneyMoney(rows[2][ListTable::ctEndingBalance]) == MyMoneyMoney(0.00)); // this should stay zero to check if investment performance is calculated at zero ending balance - QVERIFY(MyMoneyMoney(rows[4]["endingbal"]) == MyMoneyMoney(280000.00)); + QVERIFY(MyMoneyMoney(rows[4][ListTable::ctEndingBalance]) == MyMoneyMoney(280000.00)); #if 0 // Dump file & reports @@ -732,7 +732,7 @@ QVERIFY(html.indexOf("" + closingDateString + "Test PayeeTransfer from Credit CardUSD 100.00USD 304.00") > 0); // a 100.00 JPY withdrawal should be displayed as such even if the expense account uses another currency - QVERIFY(html.indexOf("" + intermediateDateString + "Test PayeeSoloJPY -100.00JPY -400.00") > 0); + QVERIFY(html.indexOf("" + intermediateDateString + "Test PayeeSoloJPY -100.00JPY -300.00") > 0); // now run the same report again but this time convert all values to the base currency and make sure the values are correct filter.setConvertCurrency(true); @@ -761,10 +761,10 @@ QVERIFY(html.indexOf("" + intermediateDateString + "Test PayeeTransfer to Checking Account -1.00 -2.00") > 0); // a 100.00 JPY transfer should be displayed as -2.00 when converted to the base currency using the closing date price (notice the balance is -5.00) - QVERIFY(html.indexOf("" + closingDateString + "Test PayeeTransfer to Checking Account -2.00 -4.00") > 0); + QVERIFY(html.indexOf("" + closingDateString + "Test PayeeTransfer to Checking Account -2.00 -5.00") > 0); // a 100.00 JPY withdrawal should be displayed as -1.00 when converted to the base currency using the intermediate date price - QVERIFY(html.indexOf("" + intermediateDateString + "Test PayeeSolo -1.00 -5.00") > 0); + QVERIFY(html.indexOf("" + intermediateDateString + "Test PayeeSolo -1.00 -3.00") > 0); } catch (const MyMoneyException &e) { QFAIL(qPrintable(e.what()));