diff --git a/kmymoney/reports/tests/pivottable-test.cpp b/kmymoney/reports/tests/pivottable-test.cpp index f43e83985..f6dd4df6b 100644 --- a/kmymoney/reports/tests/pivottable-test.cpp +++ b/kmymoney/reports/tests/pivottable-test.cpp @@ -1,1078 +1,1077 @@ /*************************************************************************** pivottabletest.cpp ------------------- copyright : (C) 2002-2005 by Thomas Baumgart email : ipwizard@users.sourceforge.net Ace Jones ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "pivottable-test.h" #include #include #include #include // DOH, mmreport.h uses this without including it!! #include "mymoneyinstitution.h" #include "mymoneyaccount.h" #include "mymoneysecurity.h" #include "mymoneyprice.h" #include "mymoneyreport.h" #include "mymoneystatement.h" #include "mymoneysplit.h" #include "mymoneypayee.h" #include "mymoneyexception.h" #include "mymoneystoragedump.h" #include "mymoneystoragexml.h" #include "mymoneyenums.h" #include "pivottable.h" #include "reportstestcommon.h" #include "kmymoneysettings.h" using namespace reports; using namespace test; QTEST_GUILESS_MAIN(PivotTableTest) void PivotTableTest::setup() { - KMyMoneySettings::instance(QString()); } void PivotTableTest::init() { storage = new MyMoneySeqAccessMgr; file = MyMoneyFile::instance(); file->attachStorage(storage); MyMoneyFileTransaction ft; file->addCurrency(MyMoneySecurity("CAD", "Canadian Dollar", "C$")); file->addCurrency(MyMoneySecurity("USD", "US Dollar", "$")); file->addCurrency(MyMoneySecurity("JPY", "Japanese Yen", QChar(0x00A5), 1)); file->addCurrency(MyMoneySecurity("GBP", "British Pound", "#")); file->setBaseCurrency(file->currency("USD")); MyMoneyPayee payeeTest("Test Payee"); file->addPayee(payeeTest); MyMoneyPayee payeeTest2("Thomas Baumgart"); file->addPayee(payeeTest2); acAsset = (MyMoneyFile::instance()->asset().id()); acLiability = (MyMoneyFile::instance()->liability().id()); acExpense = (MyMoneyFile::instance()->expense().id()); acIncome = (MyMoneyFile::instance()->income().id()); acChecking = makeAccount(QString("Checking Account"), eMyMoney::Account::Type::Checkings, moCheckingOpen, QDate(2004, 5, 15), acAsset); acCredit = makeAccount(QString("Credit Card"), eMyMoney::Account::Type::CreditCard, moCreditOpen, QDate(2004, 7, 15), acLiability); acSolo = makeAccount(QString("Solo"), eMyMoney::Account::Type::Expense, MyMoneyMoney(), QDate(2004, 1, 11), acExpense); acParent = makeAccount(QString("Parent"), eMyMoney::Account::Type::Expense, MyMoneyMoney(), QDate(2004, 1, 11), acExpense); acChild = makeAccount(QString("Child"), eMyMoney::Account::Type::Expense, MyMoneyMoney(), QDate(2004, 2, 11), acParent); acForeign = makeAccount(QString("Foreign"), eMyMoney::Account::Type::Expense, MyMoneyMoney(), QDate(2004, 1, 11), acExpense); acSecondChild = makeAccount(QString("Second Child"), eMyMoney::Account::Type::Expense, MyMoneyMoney(), QDate(2004, 2, 11), acParent); acGrandChild1 = makeAccount(QString("Grand Child 1"), eMyMoney::Account::Type::Expense, MyMoneyMoney(), QDate(2004, 2, 11), acChild); acGrandChild2 = makeAccount(QString("Grand Child 2"), eMyMoney::Account::Type::Expense, MyMoneyMoney(), QDate(2004, 2, 11), acChild); MyMoneyInstitution i("Bank of the World", "", "", "", "", "", ""); file->addInstitution(i); inBank = i.id(); ft.commit(); } void PivotTableTest::cleanup() { file->detachStorage(storage); delete storage; } void PivotTableTest::testNetWorthSingle() { try { MyMoneyReport filter; filter.setRowType(MyMoneyReport::eAssetLiability); filter.setDateFilter(QDate(2004, 1, 1), QDate(2004, 7, 1).addDays(-1)); XMLandback(filter); PivotTable networth_f(filter); writeTabletoCSV(networth_f); QVERIFY(networth_f.m_grid["Asset"]["Checking Account"][ReportAccount(acChecking)][eActual][5] == moCheckingOpen); QVERIFY(networth_f.m_grid["Asset"]["Checking Account"][ReportAccount(acChecking)][eActual][6] == moCheckingOpen); QVERIFY(networth_f.m_grid["Asset"]["Checking Account"].m_total[eActual][5] == moCheckingOpen); QVERIFY(networth_f.m_grid.m_total[eActual][0] == moZero); QVERIFY(networth_f.m_grid.m_total[eActual][4] == moZero); QVERIFY(networth_f.m_grid.m_total[eActual][5] == moCheckingOpen); QVERIFY(networth_f.m_grid.m_total[eActual][6] == moCheckingOpen); } catch (const MyMoneyException &e) { QFAIL(qPrintable(e.what())); } } void PivotTableTest::testNetWorthOfsetting() { // Test the net worth report to make sure it picks up the opening balance for two // accounts opened during the period of the report, one asset & one liability. Test // that it calculates the totals correctly. MyMoneyReport filter; filter.setRowType(MyMoneyReport::eAssetLiability); filter.setDateFilter(QDate(2004, 1, 1), QDate(2005, 1, 1).addDays(-1)); XMLandback(filter); PivotTable networth_f(filter); QVERIFY(networth_f.m_grid["Liability"]["Credit Card"][ReportAccount(acCredit)][eActual][7] == -moCreditOpen); QVERIFY(networth_f.m_grid.m_total[eActual][0] == moZero); QVERIFY(networth_f.m_grid.m_total[eActual][12] == moCheckingOpen + moCreditOpen); } void PivotTableTest::testNetWorthOpeningPrior() { // Test the net worth report to make sure it's picking up opening balances PRIOR to // the period of the report. MyMoneyReport filter; filter.setRowType(MyMoneyReport::eAssetLiability); filter.setDateFilter(QDate(2005, 8, 1), QDate(2005, 12, 31)); filter.setName("Net Worth Opening Prior 1"); XMLandback(filter); PivotTable networth_f(filter); writeTabletoCSV(networth_f); QVERIFY(networth_f.m_grid["Liability"]["Credit Card"].m_total[eActual][0] == -moCreditOpen); QVERIFY(networth_f.m_grid["Asset"]["Checking Account"].m_total[eActual][0] == moCheckingOpen); QVERIFY(networth_f.m_grid.m_total[eActual][0] == moCheckingOpen + moCreditOpen); QVERIFY(networth_f.m_grid.m_total[eActual][1] == moCheckingOpen + moCreditOpen); // Test the net worth report to make sure that transactions prior to the report // period are included in the opening balance TransactionHelper t1(QDate(2004, 11, 7), MyMoneySplit::ActionWithdrawal, moParent1, acCredit, acParent); TransactionHelper t2(QDate(2004, 11, 7), MyMoneySplit::ActionWithdrawal, moParent2, acCredit, acParent); TransactionHelper t3(QDate(2004, 11, 7), MyMoneySplit::ActionWithdrawal, moChild, acChecking, acChild); filter.setName("Net Worth Opening Prior 2"); PivotTable networth_f2(filter); writeTabletoCSV(networth_f2); MyMoneyMoney m1 = (networth_f2.m_grid["Liability"]["Credit Card"].m_total[eActual][1]); MyMoneyMoney m2 = (-moCreditOpen + moParent); QVERIFY((networth_f2.m_grid["Liability"]["Credit Card"].m_total[eActual][1]) == (-moCreditOpen + moParent)); QVERIFY(networth_f2.m_grid["Asset"]["Checking Account"].m_total[eActual][1] == moCheckingOpen - moChild); QVERIFY(networth_f2.m_grid.m_total[eActual][1] == moCheckingOpen + moCreditOpen - moChild - moParent); } void PivotTableTest::testNetWorthDateFilter() { // Test a net worth report whose period is prior to the time any accounts are open, // so the report should be zero. MyMoneyReport filter; filter.setRowType(MyMoneyReport::eAssetLiability); filter.setDateFilter(QDate(2004, 1, 1), QDate(2004, 2, 1).addDays(-1)); XMLandback(filter); PivotTable networth_f(filter); QVERIFY(networth_f.m_grid.m_total[eActual][1] == moZero); } void PivotTableTest::testNetWorthOpening() { MyMoneyMoney openingBalance(12000000); auto acBasicAccount = makeAccount(QString("Basic Account"), eMyMoney::Account::Type::Checkings, openingBalance, QDate(2016, 1, 1), acAsset); auto ctBasicIncome = makeAccount(QString("Basic Income"), eMyMoney::Account::Type::Income, MyMoneyMoney(), QDate(2016, 1, 1), acIncome); auto ctBasicExpense = makeAccount(QString("Basic Expense"), eMyMoney::Account::Type::Expense, MyMoneyMoney(), QDate(2016, 1, 1), acExpense); TransactionHelper t1(QDate(2016, 7, 1), MyMoneySplit::ActionDeposit, MyMoneyMoney(-6200000), acBasicAccount, ctBasicIncome); TransactionHelper t2(QDate(2016, 8, 1), MyMoneySplit::ActionDeposit, MyMoneyMoney(-200000), acBasicAccount, ctBasicIncome); TransactionHelper t3(QDate(2016, 9, 1), MyMoneySplit::ActionDeposit, MyMoneyMoney(-200000), acBasicAccount, ctBasicIncome); TransactionHelper t4(QDate(2016, 10, 1), MyMoneySplit::ActionDeposit, MyMoneyMoney(-100000), acBasicAccount, ctBasicIncome); TransactionHelper t5(QDate(2016, 11, 1), MyMoneySplit::ActionDeposit, MyMoneyMoney(-100000), acBasicAccount, ctBasicIncome); TransactionHelper t6(QDate(2016, 12, 1), MyMoneySplit::ActionWithdrawal, MyMoneyMoney(100000), acBasicAccount, ctBasicExpense); TransactionHelper t7(QDate(2017, 1, 1), MyMoneySplit::ActionDeposit, MyMoneyMoney(-100000), acBasicAccount, ctBasicIncome); TransactionHelper t8(QDate(2017, 2, 1), MyMoneySplit::ActionDeposit, MyMoneyMoney(-100000), acBasicAccount, ctBasicIncome); TransactionHelper t9(QDate(2017, 3, 1), MyMoneySplit::ActionDeposit, MyMoneyMoney(-100000), acBasicAccount, ctBasicIncome); TransactionHelper t10(QDate(2017, 4, 1), MyMoneySplit::ActionDeposit, MyMoneyMoney(-100000), acBasicAccount, ctBasicIncome); TransactionHelper t11(QDate(2017, 5, 1), MyMoneySplit::ActionWithdrawal, MyMoneyMoney(4500000), acBasicAccount, ctBasicExpense); TransactionHelper t12(QDate(2017, 6, 1), MyMoneySplit::ActionDeposit, MyMoneyMoney(-100000), acBasicAccount, ctBasicIncome); TransactionHelper t13(QDate(2017, 7, 1), MyMoneySplit::ActionDeposit, MyMoneyMoney(-100000), acBasicAccount, ctBasicIncome); MyMoneyReport filter; filter.setRowType(MyMoneyReport::eAssetLiability); filter.setDateFilter(QDate(2016, 1, 1), QDate(2017, 12, 31)); filter.addAccount(acBasicAccount); XMLandback(filter); PivotTable nt_opening1(filter); writeTabletoCSV(nt_opening1, "networth-opening-1.csv"); QVERIFY(nt_opening1.m_grid["Asset"]["Basic Account"][ReportAccount(acBasicAccount)][eActual][0] == MyMoneyMoney()); // opening value on 1st Jan 2016 is 12000000, but before that i.e. 31st Dec 2015 opening value is 0 for (auto i = 1; i <= 6; ++i) QVERIFY(nt_opening1.m_grid["Asset"]["Basic Account"][ReportAccount(acBasicAccount)][eActual][i] == openingBalance); QVERIFY(nt_opening1.m_grid["Asset"]["Basic Account"][ReportAccount(acBasicAccount)][eActual][7] == openingBalance + MyMoneyMoney(6200000)); QVERIFY(nt_opening1.m_grid["Asset"]["Basic Account"][ReportAccount(acBasicAccount)][eActual][12] == MyMoneyMoney(18700000)); // value after t6 transaction filter.setDateFilter(QDate(2017, 1, 1), QDate(2017, 12, 31)); XMLandback(filter); PivotTable nt_opening2(filter); writeTabletoCSV(nt_opening2, "networth-opening-2.csv"); QVERIFY(nt_opening2.m_grid["Asset"]["Basic Account"][ReportAccount(acBasicAccount)][eActual][0] == MyMoneyMoney(18700000)); // opening value is equall to the value after t6 transaction QVERIFY(nt_opening2.m_grid["Asset"]["Basic Account"][ReportAccount(acBasicAccount)][eActual][12] == MyMoneyMoney(14800000)); } void PivotTableTest::testSpendingEmpty() { // test a spending report with no entries MyMoneyReport filter; filter.setRowType(MyMoneyReport::eExpenseIncome); XMLandback(filter); PivotTable spending_f1(filter); QVERIFY(spending_f1.m_grid.m_total[eActual].m_total == moZero); filter.setDateFilter(QDate(2004, 9, 1), QDate(2005, 1, 1).addDays(-1)); PivotTable spending_f2(filter); QVERIFY(spending_f2.m_grid.m_total[eActual].m_total == moZero); } void PivotTableTest::testSingleTransaction() { // Test a single transaction TransactionHelper t(QDate(2004, 10, 31), MyMoneySplit::ActionWithdrawal, moSolo, acChecking, acSolo); MyMoneyReport filter; filter.setRowType(MyMoneyReport::eExpenseIncome); filter.setDateFilter(QDate(2004, 9, 1), QDate(2005, 1, 1).addDays(-1)); filter.setName("Spending with Single Transaction.html"); XMLandback(filter); PivotTable spending_f(filter); writeTabletoHTML(spending_f, "Spending with Single Transaction.html"); QVERIFY(spending_f.m_grid["Expense"]["Solo"][ReportAccount(acSolo)][eActual][1] == moSolo); QVERIFY(spending_f.m_grid["Expense"]["Solo"].m_total[eActual][1] == moSolo); QVERIFY(spending_f.m_grid["Expense"]["Solo"].m_total[eActual][0] == moZero); QVERIFY(spending_f.m_grid.m_total[eActual][1] == (-moSolo)); QVERIFY(spending_f.m_grid.m_total[eActual].m_total == (-moSolo)); filter.clearTransactionFilter(); filter.setRowType(MyMoneyReport::eAssetLiability); filter.setDateFilter(QDate(2004, 9, 1), QDate(2005, 1, 1).addDays(-1)); XMLandback(filter); PivotTable networth_f(filter); QVERIFY(networth_f.m_grid["Asset"]["Checking Account"].m_total[eActual][2] == (moCheckingOpen - moSolo)); } void PivotTableTest::testSubAccount() { // Test a sub-account with a value, under an account with a value TransactionHelper t1(QDate(2004, 11, 7), MyMoneySplit::ActionWithdrawal, moParent1, acCredit, acParent); TransactionHelper t2(QDate(2004, 11, 7), MyMoneySplit::ActionWithdrawal, moParent2, acCredit, acParent); TransactionHelper t3(QDate(2004, 11, 7), MyMoneySplit::ActionWithdrawal, moChild, acCredit, acChild); MyMoneyReport filter; filter.setRowType(MyMoneyReport::eExpenseIncome); filter.setDateFilter(QDate(2004, 9, 1), QDate(2005, 1, 1).addDays(-1)); filter.setDetailLevel(MyMoneyReport::eDetailAll); filter.setName("Spending with Sub-Account"); XMLandback(filter); PivotTable spending_f(filter); writeTabletoHTML(spending_f, "Spending with Sub-Account.html"); QVERIFY(spending_f.m_grid["Expense"]["Parent"][ReportAccount(acParent)][eActual][2] == moParent); QVERIFY(spending_f.m_grid["Expense"]["Parent"][ReportAccount(acChild)][eActual][2] == moChild); QVERIFY(spending_f.m_grid["Expense"]["Parent"].m_total[eActual][2] == moParent + moChild); QVERIFY(spending_f.m_grid["Expense"]["Parent"].m_total[eActual][1] == moZero); QVERIFY(spending_f.m_grid["Expense"]["Parent"].m_total[eActual].m_total == moParent + moChild); QVERIFY(spending_f.m_grid.m_total[eActual][2] == (-moParent - moChild)); QVERIFY(spending_f.m_grid.m_total[eActual].m_total == (-moParent - moChild)); filter.clearTransactionFilter(); filter.setRowType(MyMoneyReport::eAssetLiability); filter.setDateFilter(QDate(2004, 9, 1), QDate(2005, 1, 1).addDays(-1)); filter.setName("Net Worth with Sub-Account"); XMLandback(filter); PivotTable networth_f(filter); writeTabletoHTML(networth_f, "Net Worth with Sub-Account.html"); QVERIFY(networth_f.m_grid["Liability"]["Credit Card"].m_total[eActual][3] == moParent + moChild - moCreditOpen); QVERIFY(networth_f.m_grid.m_total[eActual][4] == -moParent - moChild + moCreditOpen + moCheckingOpen); } void PivotTableTest::testFilterIEvsIE() { // Test that removing an income/spending account will remove the entry from an income/spending report TransactionHelper t1(QDate(2004, 10, 31), MyMoneySplit::ActionWithdrawal, moSolo, acChecking, acSolo); TransactionHelper t2(QDate(2004, 11, 7), MyMoneySplit::ActionWithdrawal, moParent1, acCredit, acParent); TransactionHelper t3(QDate(2004, 11, 7), MyMoneySplit::ActionWithdrawal, moChild, acCredit, acChild); MyMoneyReport filter; filter.setRowType(MyMoneyReport::eExpenseIncome); filter.setDateFilter(QDate(2004, 9, 1), QDate(2005, 1, 1).addDays(-1)); filter.addCategory(acChild); filter.addCategory(acSolo); XMLandback(filter); PivotTable spending_f(filter); QVERIFY(spending_f.m_grid["Expense"]["Parent"].m_total[eActual][2] == moChild); QVERIFY(spending_f.m_grid["Expense"].m_total[eActual][1] == moSolo); QVERIFY(spending_f.m_grid.m_total[eActual].m_total == -moSolo - moChild); } void PivotTableTest::testFilterALvsAL() { // Test that removing an asset/liability account will remove the entry from an asset/liability report TransactionHelper t1(QDate(2004, 10, 31), MyMoneySplit::ActionWithdrawal, moSolo, acChecking, acSolo); TransactionHelper t2(QDate(2004, 11, 7), MyMoneySplit::ActionWithdrawal, moParent1, acCredit, acParent); TransactionHelper t3(QDate(2004, 11, 7), MyMoneySplit::ActionWithdrawal, moChild, acCredit, acChild); MyMoneyReport filter; filter.setRowType(MyMoneyReport::eAssetLiability); filter.setDateFilter(QDate(2004, 9, 1), QDate(2005, 1, 1).addDays(-1)); filter.addAccount(acChecking); filter.addCategory(acChild); filter.addCategory(acSolo); XMLandback(filter); PivotTable networth_f(filter); QVERIFY(networth_f.m_grid.m_total[eActual][2] == -moSolo + moCheckingOpen); } void PivotTableTest::testFilterALvsIE() { // Test that removing an asset/liability account will remove the entry from an income/spending report TransactionHelper t1(QDate(2004, 10, 31), MyMoneySplit::ActionWithdrawal, moSolo, acChecking, acSolo); TransactionHelper t2(QDate(2004, 11, 7), MyMoneySplit::ActionWithdrawal, moParent1, acCredit, acParent); TransactionHelper t3(QDate(2004, 11, 7), MyMoneySplit::ActionWithdrawal, moChild, acCredit, acChild); MyMoneyReport filter; filter.setRowType(MyMoneyReport::eExpenseIncome); filter.setDateFilter(QDate(2004, 9, 1), QDate(2005, 1, 1).addDays(-1)); filter.addAccount(acChecking); QVERIFY(file->transactionList(filter).count() == 1); XMLandback(filter); PivotTable spending_f(filter); QVERIFY(spending_f.m_grid["Expense"].m_total[eActual][2] == moZero); QVERIFY(spending_f.m_grid["Expense"].m_total[eActual][1] == moSolo); QVERIFY(spending_f.m_grid.m_total[eActual].m_total == -moSolo); } void PivotTableTest::testFilterAllvsIE() { // Test that removing an asset/liability account AND an income/expense // category will remove the entry from an income/spending report TransactionHelper t1(QDate(2004, 10, 31), MyMoneySplit::ActionWithdrawal, moSolo, acChecking, acSolo); TransactionHelper t2(QDate(2004, 11, 7), MyMoneySplit::ActionWithdrawal, moParent1, acCredit, acParent); TransactionHelper t3(QDate(2004, 11, 7), MyMoneySplit::ActionWithdrawal, moChild, acCredit, acChild); MyMoneyReport filter; filter.setRowType(MyMoneyReport::eExpenseIncome); filter.setDateFilter(QDate(2004, 9, 1), QDate(2005, 1, 1).addDays(-1)); filter.addAccount(acCredit); filter.addCategory(acChild); PivotTable spending_f(filter); QVERIFY(spending_f.m_grid["Expense"].m_total[eActual][1] == moZero); QVERIFY(spending_f.m_grid["Expense"].m_total[eActual][2] == moChild); QVERIFY(spending_f.m_grid.m_total[eActual].m_total == -moChild); } void PivotTableTest::testFilterBasics() { // Test that the filters are operating the way that the reports expect them to TransactionHelper t1(QDate(2004, 10, 31), MyMoneySplit::ActionWithdrawal, moSolo, acChecking, acSolo); TransactionHelper t2(QDate(2004, 11, 7), MyMoneySplit::ActionWithdrawal, moParent1, acCredit, acParent); TransactionHelper t3(QDate(2004, 11, 7), MyMoneySplit::ActionWithdrawal, moParent2, acCredit, acParent); TransactionHelper t4(QDate(2004, 11, 7), MyMoneySplit::ActionWithdrawal, moChild, acCredit, acChild); MyMoneyTransactionFilter filter; filter.clear(); filter.setDateFilter(QDate(2004, 9, 1), QDate(2005, 1, 1).addDays(-1)); filter.addCategory(acSolo); filter.setReportAllSplits(false); filter.setConsiderCategory(true); QVERIFY(file->transactionList(filter).count() == 1); filter.addCategory(acParent); QVERIFY(file->transactionList(filter).count() == 3); filter.addAccount(acChecking); QVERIFY(file->transactionList(filter).count() == 1); filter.clear(); filter.setDateFilter(QDate(2004, 9, 1), QDate(2005, 1, 1).addDays(-1)); filter.addCategory(acParent); filter.addAccount(acCredit); filter.setReportAllSplits(false); filter.setConsiderCategory(true); QVERIFY(file->transactionList(filter).count() == 2); } void PivotTableTest::testMultipleCurrencies() { MyMoneyMoney moCanOpening(0.0, 10); MyMoneyMoney moJpyOpening(0.0, 10); MyMoneyMoney moCanPrice(0.75, 100); MyMoneyMoney moJpyPrice(0.010, 1000); MyMoneyMoney moJpyPrice2(0.011, 1000); MyMoneyMoney moJpyPrice3(0.014, 1000); MyMoneyMoney moJpyPrice4(0.0395, 10000); MyMoneyMoney moCanTransaction(100.0, 10); MyMoneyMoney moJpyTransaction(100.0, 10); QString acCanChecking = makeAccount(QString("Canadian Checking"), eMyMoney::Account::Type::Checkings, moCanOpening, QDate(2003, 11, 15), acAsset, "CAD"); QString acJpyChecking = makeAccount(QString("Japanese Checking"), eMyMoney::Account::Type::Checkings, moJpyOpening, QDate(2003, 11, 15), acAsset, "JPY"); QString acCanCash = makeAccount(QString("Canadian"), eMyMoney::Account::Type::Expense, MyMoneyMoney(), QDate(2004, 2, 11), acForeign, "CAD"); QString acJpyCash = makeAccount(QString("Japanese"), eMyMoney::Account::Type::Expense, MyMoneyMoney(), QDate(2004, 2, 11), acForeign, "JPY"); makePrice("CAD", QDate(2004, 1, 1), MyMoneyMoney(moCanPrice)); makePrice("JPY", QDate(2004, 1, 1), MyMoneyMoney(moJpyPrice)); makePrice("JPY", QDate(2004, 5, 1), MyMoneyMoney(moJpyPrice2)); makePrice("JPY", QDate(2004, 6, 30), MyMoneyMoney(moJpyPrice3)); makePrice("JPY", QDate(2004, 7, 15), MyMoneyMoney(moJpyPrice4)); TransactionHelper t1(QDate(2004, 2, 20), MyMoneySplit::ActionWithdrawal, MyMoneyMoney(moJpyTransaction), acJpyChecking, acJpyCash, "JPY"); TransactionHelper t2(QDate(2004, 3, 20), MyMoneySplit::ActionWithdrawal, MyMoneyMoney(moJpyTransaction), acJpyChecking, acJpyCash, "JPY"); TransactionHelper t3(QDate(2004, 4, 20), MyMoneySplit::ActionWithdrawal, MyMoneyMoney(moJpyTransaction), acJpyChecking, acJpyCash, "JPY"); TransactionHelper t4(QDate(2004, 2, 20), MyMoneySplit::ActionWithdrawal, MyMoneyMoney(moCanTransaction), acCanChecking, acCanCash, "CAD"); TransactionHelper t5(QDate(2004, 3, 20), MyMoneySplit::ActionWithdrawal, MyMoneyMoney(moCanTransaction), acCanChecking, acCanCash, "CAD"); TransactionHelper t6(QDate(2004, 4, 20), MyMoneySplit::ActionWithdrawal, MyMoneyMoney(moCanTransaction), acCanChecking, acCanCash, "CAD"); #if 0 QFile g("multicurrencykmy.xml"); g.open(QIODevice::WriteOnly); MyMoneyStorageXML xml; IMyMoneyStorageFormat& interface = xml; interface.writeFile(&g, dynamic_cast(MyMoneyFile::instance()->storage())); g.close(); #endif MyMoneyReport filter; filter.setRowType(MyMoneyReport::eExpenseIncome); filter.setDateFilter(QDate(2004, 1, 1), QDate(2005, 1, 1).addDays(-1)); filter.setDetailLevel(MyMoneyReport::eDetailAll); filter.setConvertCurrency(true); filter.setName("Multiple Currency Spending Rerport (with currency conversion)"); XMLandback(filter); PivotTable spending_f(filter); writeTabletoCSV(spending_f); // test single foreign currency QVERIFY(spending_f.m_grid["Expense"]["Foreign"][ReportAccount(acCanCash)][eActual][1] == (moCanTransaction*moCanPrice)); QVERIFY(spending_f.m_grid["Expense"]["Foreign"][ReportAccount(acCanCash)][eActual][2] == (moCanTransaction*moCanPrice)); QVERIFY(spending_f.m_grid["Expense"]["Foreign"][ReportAccount(acCanCash)][eActual][3] == (moCanTransaction*moCanPrice)); // test multiple foreign currencies under a common parent QVERIFY(spending_f.m_grid["Expense"]["Foreign"][ReportAccount(acJpyCash)][eActual][1] == (moJpyTransaction*moJpyPrice)); QVERIFY(spending_f.m_grid["Expense"]["Foreign"][ReportAccount(acJpyCash)][eActual][2] == (moJpyTransaction*moJpyPrice)); QVERIFY(spending_f.m_grid["Expense"]["Foreign"][ReportAccount(acJpyCash)][eActual][3] == (moJpyTransaction*moJpyPrice)); QVERIFY(spending_f.m_grid["Expense"]["Foreign"].m_total[eActual][1] == (moJpyTransaction*moJpyPrice + moCanTransaction*moCanPrice)); QVERIFY(spending_f.m_grid["Expense"]["Foreign"].m_total[eActual].m_total == (moJpyTransaction*moJpyPrice + moCanTransaction*moCanPrice + moJpyTransaction*moJpyPrice + moCanTransaction*moCanPrice + moJpyTransaction*moJpyPrice + moCanTransaction*moCanPrice)); // Test the report type where we DO NOT convert the currency filter.setConvertCurrency(false); filter.setDetailLevel(MyMoneyReport::eDetailAll); filter.setName("Multiple Currency Spending Report (WITHOUT currency conversion)"); XMLandback(filter); PivotTable spending_fnc(filter); writeTabletoCSV(spending_fnc); QVERIFY(spending_fnc.m_grid["Expense"]["Foreign"][ReportAccount(acCanCash)][eActual][1] == (moCanTransaction)); QVERIFY(spending_fnc.m_grid["Expense"]["Foreign"][ReportAccount(acCanCash)][eActual][2] == (moCanTransaction)); QVERIFY(spending_fnc.m_grid["Expense"]["Foreign"][ReportAccount(acCanCash)][eActual][3] == (moCanTransaction)); QVERIFY(spending_fnc.m_grid["Expense"]["Foreign"][ReportAccount(acJpyCash)][eActual][1] == (moJpyTransaction)); QVERIFY(spending_fnc.m_grid["Expense"]["Foreign"][ReportAccount(acJpyCash)][eActual][2] == (moJpyTransaction)); QVERIFY(spending_fnc.m_grid["Expense"]["Foreign"][ReportAccount(acJpyCash)][eActual][3] == (moJpyTransaction)); filter.setConvertCurrency(true); filter.clearTransactionFilter(); filter.setName("Multiple currency net worth"); filter.setRowType(MyMoneyReport::eAssetLiability); filter.setDateFilter(QDate(2004, 1, 1), QDate(2005, 1, 1).addDays(-1)); XMLandback(filter); PivotTable networth_f(filter); writeTabletoCSV(networth_f); // test single foreign currency QVERIFY(networth_f.m_grid["Asset"]["Canadian Checking"][ReportAccount(acCanChecking)][eActual][1] == (moCanOpening*moCanPrice)); QVERIFY(networth_f.m_grid["Asset"]["Canadian Checking"][ReportAccount(acCanChecking)][eActual][2] == ((moCanOpening - moCanTransaction)*moCanPrice)); QVERIFY(networth_f.m_grid["Asset"]["Canadian Checking"][ReportAccount(acCanChecking)][eActual][3] == ((moCanOpening - moCanTransaction - moCanTransaction)*moCanPrice)); QVERIFY(networth_f.m_grid["Asset"]["Canadian Checking"][ReportAccount(acCanChecking)][eActual][4] == ((moCanOpening - moCanTransaction - moCanTransaction - moCanTransaction)*moCanPrice)); QVERIFY(networth_f.m_grid["Asset"]["Canadian Checking"][ReportAccount(acCanChecking)][eActual][12] == ((moCanOpening - moCanTransaction - moCanTransaction - moCanTransaction)*moCanPrice)); // test Stable currency price, fluctuating account balance QVERIFY(networth_f.m_grid["Asset"]["Japanese Checking"][ReportAccount(acJpyChecking)][eActual][1] == (moJpyOpening*moJpyPrice)); QVERIFY(networth_f.m_grid["Asset"]["Japanese Checking"][ReportAccount(acJpyChecking)][eActual][2] == ((moJpyOpening - moJpyTransaction)*moJpyPrice)); QVERIFY(networth_f.m_grid["Asset"]["Japanese Checking"][ReportAccount(acJpyChecking)][eActual][3] == ((moJpyOpening - moJpyTransaction - moJpyTransaction)*moJpyPrice)); QVERIFY(networth_f.m_grid["Asset"]["Japanese Checking"][ReportAccount(acJpyChecking)][eActual][4] == ((moJpyOpening - moJpyTransaction - moJpyTransaction - moJpyTransaction)*moJpyPrice)); // test Fluctuating currency price, stable account balance QVERIFY(networth_f.m_grid["Asset"]["Japanese Checking"][ReportAccount(acJpyChecking)][eActual][5] == ((moJpyOpening - moJpyTransaction - moJpyTransaction - moJpyTransaction)*moJpyPrice2)); QVERIFY(networth_f.m_grid["Asset"]["Japanese Checking"][ReportAccount(acJpyChecking)][eActual][6] == ((moJpyOpening - moJpyTransaction - moJpyTransaction - moJpyTransaction)*moJpyPrice3)); QVERIFY(networth_f.m_grid["Asset"]["Japanese Checking"][ReportAccount(acJpyChecking)][eActual][7] == ((moJpyOpening - moJpyTransaction - moJpyTransaction - moJpyTransaction)*moJpyPrice4)); // test multiple currencies totalled up QVERIFY(networth_f.m_grid["Asset"].m_total[eActual][4] == ((moCanOpening - moCanTransaction - moCanTransaction - moCanTransaction)*moCanPrice) + ((moJpyOpening - moJpyTransaction - moJpyTransaction - moJpyTransaction)*moJpyPrice)); QVERIFY(networth_f.m_grid["Asset"].m_total[eActual][5] == ((moCanOpening - moCanTransaction - moCanTransaction - moCanTransaction)*moCanPrice) + ((moJpyOpening - moJpyTransaction - moJpyTransaction - moJpyTransaction)*moJpyPrice2) + moCheckingOpen); } void PivotTableTest::testAdvancedFilter() { // test more advanced filtering capabilities // amount { TransactionHelper t1(QDate(2004, 11, 7), MyMoneySplit::ActionWithdrawal, moParent1, acCredit, acParent); TransactionHelper t2(QDate(2004, 11, 7), MyMoneySplit::ActionWithdrawal, moChild, acCredit, acChild); MyMoneyReport filter; filter.setRowType(MyMoneyReport::eExpenseIncome); filter.setDateFilter(QDate(2004, 1, 1), QDate(2005, 1, 1).addDays(-1)); filter.setAmountFilter(moChild, moChild); XMLandback(filter); PivotTable spending_f(filter); QVERIFY(spending_f.m_grid.m_total[eActual].m_total == -moChild); } // payee (specific) { TransactionHelper t1(QDate(2004, 10, 31), MyMoneySplit::ActionWithdrawal, moSolo, acChecking, acSolo); TransactionHelper t2(QDate(2004, 11, 7), MyMoneySplit::ActionWithdrawal, moParent1, acCredit, acParent); TransactionHelper t3(QDate(2004, 11, 7), MyMoneySplit::ActionWithdrawal, moChild, acCredit, acChild); TransactionHelper t4(QDate(2004, 11, 7), MyMoneySplit::ActionWithdrawal, moThomas, acCredit, acParent, QString(), "Thomas Baumgart"); MyMoneyReport filter; filter.setRowType(MyMoneyReport::eExpenseIncome); filter.setDateFilter(QDate(2004, 1, 1), QDate(2005, 1, 1).addDays(-1)); filter.addPayee(MyMoneyFile::instance()->payeeByName("Thomas Baumgart").id()); filter.setName("Spending with Payee Filter"); XMLandback(filter); PivotTable spending_f(filter); writeTabletoHTML(spending_f, "Spending with Payee Filter.html"); QVERIFY(spending_f.m_grid["Expense"]["Parent"][ReportAccount(acParent)][eActual][10] == moThomas); QVERIFY(spending_f.m_grid.m_total[eActual].m_total == -moThomas); } // payee (no payee) { TransactionHelper t1(QDate(2004, 10, 31), MyMoneySplit::ActionWithdrawal, moSolo, acChecking, acSolo); TransactionHelper t2(QDate(2004, 11, 7), MyMoneySplit::ActionWithdrawal, moParent1, acCredit, acParent); TransactionHelper t3(QDate(2004, 11, 7), MyMoneySplit::ActionWithdrawal, moChild, acCredit, acChild); TransactionHelper t4(QDate(2004, 11, 7), MyMoneySplit::ActionWithdrawal, moNoPayee, acCredit, acParent, QString(), QString()); MyMoneyReport filter; filter.setRowType(MyMoneyReport::eExpenseIncome); filter.setDateFilter(QDate(2004, 1, 1), QDate(2005, 1, 1).addDays(-1)); filter.addPayee(QString()); XMLandback(filter); PivotTable spending_f(filter); QVERIFY(spending_f.m_grid["Expense"]["Parent"][ReportAccount(acParent)][eActual][10] == moNoPayee); QVERIFY(spending_f.m_grid.m_total[eActual].m_total == -moNoPayee); } // text { TransactionHelper t1(QDate(2004, 10, 31), MyMoneySplit::ActionWithdrawal, moSolo, acChecking, acSolo); TransactionHelper t2(QDate(2004, 11, 7), MyMoneySplit::ActionWithdrawal, moParent1, acCredit, acParent); TransactionHelper t3(QDate(2004, 11, 7), MyMoneySplit::ActionWithdrawal, moChild, acCredit, acChild); TransactionHelper t4(QDate(2004, 11, 7), MyMoneySplit::ActionWithdrawal, moThomas, acCredit, acParent, QString(), "Thomas Baumgart"); MyMoneyReport filter; filter.setRowType(MyMoneyReport::eExpenseIncome); filter.setDateFilter(QDate(2004, 1, 1), QDate(2005, 1, 1).addDays(-1)); filter.setTextFilter(QRegExp("Thomas")); XMLandback(filter); PivotTable spending_f(filter); } // type (payment, deposit, transfer) { TransactionHelper t1(QDate(2004, 1, 1), MyMoneySplit::ActionWithdrawal, moSolo, acChecking, acSolo); TransactionHelper t2(QDate(2004, 2, 1), MyMoneySplit::ActionDeposit, -moParent1, acCredit, acParent); TransactionHelper t3(QDate(2004, 11, 1), MyMoneySplit::ActionTransfer, moChild, acCredit, acChecking); MyMoneyReport filter; filter.setRowType(MyMoneyReport::eExpenseIncome); filter.addType((int)eMyMoney::TransactionFilter::Type::Payments); XMLandback(filter); PivotTable spending_f(filter); QVERIFY(spending_f.m_grid.m_total[eActual].m_total == -moSolo); filter.clearTransactionFilter(); filter.addType((int)eMyMoney::TransactionFilter::Type::Deposits); XMLandback(filter); PivotTable spending_f2(filter); QVERIFY(spending_f2.m_grid.m_total[eActual].m_total == moParent1); filter.clearTransactionFilter(); filter.addType((int)eMyMoney::TransactionFilter::Type::Transfers); XMLandback(filter); PivotTable spending_f3(filter); QVERIFY(spending_f3.m_grid.m_total[eActual].m_total == moZero); filter.setRowType(MyMoneyReport::eAssetLiability); filter.setDateFilter(QDate(2004, 1, 1), QDate(2004, 12, 31)); XMLandback(filter); PivotTable networth_f4(filter); QVERIFY(networth_f4.m_grid["Asset"].m_total[eActual][11] == moCheckingOpen + moChild); QVERIFY(networth_f4.m_grid["Liability"].m_total[eActual][11] == - moCreditOpen + moChild); QVERIFY(networth_f4.m_grid.m_total[eActual][9] == moCheckingOpen + moCreditOpen); QVERIFY(networth_f4.m_grid.m_total[eActual][10] == moCheckingOpen + moCreditOpen); } // state (reconciled, cleared, not) { TransactionHelper t1(QDate(2004, 1, 1), MyMoneySplit::ActionWithdrawal, moSolo, acChecking, acSolo); TransactionHelper t2(QDate(2004, 2, 1), MyMoneySplit::ActionWithdrawal, moParent1, acCredit, acParent); TransactionHelper t3(QDate(2004, 3, 1), MyMoneySplit::ActionWithdrawal, moParent2, acCredit, acParent); TransactionHelper t4(QDate(2004, 4, 1), MyMoneySplit::ActionWithdrawal, moChild, acCredit, acChild); QList splits = t1.splits(); splits[0].setReconcileFlag(eMyMoney::Split::State::Cleared); splits[1].setReconcileFlag(eMyMoney::Split::State::Cleared); t1.modifySplit(splits[0]); t1.modifySplit(splits[1]); t1.update(); splits.clear(); splits = t2.splits(); splits[0].setReconcileFlag(eMyMoney::Split::State::Reconciled); splits[1].setReconcileFlag(eMyMoney::Split::State::Reconciled); t2.modifySplit(splits[0]); t2.modifySplit(splits[1]); t2.update(); MyMoneyReport filter; filter.setRowType(MyMoneyReport::eExpenseIncome); filter.setDateFilter(QDate(2004, 1, 1), QDate(2005, 1, 1).addDays(-1)); filter.addState((int)eMyMoney::TransactionFilter::State::Cleared); XMLandback(filter); PivotTable spending_f(filter); QVERIFY(spending_f.m_grid.m_total[eActual].m_total == -moSolo); filter.addState((int)eMyMoney::TransactionFilter::State::Reconciled); XMLandback(filter); PivotTable spending_f2(filter); QVERIFY(spending_f2.m_grid.m_total[eActual].m_total == -moSolo - moParent1); filter.clearTransactionFilter(); filter.addState((int)eMyMoney::TransactionFilter::State::NotReconciled); XMLandback(filter); PivotTable spending_f3(filter); QVERIFY(spending_f3.m_grid.m_total[eActual].m_total == -moChild - moParent2); } // number { TransactionHelper t1(QDate(2004, 10, 31), MyMoneySplit::ActionWithdrawal, moSolo, acChecking, acSolo); TransactionHelper t2(QDate(2004, 11, 7), MyMoneySplit::ActionWithdrawal, moParent1, acCredit, acParent); TransactionHelper t3(QDate(2004, 11, 7), MyMoneySplit::ActionWithdrawal, moParent2, acCredit, acParent); TransactionHelper t4(QDate(2004, 11, 7), MyMoneySplit::ActionWithdrawal, moChild, acCredit, acChild); QList splits = t1.splits(); splits[0].setNumber("1"); splits[1].setNumber("1"); t1.modifySplit(splits[0]); t1.modifySplit(splits[1]); t1.update(); splits.clear(); splits = t2.splits(); splits[0].setNumber("2"); splits[1].setNumber("2"); t2.modifySplit(splits[0]); t2.modifySplit(splits[1]); t2.update(); splits.clear(); splits = t3.splits(); splits[0].setNumber("3"); splits[1].setNumber("3"); t3.modifySplit(splits[0]); t3.modifySplit(splits[1]); t3.update(); splits.clear(); splits = t2.splits(); splits[0].setNumber("4"); splits[1].setNumber("4"); t4.modifySplit(splits[0]); t4.modifySplit(splits[1]); t4.update(); MyMoneyReport filter; filter.setRowType(MyMoneyReport::eExpenseIncome); filter.setDateFilter(QDate(2004, 1, 1), QDate(2005, 1, 1).addDays(-1)); filter.setNumberFilter("1", "3"); XMLandback(filter); PivotTable spending_f(filter); QVERIFY(spending_f.m_grid.m_total[eActual].m_total == -moSolo - moParent1 - moParent2); } // blank dates { TransactionHelper t1y1(QDate(2003, 10, 1), MyMoneySplit::ActionWithdrawal, moSolo, acChecking, acSolo); TransactionHelper t2y1(QDate(2003, 11, 1), MyMoneySplit::ActionWithdrawal, moParent1, acCredit, acParent); TransactionHelper t3y1(QDate(2003, 12, 1), MyMoneySplit::ActionWithdrawal, moParent2, acCredit, acParent); TransactionHelper t1y2(QDate(2004, 4, 1), MyMoneySplit::ActionWithdrawal, moSolo, acChecking, acSolo); TransactionHelper t2y2(QDate(2004, 5, 1), MyMoneySplit::ActionWithdrawal, moParent1, acCredit, acParent); TransactionHelper t3y2(QDate(2004, 6, 1), MyMoneySplit::ActionWithdrawal, moParent2, acCredit, acParent); TransactionHelper t1y3(QDate(2005, 1, 1), MyMoneySplit::ActionWithdrawal, moSolo, acChecking, acSolo); TransactionHelper t2y3(QDate(2005, 5, 1), MyMoneySplit::ActionWithdrawal, moParent1, acCredit, acParent); TransactionHelper t3y3(QDate(2005, 9, 1), MyMoneySplit::ActionWithdrawal, moParent2, acCredit, acParent); MyMoneyReport filter; filter.setRowType(MyMoneyReport::eExpenseIncome); filter.setDateFilter(QDate(), QDate(2004, 7, 1)); XMLandback(filter); PivotTable spending_f(filter); QVERIFY(spending_f.m_grid.m_total[eActual].m_total == -moSolo - moParent1 - moParent2 - moSolo - moParent1 - moParent2); filter.clearTransactionFilter(); XMLandback(filter); PivotTable spending_f2(filter); QVERIFY(spending_f2.m_grid.m_total[eActual].m_total == -moSolo - moParent1 - moParent2 - moSolo - moParent1 - moParent2 - moSolo - moParent1 - moParent2); } } void PivotTableTest::testColumnType() { // test column type values of other than 'month' TransactionHelper t1q1(QDate(2004, 1, 1), MyMoneySplit::ActionWithdrawal, moSolo, acChecking, acSolo); TransactionHelper t2q1(QDate(2004, 2, 1), MyMoneySplit::ActionWithdrawal, moParent1, acCredit, acParent); TransactionHelper t3q1(QDate(2004, 3, 1), MyMoneySplit::ActionWithdrawal, moParent2, acCredit, acParent); TransactionHelper t1q2(QDate(2004, 4, 1), MyMoneySplit::ActionWithdrawal, moSolo, acChecking, acSolo); TransactionHelper t2q2(QDate(2004, 5, 1), MyMoneySplit::ActionWithdrawal, moParent1, acCredit, acParent); TransactionHelper t3q2(QDate(2004, 6, 1), MyMoneySplit::ActionWithdrawal, moParent2, acCredit, acParent); TransactionHelper t1y2(QDate(2005, 1, 1), MyMoneySplit::ActionWithdrawal, moSolo, acChecking, acSolo); TransactionHelper t2y2(QDate(2005, 5, 1), MyMoneySplit::ActionWithdrawal, moParent1, acCredit, acParent); TransactionHelper t3y2(QDate(2005, 9, 1), MyMoneySplit::ActionWithdrawal, moParent2, acCredit, acParent); MyMoneyReport filter; filter.setRowType(MyMoneyReport::eExpenseIncome); filter.setDateFilter(QDate(2003, 12, 31), QDate(2005, 12, 31)); filter.setRowType(MyMoneyReport::eExpenseIncome); filter.setColumnType(MyMoneyReport::eBiMonths); XMLandback(filter); PivotTable spending_b(filter); QVERIFY(spending_b.m_grid.m_total[eActual][0] == moZero); QVERIFY(spending_b.m_grid.m_total[eActual][1] == -moParent1 - moSolo); QVERIFY(spending_b.m_grid.m_total[eActual][2] == -moParent2 - moSolo); QVERIFY(spending_b.m_grid.m_total[eActual][3] == -moParent); QVERIFY(spending_b.m_grid.m_total[eActual][4] == moZero); QVERIFY(spending_b.m_grid.m_total[eActual][5] == moZero); QVERIFY(spending_b.m_grid.m_total[eActual][6] == moZero); QVERIFY(spending_b.m_grid.m_total[eActual][7] == -moSolo); QVERIFY(spending_b.m_grid.m_total[eActual][8] == moZero); QVERIFY(spending_b.m_grid.m_total[eActual][9] == -moParent1); QVERIFY(spending_b.m_grid.m_total[eActual][10] == moZero); QVERIFY(spending_b.m_grid.m_total[eActual][11] == -moParent2); QVERIFY(spending_b.m_grid.m_total[eActual][12] == moZero); filter.setColumnType(MyMoneyReport::eQuarters); XMLandback(filter); PivotTable spending_q(filter); QVERIFY(spending_q.m_grid.m_total[eActual][0] == moZero); QVERIFY(spending_q.m_grid.m_total[eActual][1] == -moSolo - moParent); QVERIFY(spending_q.m_grid.m_total[eActual][2] == -moSolo - moParent); QVERIFY(spending_q.m_grid.m_total[eActual][3] == moZero); QVERIFY(spending_q.m_grid.m_total[eActual][4] == moZero); QVERIFY(spending_q.m_grid.m_total[eActual][5] == -moSolo); QVERIFY(spending_q.m_grid.m_total[eActual][6] == -moParent1); QVERIFY(spending_q.m_grid.m_total[eActual][7] == -moParent2); QVERIFY(spending_q.m_grid.m_total[eActual][8] == moZero); filter.setRowType(MyMoneyReport::eAssetLiability); filter.setName("Net Worth by Quarter"); XMLandback(filter); PivotTable networth_q(filter); writeTabletoHTML(networth_q, "Net Worth by Quarter.html"); QVERIFY(networth_q.m_grid.m_total[eActual][1] == moZero); QVERIFY(networth_q.m_grid.m_total[eActual][2] == -moSolo - moParent); QVERIFY(networth_q.m_grid.m_total[eActual][3] == -moSolo - moParent - moSolo - moParent + moCheckingOpen); QVERIFY(networth_q.m_grid.m_total[eActual][4] == -moSolo - moParent - moSolo - moParent + moCheckingOpen + moCreditOpen); QVERIFY(networth_q.m_grid.m_total[eActual][5] == -moSolo - moParent - moSolo - moParent + moCheckingOpen + moCreditOpen); QVERIFY(networth_q.m_grid.m_total[eActual][6] == -moSolo - moSolo - moParent - moSolo - moParent + moCheckingOpen + moCreditOpen); QVERIFY(networth_q.m_grid.m_total[eActual][7] == -moParent1 - moSolo - moSolo - moParent - moSolo - moParent + moCheckingOpen + moCreditOpen); QVERIFY(networth_q.m_grid.m_total[eActual][8] == -moParent2 - moParent1 - moSolo - moSolo - moParent - moSolo - moParent + moCheckingOpen + moCreditOpen); QVERIFY(networth_q.m_grid.m_total[eActual][9] == -moParent2 - moParent1 - moSolo - moSolo - moParent - moSolo - moParent + moCheckingOpen + moCreditOpen); filter.setRowType(MyMoneyReport::eExpenseIncome); filter.setColumnType(MyMoneyReport::eYears); XMLandback(filter); PivotTable spending_y(filter); QVERIFY(spending_y.m_grid.m_total[eActual][0] == moZero); QVERIFY(spending_y.m_grid.m_total[eActual][1] == -moSolo - moParent - moSolo - moParent); QVERIFY(spending_y.m_grid.m_total[eActual][2] == -moSolo - moParent); QVERIFY(spending_y.m_grid.m_total[eActual].m_total == -moSolo - moParent - moSolo - moParent - moSolo - moParent); filter.setRowType(MyMoneyReport::eAssetLiability); XMLandback(filter); PivotTable networth_y(filter); QVERIFY(networth_y.m_grid.m_total[eActual][1] == moZero); QVERIFY(networth_y.m_grid.m_total[eActual][2] == -moSolo - moParent - moSolo - moParent + moCheckingOpen + moCreditOpen); QVERIFY(networth_y.m_grid.m_total[eActual][3] == -moSolo - moParent - moSolo - moParent - moSolo - moParent + moCheckingOpen + moCreditOpen); // Test days-based reports TransactionHelper t1d1(QDate(2004, 7, 1), MyMoneySplit::ActionWithdrawal, moSolo, acChecking, acSolo); TransactionHelper t2d1(QDate(2004, 7, 1), MyMoneySplit::ActionWithdrawal, moParent1, acCredit, acParent); TransactionHelper t3d1(QDate(2004, 7, 4), MyMoneySplit::ActionWithdrawal, moParent2, acCredit, acParent); TransactionHelper t1d2(QDate(2004, 7, 14), MyMoneySplit::ActionWithdrawal, moSolo, acChecking, acSolo); TransactionHelper t2d2(QDate(2004, 7, 15), MyMoneySplit::ActionWithdrawal, moParent1, acCredit, acParent); TransactionHelper t3d2(QDate(2004, 7, 20), MyMoneySplit::ActionWithdrawal, moParent2, acCredit, acParent); TransactionHelper t1d3(QDate(2004, 8, 2), MyMoneySplit::ActionWithdrawal, moSolo, acChecking, acSolo); TransactionHelper t2d3(QDate(2004, 8, 3), MyMoneySplit::ActionWithdrawal, moParent1, acCredit, acParent); TransactionHelper t3d3(QDate(2004, 8, 4), MyMoneySplit::ActionWithdrawal, moParent2, acCredit, acParent); filter.setDateFilter(QDate(2004, 7, 2), QDate(2004, 7, 14)); filter.setRowType(MyMoneyReport::eExpenseIncome); filter.setColumnType(MyMoneyReport::eMonths); filter.setColumnsAreDays(true); filter.setName("Spending by Days"); XMLandback(filter); PivotTable spending_days(filter); writeTabletoHTML(spending_days, "Spending by Days.html"); QVERIFY(spending_days.m_grid.m_total[eActual][2] == -moParent2); QVERIFY(spending_days.m_grid.m_total[eActual][12] == -moSolo); QVERIFY(spending_days.m_grid.m_total[eActual].m_total == -moSolo - moParent2); // set the first day of the week to 1 QLocale::setDefault(QLocale(QLocale::English, QLocale::UnitedKingdom)); filter.setDateFilter(QDate(2004, 7, 2), QDate(2004, 8, 1)); filter.setRowType(MyMoneyReport::eExpenseIncome); filter.setColumnType(static_cast(7)); filter.setColumnsAreDays(true); filter.setName("Spending by Weeks"); XMLandback(filter); PivotTable spending_weeks(filter); writeTabletoHTML(spending_weeks, "Spending by Weeks.html"); // restore the locale QLocale::setDefault(QLocale::system()); QVERIFY(spending_weeks.m_grid.m_total[eActual][0] == -moParent2); QVERIFY(spending_weeks.m_grid.m_total[eActual][1] == moZero); QVERIFY(spending_weeks.m_grid.m_total[eActual][2] == -moSolo - moParent1); QVERIFY(spending_weeks.m_grid.m_total[eActual][3] == -moParent2); QVERIFY(spending_weeks.m_grid.m_total[eActual][4] == moZero); QVERIFY(spending_weeks.m_grid.m_total[eActual].m_total == -moSolo - moParent - moParent2); } void PivotTableTest::testInvestment() { try { // Equities eqStock1 = makeEquity("Stock1", "STK1"); eqStock2 = makeEquity("Stock2", "STK2"); // Accounts acInvestment = makeAccount("Investment", eMyMoney::Account::Type::Investment, moZero, QDate(2004, 1, 1), acAsset); acStock1 = makeAccount("Stock 1", eMyMoney::Account::Type::Stock, moZero, QDate(2004, 1, 1), acInvestment, eqStock1); acStock2 = makeAccount("Stock 2", eMyMoney::Account::Type::Stock, moZero, QDate(2004, 1, 1), acInvestment, eqStock2); acDividends = makeAccount("Dividends", eMyMoney::Account::Type::Income, moZero, QDate(2004, 1, 1), acIncome); // Transactions // Date Action Shares Price Stock Asset Income InvTransactionHelper s1b1(QDate(2004, 2, 1), MyMoneySplit::ActionBuyShares, MyMoneyMoney(1000.00), MyMoneyMoney(100.00), acStock1, acChecking, QString()); InvTransactionHelper s1b2(QDate(2004, 3, 1), MyMoneySplit::ActionBuyShares, MyMoneyMoney(1000.00), MyMoneyMoney(110.00), acStock1, acChecking, QString()); InvTransactionHelper s1s1(QDate(2004, 4, 1), MyMoneySplit::ActionBuyShares, MyMoneyMoney(-200.00), MyMoneyMoney(120.00), acStock1, acChecking, QString()); InvTransactionHelper s1s2(QDate(2004, 5, 1), MyMoneySplit::ActionBuyShares, MyMoneyMoney(-200.00), MyMoneyMoney(100.00), acStock1, acChecking, QString()); InvTransactionHelper s1r1(QDate(2004, 6, 1), MyMoneySplit::ActionReinvestDividend, MyMoneyMoney(50.00), MyMoneyMoney(100.00), acStock1, QString(), acDividends); InvTransactionHelper s1r2(QDate(2004, 7, 1), MyMoneySplit::ActionReinvestDividend, MyMoneyMoney(50.00), MyMoneyMoney(80.00), acStock1, QString(), acDividends); InvTransactionHelper s1c1(QDate(2004, 8, 1), MyMoneySplit::ActionDividend, MyMoneyMoney(10.00), MyMoneyMoney(100.00), acStock1, acChecking, acDividends); InvTransactionHelper s1c2(QDate(2004, 9, 1), MyMoneySplit::ActionDividend, MyMoneyMoney(10.00), MyMoneyMoney(120.00), acStock1, acChecking, acDividends); makeEquityPrice(eqStock1, QDate(2004, 10, 1), MyMoneyMoney(100.00)); // // Net Worth Report (with investments) // MyMoneyReport networth_r; networth_r.setRowType(MyMoneyReport::eAssetLiability); networth_r.setDateFilter(QDate(2004, 1, 1), QDate(2004, 12, 31).addDays(-1)); XMLandback(networth_r); PivotTable networth(networth_r); networth.dump("networth_i.html"); QVERIFY(networth.m_grid["Asset"]["Investment"].m_total[eActual][1] == moZero); // 1000 shares @ $100.00 QVERIFY(networth.m_grid["Asset"]["Investment"].m_total[eActual][2] == MyMoneyMoney(100000.0)); // 2000 shares @ $110.00 QVERIFY(networth.m_grid["Asset"]["Investment"].m_total[eActual][3] == MyMoneyMoney(220000.0)); // 1800 shares @ $120.00 QVERIFY(networth.m_grid["Asset"]["Investment"].m_total[eActual][4] == MyMoneyMoney(216000.0)); // 1600 shares @ $100.00 QVERIFY(networth.m_grid["Asset"]["Investment"].m_total[eActual][5] == MyMoneyMoney(160000.0)); // 1650 shares @ $100.00 QVERIFY(networth.m_grid["Asset"]["Investment"].m_total[eActual][6] == MyMoneyMoney(165000.0)); // 1700 shares @ $ 80.00 QVERIFY(networth.m_grid["Asset"]["Investment"].m_total[eActual][7] == MyMoneyMoney(136000.0)); // 1700 shares @ $100.00 QVERIFY(networth.m_grid["Asset"]["Investment"].m_total[eActual][8] == MyMoneyMoney(170000.0)); // 1700 shares @ $120.00 QVERIFY(networth.m_grid["Asset"]["Investment"].m_total[eActual][9] == MyMoneyMoney(204000.0)); // 1700 shares @ $100.00 QVERIFY(networth.m_grid["Asset"]["Investment"].m_total[eActual][10] == MyMoneyMoney(170000.0)); #if 0 // Dump file & reports QFile g("investmentkmy.xml"); g.open(QIODevice::WriteOnly); MyMoneyStorageXML xml; IMyMoneyStorageFormat& interface = xml; interface.writeFile(&g, dynamic_cast(MyMoneyFile::instance()->storage())); g.close(); invtran.dump("invtran.html", "%1"); invhold.dump("invhold.html", "%1"); #endif } catch (const MyMoneyException &e) { QFAIL(qPrintable(e.what())); } } void PivotTableTest::testBudget() { // 1. Budget on A, transactions on A { BudgetHelper budget; budget += BudgetEntryHelper(QDate(2006, 1, 1), acSolo, false, MyMoneyMoney(100.0)); MyMoneyReport report(MyMoneyReport::eBudgetActual, MyMoneyReport::eMonths, eMyMoney::TransactionFilter::Date::YearToDate, MyMoneyReport::eDetailTop, "Yearly Budgeted vs. Actual", "Default Report"); PivotTable table(report); } // 2. Budget on B, not applying to sub accounts, transactions on B and B:1 { BudgetHelper budget; budget += BudgetEntryHelper(QDate(2006, 1, 1), acParent, false, MyMoneyMoney(100.0)); MyMoneyReport report(MyMoneyReport::eBudgetActual, MyMoneyReport::eMonths, eMyMoney::TransactionFilter::Date::YearToDate, MyMoneyReport::eDetailTop, "Yearly Budgeted vs. Actual", "Default Report"); PivotTable table(report); } // - Both B and B:1 totals should show up // - B actuals compare against B budget // - B:1 actuals compare against 0 // 3. Budget on C, applying to sub accounts, transactions on C and C:1 and C:1:a { BudgetHelper budget; budget += BudgetEntryHelper(QDate(2006, 1, 1), acParent, true, MyMoneyMoney(100.0)); MyMoneyReport report(MyMoneyReport::eBudgetActual, MyMoneyReport::eMonths, eMyMoney::TransactionFilter::Date::YearToDate, MyMoneyReport::eDetailTop , "Yearly Budgeted vs. Actual", "Default Report"); PivotTable table(report); } // - Only C totals show up, not C:1 or C:1:a totals // - C + C:1 totals compare against C budget // 4. Budget on D, not applying to sub accounts, budget on D:1 not applying, budget on D:2 applying. Transactions on D, D:1, D:2, D:2:a, D:2:b { BudgetHelper budget; budget += BudgetEntryHelper(QDate(2006, 1, 1), acParent, false, MyMoneyMoney(100.0)); budget += BudgetEntryHelper(QDate(2006, 1, 1), acChild, false, MyMoneyMoney(100.0)); budget += BudgetEntryHelper(QDate(2006, 1, 1), acSecondChild, true, MyMoneyMoney(100.0)); MyMoneyReport report(MyMoneyReport::eBudgetActual, MyMoneyReport::eMonths, eMyMoney::TransactionFilter::Date::YearToDate, MyMoneyReport::eDetailTop, "Yearly Budgeted vs. Actual", "Default Report"); PivotTable table(report); } // - Totals for D, D:1, D:2 show up. D:2:a and D:2:b do not // - D actuals (only) compare against D budget // - Ditto for D:1 // - D:2 acutals and children compare against D:2 budget // 5. Budget on E, no transactions on E { BudgetHelper budget; budget += BudgetEntryHelper(QDate(2006, 1, 1), acSolo, false, MyMoneyMoney(100.0)); MyMoneyReport report(MyMoneyReport::eBudgetActual, MyMoneyReport::eMonths, eMyMoney::TransactionFilter::Date::YearToDate, MyMoneyReport::eDetailTop, "Yearly Budgeted vs. Actual", "Default Report"); PivotTable table(report); } } void PivotTableTest::testHtmlEncoding() { MyMoneyReport filter; filter.setRowType(MyMoneyReport::eAssetLiability); filter.setDateFilter(QDate(2004, 1, 1), QDate(2005, 1, 1).addDays(-1)); XMLandback(filter); PivotTable networth_f(filter); QByteArray encoding = QTextCodec::codecForLocale()->name(); QString html = networth_f.renderReport(QLatin1String("html"), encoding, filter.name(), false); QRegExp rx(QString::fromLatin1("**")); rx.setPatternSyntax(QRegExp::Wildcard); rx.setCaseSensitivity(Qt::CaseInsensitive); QVERIFY(rx.exactMatch(html)); } diff --git a/kmymoney/reports/tests/querytable-test.cpp b/kmymoney/reports/tests/querytable-test.cpp index 9b480cc7e..4affe5ddb 100644 --- a/kmymoney/reports/tests/querytable-test.cpp +++ b/kmymoney/reports/tests/querytable-test.cpp @@ -1,905 +1,904 @@ /*************************************************************************** querytabletest.cpp ------------------- copyright : (C) 2002 by Thomas Baumgart email : ipwizard@users.sourceforge.net Ace Jones ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "querytable-test.h" #include #include #include #include "reportstestcommon.h" #include "querytable.h" #include "mymoneyinstitution.h" #include "mymoneyaccount.h" #include "mymoneysecurity.h" #include "mymoneyprice.h" #include "mymoneystoragedump.h" #include "mymoneyreport.h" #include "mymoneysplit.h" #include "mymoneypayee.h" #include "mymoneystatement.h" #include "mymoneystoragexml.h" #include "mymoneyexception.h" #include "kmymoneysettings.h" using namespace reports; using namespace test; QTEST_GUILESS_MAIN(QueryTableTest) void QueryTableTest::setup() { - KMyMoneySettings::instance(QString()); } void QueryTableTest::init() { storage = new MyMoneySeqAccessMgr; file = MyMoneyFile::instance(); file->attachStorage(storage); MyMoneyFileTransaction ft; file->addCurrency(MyMoneySecurity("CAD", "Canadian Dollar", "C$")); file->addCurrency(MyMoneySecurity("USD", "US Dollar", "$")); file->addCurrency(MyMoneySecurity("JPY", "Japanese Yen", QChar(0x00A5), 1)); file->addCurrency(MyMoneySecurity("GBP", "British Pound", "#")); file->setBaseCurrency(file->currency("USD")); MyMoneyPayee payeeTest("Test Payee"); file->addPayee(payeeTest); MyMoneyPayee payeeTest2("Thomas Baumgart"); file->addPayee(payeeTest2); acAsset = (MyMoneyFile::instance()->asset().id()); acLiability = (MyMoneyFile::instance()->liability().id()); acExpense = (MyMoneyFile::instance()->expense().id()); acIncome = (MyMoneyFile::instance()->income().id()); acChecking = makeAccount(QString("Checking Account"), eMyMoney::Account::Type::Checkings, moCheckingOpen, QDate(2004, 5, 15), acAsset); acCredit = makeAccount(QString("Credit Card"), eMyMoney::Account::Type::CreditCard, moCreditOpen, QDate(2004, 7, 15), acLiability); acSolo = makeAccount(QString("Solo"), eMyMoney::Account::Type::Expense, MyMoneyMoney(), QDate(2004, 1, 11), acExpense); acParent = makeAccount(QString("Parent"), eMyMoney::Account::Type::Expense, MyMoneyMoney(), QDate(2004, 1, 11), acExpense); acChild = makeAccount(QString("Child"), eMyMoney::Account::Type::Expense, MyMoneyMoney(), QDate(2004, 2, 11), acParent); acForeign = makeAccount(QString("Foreign"), eMyMoney::Account::Type::Expense, MyMoneyMoney(), QDate(2004, 1, 11), acExpense); acTax = makeAccount(QString("Tax"), eMyMoney::Account::Type::Expense, MyMoneyMoney(), QDate(2005, 1, 11), acExpense, "", true); MyMoneyInstitution i("Bank of the World", "", "", "", "", "", ""); file->addInstitution(i); inBank = i.id(); ft.commit(); } void QueryTableTest::cleanup() { file->detachStorage(storage); delete storage; } void QueryTableTest::testQueryBasics() { try { TransactionHelper t1q1(QDate(2004, 1, 1), MyMoneySplit::ActionWithdrawal, moSolo, acChecking, acSolo); TransactionHelper t2q1(QDate(2004, 2, 1), MyMoneySplit::ActionWithdrawal, moParent1, acCredit, acParent); TransactionHelper t3q1(QDate(2004, 3, 1), MyMoneySplit::ActionWithdrawal, moParent2, acCredit, acParent); TransactionHelper t4y1(QDate(2004, 11, 7), MyMoneySplit::ActionWithdrawal, moChild, acCredit, acChild); TransactionHelper t1q2(QDate(2004, 4, 1), MyMoneySplit::ActionWithdrawal, moSolo, acChecking, acSolo); TransactionHelper t2q2(QDate(2004, 5, 1), MyMoneySplit::ActionWithdrawal, moParent1, acCredit, acParent); TransactionHelper t3q2(QDate(2004, 6, 1), MyMoneySplit::ActionWithdrawal, moParent2, acCredit, acParent); TransactionHelper t4q2(QDate(2004, 11, 7), MyMoneySplit::ActionWithdrawal, moChild, acCredit, acChild); TransactionHelper t1y2(QDate(2005, 1, 1), MyMoneySplit::ActionWithdrawal, moSolo, acChecking, acSolo); TransactionHelper t2y2(QDate(2005, 5, 1), MyMoneySplit::ActionWithdrawal, moParent1, acCredit, acParent); TransactionHelper t3y2(QDate(2005, 9, 1), MyMoneySplit::ActionWithdrawal, moParent2, acCredit, acParent); TransactionHelper t4y2(QDate(2004, 11, 7), MyMoneySplit::ActionWithdrawal, moChild, acCredit, acChild); unsigned cols; MyMoneyReport filter; filter.setRowType(MyMoneyReport::eCategory); cols = MyMoneyReport::eQCnumber | MyMoneyReport::eQCpayee | MyMoneyReport::eQCaccount; filter.setQueryColumns(static_cast(cols)); // filter.setName("Transactions by Category"); XMLandback(filter); QueryTable qtbl_1(filter); writeTabletoHTML(qtbl_1, "Transactions by Category.html"); QList rows = qtbl_1.rows(); QVERIFY(rows.count() == 19); 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; filter.setQueryColumns(static_cast(cols)); // filter.setName("Transactions by Top Category"); XMLandback(filter); QueryTable qtbl_2(filter); writeTabletoHTML(qtbl_2, "Transactions by Top Category.html"); rows = qtbl_2.rows(); QVERIFY(rows.count() == 16); 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"); cols = MyMoneyReport::eQCnumber | MyMoneyReport::eQCpayee | MyMoneyReport::eQCcategory; filter.setQueryColumns(static_cast(cols)); // XMLandback(filter); QueryTable qtbl_3(filter); writeTabletoHTML(qtbl_3, "Transactions by Account.html"); rows = qtbl_3.rows(); #if 1 QVERIFY(rows.count() == 19); 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][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][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"); cols = MyMoneyReport::eQCnumber | MyMoneyReport::eQCmemo | MyMoneyReport::eQCcategory; filter.setQueryColumns(static_cast(cols)); // XMLandback(filter); QueryTable qtbl_4(filter); writeTabletoHTML(qtbl_4, "Transactions by Payee.html"); rows = qtbl_4.rows(); QVERIFY(rows.count() == 14); 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"); cols = MyMoneyReport::eQCnumber | MyMoneyReport::eQCpayee | MyMoneyReport::eQCcategory; filter.setQueryColumns(static_cast(cols)); // XMLandback(filter); QueryTable qtbl_5(filter); writeTabletoHTML(qtbl_5, "Transactions by Month.html"); rows = qtbl_5.rows(); QVERIFY(rows.count() == 23); 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"); cols = MyMoneyReport::eQCnumber | MyMoneyReport::eQCpayee | MyMoneyReport::eQCcategory; filter.setQueryColumns(static_cast(cols)); // XMLandback(filter); QueryTable qtbl_6(filter); writeTabletoHTML(qtbl_6, "Transactions by Week.html"); rows = qtbl_6.rows(); QVERIFY(rows.count() == 23); 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[ListTable::ctPrice] = 'A'; low[ListTable::ctLastPrice] = 'B'; low[ListTable::ctBuyPrice] = 'C'; QueryTable::TableRow high; high[ListTable::ctPrice] = 'A'; high[ListTable::ctLastPrice] = 'C'; high[ListTable::ctBuyPrice] = 'B'; QueryTable::TableRow::setSortCriteria({ListTable::ctPrice, ListTable::ctLastPrice, ListTable::ctBuyPrice}); QVERIFY(low < high); QVERIFY(low <= high); QVERIFY(high > low); QVERIFY(high <= high); QVERIFY(high == high); } void QueryTableTest::testCashFlowAnalysis() { // // Test IRR calculations // CashFlowList list; list += CashFlowListItem(QDate(2004, 5, 3), MyMoneyMoney(1000.0)); list += CashFlowListItem(QDate(2004, 5, 20), MyMoneyMoney(59.0)); list += CashFlowListItem(QDate(2004, 6, 3), MyMoneyMoney(14.0)); list += CashFlowListItem(QDate(2004, 6, 24), MyMoneyMoney(92.0)); list += CashFlowListItem(QDate(2004, 7, 6), MyMoneyMoney(63.0)); list += CashFlowListItem(QDate(2004, 7, 25), MyMoneyMoney(15.0)); list += CashFlowListItem(QDate(2004, 8, 5), MyMoneyMoney(92.0)); list += CashFlowListItem(QDate(2004, 9, 2), MyMoneyMoney(18.0)); list += CashFlowListItem(QDate(2004, 9, 21), MyMoneyMoney(5.0)); list += CashFlowListItem(QDate(2004, 10, 16), MyMoneyMoney(-2037.0)); MyMoneyMoney IRR(list.IRR(), 1000); QVERIFY(IRR == MyMoneyMoney(1676, 1000)); list.pop_back(); list += CashFlowListItem(QDate(2004, 10, 16), MyMoneyMoney(-1358.0)); IRR = MyMoneyMoney(list.IRR(), 1000); QVERIFY(IRR.isZero()); } void QueryTableTest::testAccountQuery() { try { QString htmlcontext = QString("\n\n%1\n\n"); // // No transactions, opening balances only // MyMoneyReport filter; filter.setRowType(MyMoneyReport::eInstitution); filter.setName("Accounts by Institution (No transactions)"); XMLandback(filter); QueryTable qtbl_1(filter); writeTabletoHTML(qtbl_1, "Accounts by Institution (No transactions).html"); QList rows = qtbl_1.rows(); QVERIFY(rows.count() == 6); 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][ListTable::ctValue]) == moCheckingOpen + moCreditOpen); QVERIFY(MyMoneyMoney(rows[5][ListTable::ctValue]) == moCheckingOpen + moCreditOpen); // // Adding in transactions // TransactionHelper t1q1(QDate(2004, 1, 1), MyMoneySplit::ActionWithdrawal, moSolo, acChecking, acSolo); TransactionHelper t2q1(QDate(2004, 2, 1), MyMoneySplit::ActionWithdrawal, moParent1, acCredit, acParent); TransactionHelper t3q1(QDate(2004, 3, 1), MyMoneySplit::ActionWithdrawal, moParent2, acCredit, acParent); TransactionHelper t4y1(QDate(2004, 11, 7), MyMoneySplit::ActionWithdrawal, moChild, acCredit, acChild); TransactionHelper t1q2(QDate(2004, 4, 1), MyMoneySplit::ActionWithdrawal, moSolo, acChecking, acSolo); TransactionHelper t2q2(QDate(2004, 5, 1), MyMoneySplit::ActionWithdrawal, moParent1, acCredit, acParent); TransactionHelper t3q2(QDate(2004, 6, 1), MyMoneySplit::ActionWithdrawal, moParent2, acCredit, acParent); TransactionHelper t4q2(QDate(2004, 11, 7), MyMoneySplit::ActionWithdrawal, moChild, acCredit, acChild); TransactionHelper t1y2(QDate(2005, 1, 1), MyMoneySplit::ActionWithdrawal, moSolo, acChecking, acSolo); TransactionHelper t2y2(QDate(2005, 5, 1), MyMoneySplit::ActionWithdrawal, moParent1, acCredit, acParent); TransactionHelper t3y2(QDate(2005, 9, 1), MyMoneySplit::ActionWithdrawal, moParent2, acCredit, acParent); TransactionHelper t4y2(QDate(2004, 11, 7), MyMoneySplit::ActionWithdrawal, moChild, acCredit, acChild); filter.setRowType(MyMoneyReport::eInstitution); filter.setName("Accounts by Institution (With Transactions)"); XMLandback(filter); QueryTable qtbl_2(filter); rows = qtbl_2.rows(); QVERIFY(rows.count() == 6); 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][ListTable::ctValue]) == moCheckingOpen + moCreditOpen - (moParent1 + moParent2 + moSolo + moChild) * 3); // // Account TYPES // filter.setRowType(MyMoneyReport::eAccountType); filter.setName("Accounts by Type"); XMLandback(filter); QueryTable qtbl_3(filter); rows = qtbl_3.rows(); QVERIFY(rows.count() == 5); 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())); } } void QueryTableTest::testInvestment() { try { // Equities eqStock1 = makeEquity("Stock1", "STK1"); eqStock2 = makeEquity("Stock2", "STK2"); eqStock3 = makeEquity("Stock3", "STK3"); eqStock4 = makeEquity("Stock4", "STK4"); // Accounts acInvestment = makeAccount("Investment", eMyMoney::Account::Type::Investment, moZero, QDate(2003, 11, 1), acAsset); acStock1 = makeAccount("Stock 1", eMyMoney::Account::Type::Stock, moZero, QDate(2004, 1, 1), acInvestment, eqStock1); acStock2 = makeAccount("Stock 2", eMyMoney::Account::Type::Stock, moZero, QDate(2004, 1, 1), acInvestment, eqStock2); acStock3 = makeAccount("Stock 3", eMyMoney::Account::Type::Stock, moZero, QDate(2003, 11, 1), acInvestment, eqStock3); acStock4 = makeAccount("Stock 4", eMyMoney::Account::Type::Stock, moZero, QDate(2004, 1, 1), acInvestment, eqStock4); acDividends = makeAccount("Dividends", eMyMoney::Account::Type::Income, moZero, QDate(2004, 1, 1), acIncome); acInterest = makeAccount("Interest", eMyMoney::Account::Type::Income, moZero, QDate(2004, 1, 1), acIncome); acFees = makeAccount("Fees", eMyMoney::Account::Type::Expense, moZero, QDate(2003, 11, 1), acExpense); // Transactions // Date Action Shares Price Stock Asset Income InvTransactionHelper s1b1(QDate(2003, 12, 1), MyMoneySplit::ActionBuyShares, MyMoneyMoney(1000.00), MyMoneyMoney(100.00), acStock3, acChecking, QString()); InvTransactionHelper s1b2(QDate(2004, 1, 30), MyMoneySplit::ActionBuyShares, MyMoneyMoney(500.00), MyMoneyMoney(100.00), acStock4, acChecking, acFees, MyMoneyMoney(100.00)); InvTransactionHelper s1b3(QDate(2004, 1, 30), MyMoneySplit::ActionBuyShares, MyMoneyMoney(500.00), MyMoneyMoney(90.00), acStock4, acChecking, acFees, MyMoneyMoney(100.00)); InvTransactionHelper s1b4(QDate(2004, 2, 1), MyMoneySplit::ActionBuyShares, MyMoneyMoney(1000.00), MyMoneyMoney(100.00), acStock1, acChecking, QString()); InvTransactionHelper s1b5(QDate(2004, 3, 1), MyMoneySplit::ActionBuyShares, MyMoneyMoney(1000.00), MyMoneyMoney(110.00), acStock1, acChecking, QString()); InvTransactionHelper s1s1(QDate(2004, 4, 1), MyMoneySplit::ActionBuyShares, MyMoneyMoney(-200.00), MyMoneyMoney(120.00), acStock1, acChecking, QString()); InvTransactionHelper s1s2(QDate(2004, 5, 1), MyMoneySplit::ActionBuyShares, MyMoneyMoney(-200.00), MyMoneyMoney(100.00), acStock1, acChecking, QString()); InvTransactionHelper s1s3(QDate(2004, 5, 30), MyMoneySplit::ActionBuyShares, MyMoneyMoney(-1000.00), MyMoneyMoney(120.00), acStock4, acChecking, acFees, MyMoneyMoney(200.00)); InvTransactionHelper s1r1(QDate(2004, 6, 1), MyMoneySplit::ActionReinvestDividend, MyMoneyMoney(50.00), MyMoneyMoney(100.00), acStock1, QString(), acDividends); InvTransactionHelper s1r2(QDate(2004, 7, 1), MyMoneySplit::ActionReinvestDividend, MyMoneyMoney(50.00), MyMoneyMoney(80.00), acStock1, QString(), acDividends); InvTransactionHelper s1c1(QDate(2004, 8, 1), MyMoneySplit::ActionDividend, MyMoneyMoney(10.00), MyMoneyMoney(100.00), acStock1, acChecking, acDividends); InvTransactionHelper s1c2(QDate(2004, 9, 1), MyMoneySplit::ActionDividend, MyMoneyMoney(10.00), MyMoneyMoney(120.00), acStock1, acChecking, acDividends); InvTransactionHelper s1y1(QDate(2004, 9, 15), MyMoneySplit::ActionYield, MyMoneyMoney(10.00), MyMoneyMoney(110.00), acStock1, acChecking, acInterest); makeEquityPrice(eqStock1, QDate(2004, 10, 1), MyMoneyMoney(100.00)); makeEquityPrice(eqStock3, QDate(2004, 10, 1), MyMoneyMoney(110.00)); makeEquityPrice(eqStock4, QDate(2004, 10, 1), MyMoneyMoney(110.00)); // // Investment Transactions Report // MyMoneyReport invtran_r( MyMoneyReport::eTopAccount, MyMoneyReport::eQCaction | MyMoneyReport::eQCshares | MyMoneyReport::eQCprice, eMyMoney::TransactionFilter::Date::UserDefined, MyMoneyReport::eDetailAll, i18n("Investment Transactions"), i18n("Test Report") ); invtran_r.setDateFilter(QDate(2004, 1, 1), QDate(2004, 12, 31)); invtran_r.setInvestmentsOnly(true); XMLandback(invtran_r); QueryTable invtran(invtran_r); #if 1 writeTabletoHTML(invtran, "investment_transactions_test.html"); QList rows = invtran.rows(); QVERIFY(rows.count() == 32); 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][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][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][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)); #endif // // Investment Performance Report // MyMoneyReport invhold_r( MyMoneyReport::eAccountByTopAccount, MyMoneyReport::eQCperformance, eMyMoney::TransactionFilter::Date::UserDefined, MyMoneyReport::eDetailAll, i18n("Investment Performance by Account"), i18n("Test Report") ); invhold_r.setDateFilter(QDate(2004, 1, 1), QDate(2004, 10, 1)); invhold_r.setInvestmentsOnly(true); XMLandback(invhold_r); QueryTable invhold(invhold_r); writeTabletoHTML(invhold, "Investment Performance by Account.html"); rows = invhold.rows(); QVERIFY(rows.count() == 5); 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][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][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][ListTable::ctEndingBalance]) == MyMoneyMoney(280000.00)); #if 0 // Dump file & reports QFile g("investmentkmy.xml"); g.open(QIODevice::WriteOnly); MyMoneyStorageXML xml; IMyMoneyStorageFormat& interface = xml; interface.writeFile(&g, dynamic_cast(MyMoneyFile::instance()->storage())); g.close(); invtran.dump("invtran.html", "%1"); invhold.dump("invhold.html", "%1"); #endif } catch (const MyMoneyException &e) { QFAIL(qPrintable(e.what())); } } // prevents bug #312135 void QueryTableTest::testSplitShares() { try { MyMoneyMoney firstSharesPurchase(16); MyMoneyMoney splitFactor(2); MyMoneyMoney secondSharesPurchase(1); MyMoneyMoney sharesAtTheEnd = firstSharesPurchase / splitFactor + secondSharesPurchase; MyMoneyMoney priceBeforeSplit(74.99, 100); MyMoneyMoney priceAfterSplit = splitFactor * priceBeforeSplit; // Equities eqStock1 = makeEquity("Stock1", "STK1"); // Accounts acInvestment = makeAccount("Investment", eMyMoney::Account::Type::Investment, moZero, QDate(2017, 8, 1), acAsset); acStock1 = makeAccount("Stock 1", eMyMoney::Account::Type::Stock, moZero, QDate(2017, 8, 1), acInvestment, eqStock1); // Transactions // Date Action Shares Price Stock Asset Income InvTransactionHelper s1b1(QDate(2017, 8, 1), MyMoneySplit::ActionBuyShares, firstSharesPurchase, priceBeforeSplit, acStock1, acChecking, QString()); InvTransactionHelper s1s1(QDate(2017, 8, 2), MyMoneySplit::ActionSplitShares, splitFactor, MyMoneyMoney(), acStock1, QString(), QString()); InvTransactionHelper s1b2(QDate(2017, 8, 3), MyMoneySplit::ActionBuyShares, secondSharesPurchase, priceAfterSplit, acStock1, acChecking, QString()); // // Investment Performance Report // MyMoneyReport invhold_r( MyMoneyReport::eAccountByTopAccount, MyMoneyReport::eQCperformance, eMyMoney::TransactionFilter::Date::UserDefined, MyMoneyReport::eDetailAll, i18n("Investment Performance by Account"), i18n("Test Report") ); invhold_r.setDateFilter(QDate(2017, 8, 1), QDate(2017, 8, 3)); invhold_r.setInvestmentsOnly(true); XMLandback(invhold_r); QueryTable invhold(invhold_r); writeTabletoHTML(invhold, "Investment Performance by Account (with stock split).html"); const auto rows = invhold.rows(); QVERIFY(rows.count() == 3); QVERIFY(MyMoneyMoney(rows[0][ListTable::ctBuys]) == sharesAtTheEnd * priceAfterSplit * MyMoneyMoney(-1)); } catch (const MyMoneyException &e) { QFAIL(qPrintable(e.what())); } } // prevents bug #118159 void QueryTableTest::testConversionRate() { try { MyMoneyMoney firsConversionRate(1.1800, 10000); MyMoneyMoney secondConversionRate(1.1567, 10000); MyMoneyMoney amountWithdrawn(100); const auto acCadChecking = makeAccount(QString("Canadian Checking"), eMyMoney::Account::Type::Checkings, moZero, QDate(2017, 8, 1), acAsset, "CAD"); makePrice("CAD", QDate(2017, 8, 1), firsConversionRate); makePrice("CAD", QDate(2017, 8, 2), secondConversionRate); TransactionHelper t1(QDate(2017, 8, 1), MyMoneySplit::ActionWithdrawal, amountWithdrawn, acCadChecking, acSolo, "CAD"); MyMoneyReport filter; filter.setRowType(MyMoneyReport::eAccount); filter.setDateFilter(QDate(2017, 8, 1), QDate(2017, 8, 2)); filter.setName("Transactions by Account"); auto cols = MyMoneyReport::eQCnumber | MyMoneyReport::eQCpayee | MyMoneyReport::eQCcategory | MyMoneyReport::eQCbalance; filter.setQueryColumns(static_cast(cols)); // XMLandback(filter); QueryTable qtbl(filter); writeTabletoHTML(qtbl, "Transactions by Account (conversion rate).html"); const auto rows = qtbl.rows(); QVERIFY(rows.count() == 5); QVERIFY(MyMoneyMoney(rows[1][ListTable::ctValue]) == amountWithdrawn * firsConversionRate * MyMoneyMoney(-1)); QVERIFY(MyMoneyMoney(rows[1][ListTable::ctPrice]) == firsConversionRate); QVERIFY(MyMoneyMoney(rows[2][ListTable::ctBalance]) == amountWithdrawn * secondConversionRate * MyMoneyMoney(-1)); QVERIFY(MyMoneyMoney(rows[2][ListTable::ctPrice]) == secondConversionRate); } catch (const MyMoneyException &e) { QFAIL(qPrintable(e.what())); } } //this is to prevent me from making mistakes again when modifying balances - asoliverez //this case tests only the opening and ending balance of the accounts void QueryTableTest::testBalanceColumn() { try { TransactionHelper t1q1(QDate(2004, 1, 1), MyMoneySplit::ActionWithdrawal, moSolo, acChecking, acSolo); TransactionHelper t2q1(QDate(2004, 2, 1), MyMoneySplit::ActionWithdrawal, moParent1, acCredit, acParent); TransactionHelper t3q1(QDate(2004, 3, 1), MyMoneySplit::ActionWithdrawal, moParent2, acCredit, acParent); TransactionHelper t4y1(QDate(2004, 11, 7), MyMoneySplit::ActionWithdrawal, moChild, acCredit, acChild); TransactionHelper t1q2(QDate(2004, 4, 1), MyMoneySplit::ActionWithdrawal, moSolo, acChecking, acSolo); TransactionHelper t2q2(QDate(2004, 5, 1), MyMoneySplit::ActionWithdrawal, moParent1, acCredit, acParent); TransactionHelper t3q2(QDate(2004, 6, 1), MyMoneySplit::ActionWithdrawal, moParent2, acCredit, acParent); TransactionHelper t4q2(QDate(2004, 11, 7), MyMoneySplit::ActionWithdrawal, moChild, acCredit, acChild); TransactionHelper t1y2(QDate(2005, 1, 1), MyMoneySplit::ActionWithdrawal, moSolo, acChecking, acSolo); TransactionHelper t2y2(QDate(2005, 5, 1), MyMoneySplit::ActionWithdrawal, moParent1, acCredit, acParent); TransactionHelper t3y2(QDate(2005, 9, 1), MyMoneySplit::ActionWithdrawal, moParent2, acCredit, acParent); TransactionHelper t4y2(QDate(2004, 11, 7), MyMoneySplit::ActionWithdrawal, moChild, acCredit, acChild); unsigned cols; MyMoneyReport filter; filter.setRowType(MyMoneyReport::eAccount); filter.setName("Transactions by Account"); cols = MyMoneyReport::eQCnumber | MyMoneyReport::eQCpayee | MyMoneyReport::eQCcategory | MyMoneyReport::eQCbalance; filter.setQueryColumns(static_cast(cols)); // XMLandback(filter); QueryTable qtbl_3(filter); writeTabletoHTML(qtbl_3, "Transactions by Account.html"); QString html = qtbl_3.renderHTML(); QList rows = qtbl_3.rows(); QVERIFY(rows.count() == 19); //this is to make sure that the dates of closing and opening balances and the balance numbers are ok QString openingDate = QLocale().toString(QDate(2004, 1, 1), QLocale::ShortFormat); QString closingDate = QLocale().toString(QDate(2005, 9, 1), QLocale::ShortFormat); QVERIFY(html.indexOf(openingDate + "" + i18n("Opening Balance")) > 0); QVERIFY(html.indexOf(closingDate + "" + i18n("Closing Balance") + " -702.36") > 0); QVERIFY(html.indexOf(closingDate + "" + i18n("Closing Balance") + " -705.69") > 0); } catch (const MyMoneyException &e) { QFAIL(qPrintable(e.what())); } } void QueryTableTest::testBalanceColumnWithMultipleCurrencies() { try { MyMoneyMoney moJpyOpening(0.0, 1); MyMoneyMoney moJpyPrice(0.010, 100); MyMoneyMoney moJpyPrice2(0.011, 100); MyMoneyMoney moJpyPrice3(0.024, 100); MyMoneyMoney moTransaction(100, 1); MyMoneyMoney moJpyTransaction(100, 1); QString acJpyChecking = makeAccount(QString("Japanese Checking"), eMyMoney::Account::Type::Checkings, moJpyOpening, QDate(2003, 11, 15), acAsset, "JPY"); makePrice("JPY", QDate(2004, 1, 1), MyMoneyMoney(moJpyPrice)); makePrice("JPY", QDate(2004, 5, 1), MyMoneyMoney(moJpyPrice2)); makePrice("JPY", QDate(2004, 6, 30), MyMoneyMoney(moJpyPrice3)); QDate openingDate(2004, 2, 20); QDate intermediateDate(2004, 5, 20); QDate closingDate(2004, 7, 20); TransactionHelper t1(openingDate, MyMoneySplit::ActionTransfer, MyMoneyMoney(moJpyTransaction), acJpyChecking, acChecking, "JPY"); TransactionHelper t4(openingDate, MyMoneySplit::ActionDeposit, MyMoneyMoney(moTransaction), acCredit, acChecking); TransactionHelper t2(intermediateDate, MyMoneySplit::ActionTransfer, MyMoneyMoney(moJpyTransaction), acJpyChecking, acChecking, "JPY"); TransactionHelper t5(intermediateDate, MyMoneySplit::ActionDeposit, MyMoneyMoney(moTransaction), acCredit, acChecking); TransactionHelper t3(closingDate, MyMoneySplit::ActionTransfer, MyMoneyMoney(moJpyTransaction), acJpyChecking, acChecking, "JPY"); TransactionHelper t6(closingDate, MyMoneySplit::ActionDeposit, MyMoneyMoney(moTransaction), acCredit, acChecking); // test that an income/expense transaction that involves a currency exchange is properly reported TransactionHelper t7(intermediateDate, MyMoneySplit::ActionWithdrawal, MyMoneyMoney(moJpyTransaction), acJpyChecking, acSolo, "JPY"); unsigned cols; MyMoneyReport filter; filter.setRowType(MyMoneyReport::eAccount); filter.setName("Transactions by Account"); cols = MyMoneyReport::eQCnumber | MyMoneyReport::eQCpayee | MyMoneyReport::eQCcategory | MyMoneyReport::eQCbalance; filter.setQueryColumns(static_cast(cols)); // don't convert values to the default currency filter.setConvertCurrency(false); XMLandback(filter); QueryTable qtbl_3(filter); writeTabletoHTML(qtbl_3, "Transactions by Account (multiple currencies).html"); QString html = qtbl_3.renderHTML(); QList rows = qtbl_3.rows(); QVERIFY(rows.count() == 24); //this is to make sure that the dates of closing and opening balances and the balance numbers are ok QString openingDateString = QLocale().toString(openingDate, QLocale::ShortFormat); QString intermediateDateString = QLocale().toString(intermediateDate, QLocale::ShortFormat); QString closingDateString = QLocale().toString(closingDate, QLocale::ShortFormat); // check the opening and closing balances QVERIFY(html.indexOf(openingDateString + "" + i18n("Opening Balance") + "USD 0.00") > 0); QVERIFY(html.indexOf(closingDateString + "" + i18n("Closing Balance") + "USD 304.00") > 0); QVERIFY(html.indexOf(closingDateString + "" + i18n("Closing Balance") + "USD -300.00") > 0); QVERIFY(html.indexOf(closingDateString + "" + i18n("Closing Balance") + "JPY -400.00") > 0); // after a transfer of 100 JPY the balance should be 1.00 - price is 0.010 (precision of 2) QVERIFY(html.indexOf("" + openingDateString + "Test PayeeTransfer from Japanese CheckingUSD 1.00USD 1.00") > 0); // after a transfer of 100 the balance should be 101.00 QVERIFY(html.indexOf("" + openingDateString + "Test PayeeTransfer from Credit CardUSD 100.00USD 101.00") > 0); // after a transfer of 100 JPY the balance should be 102.00 - price is 0.011 (precision of 2) QVERIFY(html.indexOf("" + intermediateDateString + "Test PayeeTransfer from Japanese CheckingUSD 1.00USD 102.00") > 0); // after a transfer of 100 the balance should be 202.00 QVERIFY(html.indexOf("" + intermediateDateString + "Test PayeeTransfer from Credit CardUSD 100.00USD 202.00") > 0); // after a transfer of 100 JPY the balance should be 204.00 - price is 0.024 (precision of 2) QVERIFY(html.indexOf("" + closingDateString + "Test PayeeTransfer from Japanese CheckingUSD 2.00USD 204.00") > 0); // after a transfer of 100 the balance should be 304.00 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 -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); XMLandback(filter); QueryTable qtbl_4(filter); writeTabletoHTML(qtbl_4, "Transactions by Account (multiple currencies converted to base).html"); html = qtbl_4.renderHTML(); rows = qtbl_4.rows(); QVERIFY(rows.count() == 23); // check the opening and closing balances QVERIFY(html.indexOf(openingDateString + "" + i18n("Opening Balance") + " 0.00") > 0); QVERIFY(html.indexOf(closingDateString + "" + i18n("Closing Balance") + " 304.00") > 0); QVERIFY(html.indexOf(closingDateString + "" + i18n("Closing Balance") + " -300.00") > 0); // although the balance should be -5.00 it's -8.00 because the foreign currency balance is converted using the closing date price (0.024) QVERIFY(html.indexOf(closingDateString + "" + i18n("Closing Balance") + " -8.00") > 0); // a 100.00 JPY transfer should be displayed as -1.00 when converted to the base currency using the opening date price QVERIFY(html.indexOf("" + openingDateString + "Test PayeeTransfer to Checking Account -1.00 -1.00") > 0); // a 100.00 JPY transfer should be displayed as -1.00 when converted to the base currency using the intermediate date price 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 -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 -3.00") > 0); } catch (const MyMoneyException &e) { QFAIL(qPrintable(e.what())); } } void QueryTableTest::testTaxReport() { try { TransactionHelper t1q1(QDate(2004, 1, 1), MyMoneySplit::ActionWithdrawal, moSolo, acChecking, acSolo); TransactionHelper t2q1(QDate(2004, 2, 1), MyMoneySplit::ActionWithdrawal, moParent1, acChecking, acTax); unsigned cols; MyMoneyReport filter; filter.setRowType(MyMoneyReport::eCategory); filter.setName("Tax Transactions"); cols = MyMoneyReport::eQCnumber | MyMoneyReport::eQCpayee | MyMoneyReport::eQCaccount; filter.setQueryColumns(static_cast(cols)); filter.setTax(true); XMLandback(filter); QueryTable qtbl_3(filter); writeTabletoHTML(qtbl_3, "Tax Transactions.html"); QList rows = qtbl_3.rows(); QString html = qtbl_3.renderHTML(); QVERIFY(rows.count() == 5); } catch (const MyMoneyException &e) { QFAIL(qPrintable(e.what())); } }