diff --git a/kmymoney/plugins/views/reports/core/querytable.cpp b/kmymoney/plugins/views/reports/core/querytable.cpp --- a/kmymoney/plugins/views/reports/core/querytable.cpp +++ b/kmymoney/plugins/views/reports/core/querytable.cpp @@ -358,9 +358,11 @@ 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)); - 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) + else if (subtotal == ctPercentageGain) { + const MyMoneyMoney denominator = (*currencyGrp).at(i + 1).value(ctBuys).abs(); + totalsRow[subtotal] = denominator.isZero() ? QString(): + (((*currencyGrp).at(i + 1).value(ctBuys) + (*currencyGrp).at(i + 1).value(ctMarketValue)) / denominator).toString(); + } else if (subtotal == ctPrice) totalsRow[subtotal] = MyMoneyMoney((*currencyGrp).at(i + 1).value(ctPrice) / (*currencyGrp).at(i + 1).value(ctRowsCount)).toString(); } @@ -1057,7 +1059,7 @@ QString QueryTable::helperROI(const MyMoneyMoney &buys, const MyMoneyMoney &sells, const MyMoneyMoney &startingBal, const MyMoneyMoney &endingBal, const MyMoneyMoney &cashIncome) const { MyMoneyMoney returnInvestment; - if (!buys.isZero() || !startingBal.isZero()) { + if (!(startingBal - buys).isZero()) { returnInvestment = (sells + buys + cashIncome + endingBal - startingBal) / (startingBal - buys); return returnInvestment.convert(10000).toString(); } else @@ -1456,7 +1458,8 @@ result[ctLastPrice] = price.toString(); result[ctMarketValue] = endingBal.toString(); result[ctCapitalGain] = (buysTotal + endingBal).toString(); - result[ctPercentageGain] = ((buysTotal + endingBal)/buysTotal.abs()).toString(); + result[ctPercentageGain] = buysTotal.isZero() ? QString() : + ((buysTotal + endingBal)/buysTotal.abs()).toString(); break; } case eMyMoney::Report::InvestmentSum::Sold: diff --git a/kmymoney/plugins/views/reports/core/tests/querytable-test.h b/kmymoney/plugins/views/reports/core/tests/querytable-test.h --- a/kmymoney/plugins/views/reports/core/tests/querytable-test.h +++ b/kmymoney/plugins/views/reports/core/tests/querytable-test.h @@ -43,6 +43,7 @@ void testBalanceColumn(); void testBalanceColumnWithMultipleCurrencies(); void testTaxReport(); + void testProtectedMethods(); }; #endif diff --git a/kmymoney/plugins/views/reports/core/tests/querytable-test.cpp b/kmymoney/plugins/views/reports/core/tests/querytable-test.cpp --- a/kmymoney/plugins/views/reports/core/tests/querytable-test.cpp +++ b/kmymoney/plugins/views/reports/core/tests/querytable-test.cpp @@ -975,3 +975,31 @@ QFAIL(e.what()); } } + +class QueryTableProtectedTester : QueryTable { +public: + QueryTableProtectedTester(): QueryTable(MyMoneyReport(eMyMoney::Report::RowType::Account, + static_cast(eMyMoney::Report::ColumnType::Months), + eMyMoney::TransactionFilter::Date::YearToDate, + eMyMoney::Report::DetailLevel::Top, + "Yearly Budgeted vs. Actual", "Default Report")) {} + + void testHelperROI() { + // (10 + 50 - 110 + 60 + 70) / (110 - 10) + QString result1 = helperROI(MyMoneyMoney(10), MyMoneyMoney(50), MyMoneyMoney(110), MyMoneyMoney(60), MyMoneyMoney(70)); + QVERIFY(MyMoneyMoney(result1) == MyMoneyMoney(80, 100)); + + // (110 + 50 - 110 + 60 + 70) / (110 - 110) + QString result2 = helperROI(MyMoneyMoney(110), MyMoneyMoney(50), MyMoneyMoney(110), MyMoneyMoney(60), MyMoneyMoney(70)); + QVERIFY(result2 == ""); + } +}; + +void QueryTableTest::testProtectedMethods() +{ + try { + QueryTableProtectedTester().testHelperROI(); + } catch (const MyMoneyException &e) { + QFAIL(e.what()); + } +}