summaryrefslogtreecommitdiffstats
path: root/kmymoney2/reports/pivottabletest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kmymoney2/reports/pivottabletest.cpp')
-rw-r--r--kmymoney2/reports/pivottabletest.cpp1021
1 files changed, 1021 insertions, 0 deletions
diff --git a/kmymoney2/reports/pivottabletest.cpp b/kmymoney2/reports/pivottabletest.cpp
new file mode 100644
index 0000000..a235c0b
--- /dev/null
+++ b/kmymoney2/reports/pivottabletest.cpp
@@ -0,0 +1,1021 @@
+/***************************************************************************
+ pivottabletest.cpp
+ -------------------
+ copyright : (C) 2002-2005 by Thomas Baumgart
+ email : ipwizard@users.sourceforge.net
+ Ace Jones <ace.j@hotpop.com>
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 <qvaluelist.h>
+#include <qvaluevector.h>
+#include <qdom.h>
+#include <qfile.h>
+
+#include <kdebug.h>
+#include <kdeversion.h>
+#include <kglobal.h>
+#include <kglobalsettings.h>
+#include <klocale.h>
+#include <kstandarddirs.h>
+
+// DOH, mmreport.h uses this without including it!!
+#include "../mymoney/mymoneyaccount.h"
+
+#include "../mymoney/mymoneysecurity.h"
+#include "../mymoney/mymoneyprice.h"
+#include "../mymoney/mymoneyreport.h"
+#include "../mymoney/mymoneystatement.h"
+#include "../mymoney/storage/mymoneystoragedump.h"
+#include "../mymoney/storage/mymoneystoragexml.h"
+
+#define private public
+#include "../reports/pivottable.h"
+#undef private
+
+#include "reportstestcommon.h"
+#include "pivottabletest.h"
+
+using namespace reports;
+using namespace test;
+
+PivotTableTest::PivotTableTest()
+{
+}
+
+void PivotTableTest::setUp ()
+{
+ 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), 100, 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"),MyMoneyAccount::Checkings,moCheckingOpen,QDate(2004,5,15),acAsset);
+ acCredit = makeAccount(QString("Credit Card"),MyMoneyAccount::CreditCard,moCreditOpen,QDate(2004,7,15),acLiability);
+ acSolo = makeAccount(QString("Solo"),MyMoneyAccount::Expense,0,QDate(2004,1,11),acExpense);
+ acParent = makeAccount(QString("Parent"),MyMoneyAccount::Expense,0,QDate(2004,1,11),acExpense);
+ acChild = makeAccount(QString("Child"),MyMoneyAccount::Expense,0,QDate(2004,2,11),acParent);
+ acForeign = makeAccount(QString("Foreign"),MyMoneyAccount::Expense,0,QDate(2004,1,11),acExpense);
+
+ acSecondChild = makeAccount(QString("Second Child"),MyMoneyAccount::Expense,0,QDate(2004,2,11),acParent);
+ acGrandChild1 = makeAccount(QString("Grand Child 1"),MyMoneyAccount::Expense,0,QDate(2004,2,11),acChild);
+ acGrandChild2 = makeAccount(QString("Grand Child 2"),MyMoneyAccount::Expense,0,QDate(2004,2,11),acChild);
+
+ MyMoneyInstitution i("Bank of the World","","","","","","");
+ file->addInstitution(i);
+ inBank = i.id();
+ ft.commit();
+}
+
+void PivotTableTest::tearDown ()
+{
+ 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);
+
+ CPPUNIT_ASSERT(networth_f.m_grid["Asset"]["Checking Account"][acChecking][eActual][5]==moCheckingOpen);
+ CPPUNIT_ASSERT(networth_f.m_grid["Asset"]["Checking Account"][acChecking][eActual][6]==moCheckingOpen);
+ CPPUNIT_ASSERT(networth_f.m_grid["Asset"]["Checking Account"].m_total[eActual][5]==moCheckingOpen);
+ CPPUNIT_ASSERT(networth_f.m_grid.m_total[eActual][0]==moZero);
+ CPPUNIT_ASSERT(networth_f.m_grid.m_total[eActual][4]==moZero);
+ CPPUNIT_ASSERT(networth_f.m_grid.m_total[eActual][5]==moCheckingOpen);
+ CPPUNIT_ASSERT(networth_f.m_grid.m_total[eActual][6]==moCheckingOpen);
+ }
+ catch(MyMoneyException *e)
+ {
+ CPPUNIT_FAIL(e->what());
+ delete e;
+ }
+}
+
+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 );
+ CPPUNIT_ASSERT(networth_f.m_grid["Liability"]["Credit Card"][acCredit][eActual][7]==-moCreditOpen);
+ CPPUNIT_ASSERT(networth_f.m_grid.m_total[eActual][0]==moZero);
+ CPPUNIT_ASSERT(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);
+
+ CPPUNIT_ASSERT(networth_f.m_grid["Liability"]["Credit Card"].m_total[eActual][0]==-moCreditOpen);
+ CPPUNIT_ASSERT(networth_f.m_grid["Asset"]["Checking Account"].m_total[eActual][0]==moCheckingOpen);
+ CPPUNIT_ASSERT(networth_f.m_grid.m_total[eActual][0]==moCheckingOpen+moCreditOpen);
+ CPPUNIT_ASSERT(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);
+ CPPUNIT_ASSERT(networth_f2.m_grid["Liability"]["Credit Card"].m_total[eActual][1]==-moCreditOpen+moParent);
+ CPPUNIT_ASSERT(networth_f2.m_grid["Asset"]["Checking Account"].m_total[eActual][1]==moCheckingOpen-moChild);
+ CPPUNIT_ASSERT(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 );
+ CPPUNIT_ASSERT(networth_f.m_grid.m_total[eActual][1]==moZero);
+
+}
+
+void PivotTableTest::testSpendingEmpty()
+{
+ // test a spending report with no entries
+
+ MyMoneyReport filter;
+ filter.setRowType( MyMoneyReport::eExpenseIncome );
+ XMLandback(filter);
+ PivotTable spending_f1( filter );
+ CPPUNIT_ASSERT(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 );
+ CPPUNIT_ASSERT(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");
+
+ CPPUNIT_ASSERT(spending_f.m_grid["Expense"]["Solo"][acSolo][eActual][2]==moSolo);
+ CPPUNIT_ASSERT(spending_f.m_grid["Expense"]["Solo"].m_total[eActual][2]==moSolo);
+ CPPUNIT_ASSERT(spending_f.m_grid["Expense"]["Solo"].m_total[eActual][1]==moZero);
+ CPPUNIT_ASSERT(spending_f.m_grid.m_total[eActual][2]==(-moSolo));
+ CPPUNIT_ASSERT(spending_f.m_grid.m_total[eActual].m_total==(-moSolo));
+
+ filter.clear();
+ filter.setRowType(MyMoneyReport::eAssetLiability);
+ filter.setDateFilter(QDate(2004,9,1),QDate(2005,1,1).addDays(-1));
+ XMLandback(filter);
+ PivotTable networth_f( filter );
+ CPPUNIT_ASSERT(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");
+
+ CPPUNIT_ASSERT(spending_f.m_grid["Expense"]["Parent"][acParent][eActual][3]==moParent);
+ CPPUNIT_ASSERT(spending_f.m_grid["Expense"]["Parent"][acChild][eActual][3]==moChild);
+ CPPUNIT_ASSERT(spending_f.m_grid["Expense"]["Parent"].m_total[eActual][3]==moParent+moChild);
+ CPPUNIT_ASSERT(spending_f.m_grid["Expense"]["Parent"].m_total[eActual][2]==moZero);
+ CPPUNIT_ASSERT(spending_f.m_grid["Expense"]["Parent"].m_total[eActual].m_total==moParent+moChild);
+ CPPUNIT_ASSERT(spending_f.m_grid.m_total[eActual][3]==(-moParent-moChild));
+ CPPUNIT_ASSERT(spending_f.m_grid.m_total[eActual].m_total==(-moParent-moChild));
+
+ filter.clear();
+ 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");
+ CPPUNIT_ASSERT(networth_f.m_grid["Liability"]["Credit Card"].m_total[eActual][3]==moParent+moChild-moCreditOpen );
+ CPPUNIT_ASSERT(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 );
+
+ CPPUNIT_ASSERT(spending_f.m_grid["Expense"]["Parent"].m_total[eActual][3]==moChild);
+ CPPUNIT_ASSERT(spending_f.m_grid["Expense"].m_total[eActual][2]==moSolo);
+ CPPUNIT_ASSERT(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 );
+ CPPUNIT_ASSERT(networth_f.m_grid.m_total[eActual][3] == -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);
+ CPPUNIT_ASSERT(file->transactionList(filter).count() == 1);
+
+ XMLandback(filter);
+ PivotTable spending_f( filter );
+
+ CPPUNIT_ASSERT(spending_f.m_grid["Expense"].m_total[eActual][3]==moZero);
+ CPPUNIT_ASSERT(spending_f.m_grid["Expense"].m_total[eActual][2]==moSolo);
+ CPPUNIT_ASSERT(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 );
+
+ CPPUNIT_ASSERT(spending_f.m_grid["Expense"].m_total[eActual][2]==moZero);
+ CPPUNIT_ASSERT(spending_f.m_grid["Expense"].m_total[eActual][3]==moChild);
+ CPPUNIT_ASSERT(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);
+
+ CPPUNIT_ASSERT(file->transactionList(filter).count() == 1);
+
+ filter.addCategory(acParent);
+
+ CPPUNIT_ASSERT(file->transactionList(filter).count() == 3);
+
+ filter.addAccount(acChecking);
+
+ CPPUNIT_ASSERT(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);
+
+ CPPUNIT_ASSERT(file->transactionList(filter).count() == 2);
+}
+
+void PivotTableTest::testMultipleCurrencies()
+{
+ MyMoneyMoney moCanOpening( 0.0 );
+ MyMoneyMoney moJpyOpening( 0.0 );
+ MyMoneyMoney moCanPrice( 0.75 );
+ MyMoneyMoney moJpyPrice( 0.010 );
+ MyMoneyMoney moJpyPrice2( 0.011 );
+ MyMoneyMoney moJpyPrice3( 0.014 );
+ MyMoneyMoney moJpyPrice4( 0.0395 );
+ MyMoneyMoney moCanTransaction( 100.0 );
+ MyMoneyMoney moJpyTransaction( 100.0 );
+
+ QString acCanChecking = makeAccount(QString("Canadian Checking"),MyMoneyAccount::Checkings,moCanOpening,QDate(2003,11,15),acAsset,"CAD");
+ QString acJpyChecking = makeAccount(QString("Japanese Checking"),MyMoneyAccount::Checkings,moJpyOpening,QDate(2003,11,15),acAsset,"JPY");
+ QString acCanCash = makeAccount(QString("Canadian"),MyMoneyAccount::Expense,0,QDate(2004,2,11),acForeign,"CAD");
+ QString acJpyCash = makeAccount(QString("Japanese"),MyMoneyAccount::Expense,0,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( IO_WriteOnly );
+ MyMoneyStorageXML xml;
+ IMyMoneyStorageFormat& interface = xml;
+ interface.writeFile(&g, dynamic_cast<IMyMoneySerialize*> (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
+ CPPUNIT_ASSERT(spending_f.m_grid["Expense"]["Foreign"][acCanCash][eActual][2]==(moCanTransaction*moCanPrice));
+ CPPUNIT_ASSERT(spending_f.m_grid["Expense"]["Foreign"][acCanCash][eActual][3]==(moCanTransaction*moCanPrice));
+ CPPUNIT_ASSERT(spending_f.m_grid["Expense"]["Foreign"][acCanCash][eActual][4]==(moCanTransaction*moCanPrice));
+
+ // test multiple foreign currencies under a common parent
+ CPPUNIT_ASSERT(spending_f.m_grid["Expense"]["Foreign"][acJpyCash][eActual][2]==(moJpyTransaction*moJpyPrice));
+ CPPUNIT_ASSERT(spending_f.m_grid["Expense"]["Foreign"][acJpyCash][eActual][3]==(moJpyTransaction*moJpyPrice));
+ CPPUNIT_ASSERT(spending_f.m_grid["Expense"]["Foreign"][acJpyCash][eActual][4]==(moJpyTransaction*moJpyPrice));
+ CPPUNIT_ASSERT(spending_f.m_grid["Expense"]["Foreign"].m_total[eActual][2]==(moJpyTransaction*moJpyPrice + moCanTransaction*moCanPrice));
+ CPPUNIT_ASSERT(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);
+
+ CPPUNIT_ASSERT(spending_fnc.m_grid["Expense"]["Foreign"][acCanCash][eActual][2]==(moCanTransaction));
+ CPPUNIT_ASSERT(spending_fnc.m_grid["Expense"]["Foreign"][acCanCash][eActual][3]==(moCanTransaction));
+ CPPUNIT_ASSERT(spending_fnc.m_grid["Expense"]["Foreign"][acCanCash][eActual][4]==(moCanTransaction));
+ CPPUNIT_ASSERT(spending_fnc.m_grid["Expense"]["Foreign"][acJpyCash][eActual][2]==(moJpyTransaction));
+ CPPUNIT_ASSERT(spending_fnc.m_grid["Expense"]["Foreign"][acJpyCash][eActual][3]==(moJpyTransaction));
+ CPPUNIT_ASSERT(spending_fnc.m_grid["Expense"]["Foreign"][acJpyCash][eActual][4]==(moJpyTransaction));
+
+ filter.setConvertCurrency(true);
+ filter.clear();
+ 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
+ CPPUNIT_ASSERT(networth_f.m_grid["Asset"]["Canadian Checking"][acCanChecking][eActual][1]==(moCanOpening*moCanPrice));
+ CPPUNIT_ASSERT(networth_f.m_grid["Asset"]["Canadian Checking"][acCanChecking][eActual][2]==((moCanOpening-moCanTransaction)*moCanPrice));
+ CPPUNIT_ASSERT(networth_f.m_grid["Asset"]["Canadian Checking"][acCanChecking][eActual][3]==((moCanOpening-moCanTransaction-moCanTransaction)*moCanPrice));
+ CPPUNIT_ASSERT(networth_f.m_grid["Asset"]["Canadian Checking"][acCanChecking][eActual][4]==((moCanOpening-moCanTransaction-moCanTransaction-moCanTransaction)*moCanPrice));
+ CPPUNIT_ASSERT(networth_f.m_grid["Asset"]["Canadian Checking"][acCanChecking][eActual][12]==((moCanOpening-moCanTransaction-moCanTransaction-moCanTransaction)*moCanPrice));
+
+ // test Stable currency price, fluctuating account balance
+ CPPUNIT_ASSERT(networth_f.m_grid["Asset"]["Japanese Checking"][acJpyChecking][eActual][1]==(moJpyOpening*moJpyPrice));
+ CPPUNIT_ASSERT(networth_f.m_grid["Asset"]["Japanese Checking"][acJpyChecking][eActual][2]==((moJpyOpening-moJpyTransaction)*moJpyPrice));
+ CPPUNIT_ASSERT(networth_f.m_grid["Asset"]["Japanese Checking"][acJpyChecking][eActual][3]==((moJpyOpening-moJpyTransaction-moJpyTransaction)*moJpyPrice));
+ CPPUNIT_ASSERT(networth_f.m_grid["Asset"]["Japanese Checking"][acJpyChecking][eActual][4]==((moJpyOpening-moJpyTransaction-moJpyTransaction-moJpyTransaction)*moJpyPrice));
+
+ // test Fluctuating currency price, stable account balance
+ CPPUNIT_ASSERT(networth_f.m_grid["Asset"]["Japanese Checking"][acJpyChecking][eActual][5]==((moJpyOpening-moJpyTransaction-moJpyTransaction-moJpyTransaction)*moJpyPrice2));
+ CPPUNIT_ASSERT(networth_f.m_grid["Asset"]["Japanese Checking"][acJpyChecking][eActual][6]==((moJpyOpening-moJpyTransaction-moJpyTransaction-moJpyTransaction)*moJpyPrice3));
+ CPPUNIT_ASSERT(networth_f.m_grid["Asset"]["Japanese Checking"][acJpyChecking][eActual][7]==((moJpyOpening-moJpyTransaction-moJpyTransaction-moJpyTransaction)*moJpyPrice4));
+
+ // test multiple currencies totalled up
+ CPPUNIT_ASSERT(networth_f.m_grid["Asset"].m_total[eActual][4]==((moCanOpening-moCanTransaction-moCanTransaction-moCanTransaction)*moCanPrice)+((moJpyOpening-moJpyTransaction-moJpyTransaction-moJpyTransaction)*moJpyPrice));
+ CPPUNIT_ASSERT(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 );
+ CPPUNIT_ASSERT(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");
+
+ CPPUNIT_ASSERT(spending_f.m_grid["Expense"]["Parent"][acParent][eActual][11]==moThomas);
+ CPPUNIT_ASSERT(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 );
+ CPPUNIT_ASSERT(spending_f.m_grid["Expense"]["Parent"][acParent][eActual][11]==moNoPayee);
+ CPPUNIT_ASSERT(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(MyMoneyTransactionFilter::payments);
+ XMLandback(filter);
+ PivotTable spending_f( filter );
+
+ CPPUNIT_ASSERT(spending_f.m_grid.m_total[eActual].m_total == -moSolo);
+
+ filter.clear();
+ filter.addType(MyMoneyTransactionFilter::deposits);
+ XMLandback(filter);
+ PivotTable spending_f2( filter );
+
+ CPPUNIT_ASSERT(spending_f2.m_grid.m_total[eActual].m_total == moParent1);
+
+ filter.clear();
+ filter.addType(MyMoneyTransactionFilter::transfers);
+ XMLandback(filter);
+ PivotTable spending_f3( filter );
+
+ CPPUNIT_ASSERT(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 );
+
+ CPPUNIT_ASSERT(networth_f4.m_grid["Asset"].m_total[eActual][11] == moCheckingOpen + moChild);
+ CPPUNIT_ASSERT(networth_f4.m_grid["Liability"].m_total[eActual][11] == - moCreditOpen + moChild);
+ CPPUNIT_ASSERT(networth_f4.m_grid.m_total[eActual][10] == moCheckingOpen + moCreditOpen);
+ CPPUNIT_ASSERT(networth_f4.m_grid.m_total[eActual][11] == 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 );
+
+ QValueList<MyMoneySplit> splits = t1.splits();
+ splits[0].setReconcileFlag(MyMoneySplit::Cleared);
+ splits[1].setReconcileFlag(MyMoneySplit::Cleared);
+ t1.modifySplit(splits[0]);
+ t1.modifySplit(splits[1]);
+ t1.update();
+
+ splits.clear();
+ splits = t2.splits();
+ splits[0].setReconcileFlag(MyMoneySplit::Reconciled);
+ splits[1].setReconcileFlag(MyMoneySplit::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(MyMoneyTransactionFilter::cleared);
+ XMLandback(filter);
+ PivotTable spending_f( filter );
+
+ CPPUNIT_ASSERT(spending_f.m_grid.m_total[eActual].m_total==-moSolo);
+
+ filter.addState(MyMoneyTransactionFilter::reconciled);
+ XMLandback(filter);
+ PivotTable spending_f2( filter );
+
+ CPPUNIT_ASSERT(spending_f2.m_grid.m_total[eActual].m_total==-moSolo-moParent1);
+
+ filter.clear();
+ filter.addState(MyMoneyTransactionFilter::notReconciled);
+ XMLandback(filter);
+ PivotTable spending_f3( filter );
+
+ CPPUNIT_ASSERT(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 );
+
+ QValueList<MyMoneySplit> 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 );
+ CPPUNIT_ASSERT(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 );
+ CPPUNIT_ASSERT(spending_f.m_grid.m_total[eActual].m_total==-moSolo-moParent1-moParent2-moSolo-moParent1-moParent2);
+
+ filter.clear();
+ XMLandback(filter);
+ PivotTable spending_f2( filter );
+ CPPUNIT_ASSERT(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 );
+
+ CPPUNIT_ASSERT(spending_b.m_grid.m_total[eActual][1] == moZero);
+ CPPUNIT_ASSERT(spending_b.m_grid.m_total[eActual][2] == -moParent1-moSolo);
+ CPPUNIT_ASSERT(spending_b.m_grid.m_total[eActual][3] == -moParent2-moSolo);
+ CPPUNIT_ASSERT(spending_b.m_grid.m_total[eActual][4] == -moParent);
+ CPPUNIT_ASSERT(spending_b.m_grid.m_total[eActual][5] == moZero);
+ CPPUNIT_ASSERT(spending_b.m_grid.m_total[eActual][6] == moZero);
+ CPPUNIT_ASSERT(spending_b.m_grid.m_total[eActual][7] == moZero);
+ CPPUNIT_ASSERT(spending_b.m_grid.m_total[eActual][8] == -moSolo);
+ CPPUNIT_ASSERT(spending_b.m_grid.m_total[eActual][9] == moZero);
+ CPPUNIT_ASSERT(spending_b.m_grid.m_total[eActual][10] == -moParent1);
+ CPPUNIT_ASSERT(spending_b.m_grid.m_total[eActual][11] == moZero);
+ CPPUNIT_ASSERT(spending_b.m_grid.m_total[eActual][12] == -moParent2);
+ CPPUNIT_ASSERT(spending_b.m_grid.m_total[eActual][13] == moZero);
+
+ filter.setColumnType(MyMoneyReport::eQuarters);
+ XMLandback(filter);
+ PivotTable spending_q( filter );
+
+ CPPUNIT_ASSERT(spending_q.m_grid.m_total[eActual][1] == moZero);
+ CPPUNIT_ASSERT(spending_q.m_grid.m_total[eActual][2] == -moSolo-moParent);
+ CPPUNIT_ASSERT(spending_q.m_grid.m_total[eActual][3] == -moSolo-moParent);
+ CPPUNIT_ASSERT(spending_q.m_grid.m_total[eActual][4] == moZero);
+ CPPUNIT_ASSERT(spending_q.m_grid.m_total[eActual][5] == moZero);
+ CPPUNIT_ASSERT(spending_q.m_grid.m_total[eActual][6] == -moSolo);
+ CPPUNIT_ASSERT(spending_q.m_grid.m_total[eActual][7] == -moParent1);
+ CPPUNIT_ASSERT(spending_q.m_grid.m_total[eActual][8] == -moParent2);
+ CPPUNIT_ASSERT(spending_q.m_grid.m_total[eActual][9] == 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" );
+
+ CPPUNIT_ASSERT(networth_q.m_grid.m_total[eActual][1] == moZero);
+ CPPUNIT_ASSERT(networth_q.m_grid.m_total[eActual][2] == -moSolo-moParent);
+ CPPUNIT_ASSERT(networth_q.m_grid.m_total[eActual][3] == -moSolo-moParent-moSolo-moParent+moCheckingOpen);
+ CPPUNIT_ASSERT(networth_q.m_grid.m_total[eActual][4] == -moSolo-moParent-moSolo-moParent+moCheckingOpen+moCreditOpen);
+ CPPUNIT_ASSERT(networth_q.m_grid.m_total[eActual][5] == -moSolo-moParent-moSolo-moParent+moCheckingOpen+moCreditOpen);
+ CPPUNIT_ASSERT(networth_q.m_grid.m_total[eActual][6] == -moSolo-moSolo-moParent-moSolo-moParent+moCheckingOpen+moCreditOpen);
+ CPPUNIT_ASSERT(networth_q.m_grid.m_total[eActual][7] == -moParent1-moSolo-moSolo-moParent-moSolo-moParent+moCheckingOpen+moCreditOpen);
+ CPPUNIT_ASSERT(networth_q.m_grid.m_total[eActual][8] == -moParent2-moParent1-moSolo-moSolo-moParent-moSolo-moParent+moCheckingOpen+moCreditOpen);
+ CPPUNIT_ASSERT(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 );
+
+ CPPUNIT_ASSERT(spending_y.m_grid.m_total[eActual][1] == moZero);
+ CPPUNIT_ASSERT(spending_y.m_grid.m_total[eActual][2] == -moSolo-moParent-moSolo-moParent);
+ CPPUNIT_ASSERT(spending_y.m_grid.m_total[eActual][3] == -moSolo-moParent);
+ CPPUNIT_ASSERT(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 );
+
+ CPPUNIT_ASSERT(networth_y.m_grid.m_total[eActual][1] == moZero);
+ CPPUNIT_ASSERT(networth_y.m_grid.m_total[eActual][2] == -moSolo-moParent-moSolo-moParent+moCheckingOpen+moCreditOpen);
+ CPPUNIT_ASSERT(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,5), 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);
+
+ XMLandback(filter);
+ PivotTable spending_days( filter );
+ writeTabletoHTML(spending_days,"Spending by Days.html");
+
+ CPPUNIT_ASSERT(spending_days.m_grid.m_total[eActual][4] == -moParent2);
+ CPPUNIT_ASSERT(spending_days.m_grid.m_total[eActual][13] == -moSolo);
+ CPPUNIT_ASSERT(spending_days.m_grid.m_total[eActual].m_total == -moSolo-moParent2);
+
+ unsigned save_dayweekstart = KGlobal::locale()->weekStartDay();
+ KGlobal::locale()->setWeekStartDay(2);
+
+ filter.setDateFilter(QDate(2004,7,2),QDate(2004,8,1));
+ filter.setRowType( MyMoneyReport::eExpenseIncome );
+ filter.setColumnType(static_cast<MyMoneyReport::EColumnType>(7));
+ filter.setColumnsAreDays(true);
+
+ XMLandback(filter);
+ PivotTable spending_weeks( filter );
+ writeTabletoHTML(spending_weeks,"Spending by Weeks.html");
+
+ KGlobal::locale()->setWeekStartDay(save_dayweekstart);
+
+ CPPUNIT_ASSERT(spending_weeks.m_grid.m_total[eActual][0] == moZero);
+ CPPUNIT_ASSERT(spending_weeks.m_grid.m_total[eActual][1] == -moParent2);
+ CPPUNIT_ASSERT(spending_weeks.m_grid.m_total[eActual][2] == moZero);
+ CPPUNIT_ASSERT(spending_weeks.m_grid.m_total[eActual][3] == -moSolo-moParent1);
+ CPPUNIT_ASSERT(spending_weeks.m_grid.m_total[eActual][4] == -moParent2);
+ CPPUNIT_ASSERT(spending_weeks.m_grid.m_total[eActual][5] == moZero);
+ CPPUNIT_ASSERT(spending_weeks.m_grid.m_total[eActual].m_total == -moSolo-moParent-moParent2);
+
+
+}
+
+void PivotTableTest::testInvestment(void)
+{
+ try
+ {
+ // Equities
+ eqStock1 = makeEquity("Stock1","STK1");
+ eqStock2 = makeEquity("Stock2","STK2");
+
+ // Accounts
+ acInvestment = makeAccount("Investment",MyMoneyAccount::Investment,moZero,QDate(2004,1,1),acAsset);
+ acStock1 = makeAccount("Stock 1",MyMoneyAccount::Stock,moZero,QDate(2004,1,1),acInvestment,eqStock1);
+ acStock2 = makeAccount("Stock 2",MyMoneyAccount::Stock,moZero,QDate(2004,1,1),acInvestment,eqStock2);
+ acDividends = makeAccount("Dividends",MyMoneyAccount::Income,moZero,QDate(2004,1,1),acIncome);
+
+ // Transactions
+ // Date Action Shares Price Stock Asset Income
+ InvTransactionHelper s1b1( QDate(2004,2,1), MyMoneySplit::ActionBuyShares, 1000.00, 100.00, acStock1, acChecking, QString() );
+ InvTransactionHelper s1b2( QDate(2004,3,1), MyMoneySplit::ActionBuyShares, 1000.00, 110.00, acStock1, acChecking, QString() );
+ InvTransactionHelper s1s1( QDate(2004,4,1), MyMoneySplit::ActionBuyShares, -200.00, 120.00, acStock1, acChecking, QString() );
+ InvTransactionHelper s1s2( QDate(2004,5,1), MyMoneySplit::ActionBuyShares, -200.00, 100.00, acStock1, acChecking, QString() );
+ InvTransactionHelper s1r1( QDate(2004,6,1), MyMoneySplit::ActionReinvestDividend, 50.00, 100.00, acStock1, QString(), acDividends );
+ InvTransactionHelper s1r2( QDate(2004,7,1), MyMoneySplit::ActionReinvestDividend, 50.00, 80.00, acStock1, QString(), acDividends );
+ InvTransactionHelper s1c1( QDate(2004,8,1), MyMoneySplit::ActionDividend, 10.00, 100.00, acStock1, acChecking, acDividends );
+ InvTransactionHelper s1c2( QDate(2004,9,1), MyMoneySplit::ActionDividend, 10.00, 120.00, acStock1, acChecking, acDividends );
+
+ makeEquityPrice( eqStock1, QDate(2004,10,1), 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");
+
+ CPPUNIT_ASSERT(networth.m_grid["Asset"]["Investment"].m_total[eActual][1]==moZero);
+ // 1000 shares @ $100.00
+ CPPUNIT_ASSERT(networth.m_grid["Asset"]["Investment"].m_total[eActual][2]==MyMoneyMoney(100000.0));
+ // 2000 shares @ $110.00
+ CPPUNIT_ASSERT(networth.m_grid["Asset"]["Investment"].m_total[eActual][3]==MyMoneyMoney(220000.0));
+ // 1800 shares @ $120.00
+ CPPUNIT_ASSERT(networth.m_grid["Asset"]["Investment"].m_total[eActual][4]==MyMoneyMoney(216000.0));
+ // 1600 shares @ $100.00
+ CPPUNIT_ASSERT(networth.m_grid["Asset"]["Investment"].m_total[eActual][5]==MyMoneyMoney(160000.0));
+ // 1650 shares @ $100.00
+ CPPUNIT_ASSERT(networth.m_grid["Asset"]["Investment"].m_total[eActual][6]==MyMoneyMoney(165000.0));
+ // 1700 shares @ $ 80.00
+ CPPUNIT_ASSERT(networth.m_grid["Asset"]["Investment"].m_total[eActual][7]==MyMoneyMoney(136000.0));
+ // 1700 shares @ $100.00
+ CPPUNIT_ASSERT(networth.m_grid["Asset"]["Investment"].m_total[eActual][8]==MyMoneyMoney(170000.0));
+ // 1700 shares @ $120.00
+ CPPUNIT_ASSERT(networth.m_grid["Asset"]["Investment"].m_total[eActual][9]==MyMoneyMoney(204000.0));
+ // 1700 shares @ $100.00
+ CPPUNIT_ASSERT(networth.m_grid["Asset"]["Investment"].m_total[eActual][10]==MyMoneyMoney(170000.0));
+
+#if 0
+ // Dump file & reports
+ QFile g( "investmentkmy.xml" );
+ g.open( IO_WriteOnly );
+ MyMoneyStorageXML xml;
+ IMyMoneyStorageFormat& interface = xml;
+ interface.writeFile(&g, dynamic_cast<IMyMoneySerialize*> (MyMoneyFile::instance()->storage()));
+ g.close();
+
+ invtran.dump("invtran.html","<html><head></head><body>%1</body></html>");
+ invhold.dump("invhold.html","<html><head></head><body>%1</body></html>");
+#endif
+
+ }
+ catch(MyMoneyException *e)
+ {
+ CPPUNIT_FAIL(e->what());
+ delete e;
+ }
+}
+
+void PivotTableTest::testBudget(void)
+{
+
+ // 1. Budget on A, transations on A
+ {
+ BudgetHelper budget;
+ budget += BudgetEntryHelper( QDate(2006,1,1), acSolo, false, 100.0 );
+
+ MyMoneyReport report(MyMoneyReport::eBudgetActual,
+ MyMoneyReport::eMonths,
+ MyMoneyTransactionFilter::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, 100.0 );
+ MyMoneyReport report(MyMoneyReport::eBudgetActual,
+ MyMoneyReport::eMonths,
+ MyMoneyTransactionFilter::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, 100.0 );
+ MyMoneyReport report(MyMoneyReport::eBudgetActual,
+ MyMoneyReport::eMonths,
+ MyMoneyTransactionFilter::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, 100.0 );
+ budget += BudgetEntryHelper( QDate(2006,1,1), acChild, false, 100.0 );
+ budget += BudgetEntryHelper( QDate(2006,1,1), acSecondChild, true, 100.0 );
+ MyMoneyReport report(MyMoneyReport::eBudgetActual,
+ MyMoneyReport::eMonths,
+ MyMoneyTransactionFilter::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, 100.0 );
+ MyMoneyReport report(MyMoneyReport::eBudgetActual,
+ MyMoneyReport::eMonths,
+ MyMoneyTransactionFilter::yearToDate,
+ MyMoneyReport::eDetailTop,
+ "Yearly Budgeted vs. Actual","Default Report");
+ PivotTable table(report);
+ }
+}
+
+// vim:cin:si:ai:et:ts=2:sw=2: