/*************************************************************************** reportstestcommon.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 <tqvaluelist.h> #include <tqvaluevector.h> #include <tqdom.h> #include <tqfile.h> #include <kdebug.h> #include <kdeversion.h> #include <kglobal.h> #include <kglobalsettings.h> #include <klocale.h> #include <kstandarddirs.h> #include "kreportsviewtest.h" #define private public #include "pivottable.h" #include "tquerytable.h" #undef private using namespace reports; #include "../mymoney/mymoneysecurity.h" #include "../mymoney/mymoneyprice.h" #include "../mymoney/storage/mymoneystoragedump.h" #include "../mymoney/mymoneyreport.h" #include "../mymoney/mymoneystatement.h" #include "../mymoney/storage/mymoneystoragexml.h" #include "reportstestcommon.h" namespace test { const MyMoneyMoney moCheckingOpen(0.0); const MyMoneyMoney moCreditOpen(-0.0); const MyMoneyMoney moConverterCheckingOpen(1418.0); const MyMoneyMoney moConverterCreditOpen(-418.0); const MyMoneyMoney moZero(0.0); const MyMoneyMoney moSolo(234.12); const MyMoneyMoney moParent1(88.01); const MyMoneyMoney moParent2(133.22); const MyMoneyMoney moParent(moParent1+moParent2); const MyMoneyMoney moChild(14.00); const MyMoneyMoney moThomas(5.11); const MyMoneyMoney moNoPayee(8944.70); TQString acAsset; TQString acLiability; TQString acExpense; TQString acIncome; TQString acChecking; TQString acCredit; TQString acSolo; TQString acParent; TQString acChild; TQString acSecondChild; TQString acGrandChild1; TQString acGrandChild2; TQString acForeign; TQString acCanChecking; TQString acJpyChecking; TQString acCanCash; TQString acJpyCash; TQString inBank; TQString eqStock1; TQString eqStock2; TQString acInvestment; TQString acStock1; TQString acStock2; TQString acDividends; TQString acInterest; TQString acTax; TQString acCash; TransactionHelper::TransactionHelper( const TQDate& _date, const TQString& _action, MyMoneyMoney _value, const TQString& _accountid, const TQString& _categoryid, const TQString& _currencyid, const TQString& _payee ) { // _currencyid is the currency of the transaction, and of the _value // both the account and category can have their own currency (athough the category having // a foreign currency is not yet supported by the program, the reports will still allow it, // so it must be tested.) MyMoneyFile* file = MyMoneyFile::instance(); bool haspayee = ! _payee.isEmpty(); MyMoneyPayee payeeTest = file->payeeByName(_payee); MyMoneyFileTransaction ft; setPostDate(_date); TQString currencyid = _currencyid; if ( currencyid.isEmpty() ) currencyid=MyMoneyFile::instance()->baseCurrency().id(); setCommodity(currencyid); MyMoneyMoney price; MyMoneySplit splitLeft; if ( haspayee ) splitLeft.setPayeeId(payeeTest.id()); splitLeft.setAction(_action); splitLeft.setValue(-_value); price = MyMoneyFile::instance()->price(currencyid, file->account(_accountid).currencyId(),_date).rate(file->account(_accountid).currencyId()); splitLeft.setShares(-_value * price); splitLeft.setAccountId(_accountid); addSplit(splitLeft); MyMoneySplit splitRight; if ( haspayee ) splitRight.setPayeeId(payeeTest.id()); splitRight.setAction(_action); splitRight.setValue(_value); price = MyMoneyFile::instance()->price(currencyid, file->account(_categoryid).currencyId(),_date).rate(file->account(_categoryid).currencyId()); splitRight.setShares(_value * price ); splitRight.setAccountId(_categoryid); addSplit(splitRight); MyMoneyFile::instance()->addTransaction(*this); ft.commit(); } TransactionHelper::~TransactionHelper() { MyMoneyFileTransaction ft; MyMoneyFile::instance()->removeTransaction(*this); ft.commit(); } void TransactionHelper::update(void) { MyMoneyFileTransaction ft; MyMoneyFile::instance()->modifyTransaction(*this); ft.commit(); } InvTransactionHelper::InvTransactionHelper( const TQDate& _date, const TQString& _action, MyMoneyMoney _shares, MyMoneyMoney _price, const TQString& _stockaccountid, const TQString& _transferid, const TQString& _categoryid ) { init(_date, _action, _shares, _price, _stockaccountid, _transferid, _categoryid); } void InvTransactionHelper::init( const TQDate& _date, const TQString& _action, MyMoneyMoney _shares, MyMoneyMoney _price, const TQString& _stockaccountid, const TQString& _transferid, const TQString& _categoryid ) { MyMoneyFile* file = MyMoneyFile::instance(); MyMoneyAccount stockaccount = file->account(_stockaccountid); MyMoneyMoney value = _shares * _price; setPostDate(_date); setCommodity("USD"); MyMoneySplit s1; s1.setValue(value); s1.setAccountId(_stockaccountid); if ( _action == MyMoneySplit::ActionReinvestDividend ) { s1.setShares(_shares); s1.setAction(MyMoneySplit::ActionReinvestDividend); MyMoneySplit s2; s2.setAccountId(_categoryid); s2.setShares(-value); s2.setValue(-value); addSplit(s2); } else if ( _action == MyMoneySplit::ActionDividend || _action == MyMoneySplit::ActionYield ) { s1.setAccountId(_categoryid); s1.setShares(-value); s1.setValue(-value); // Split 2 will be the zero-amount investment split that serves to // mark this transaction as a cash dividend and note which stock account // it belongs to. MyMoneySplit s2; s2.setValue(0); s2.setShares(0); s2.setAction(_action); s2.setAccountId(_stockaccountid); addSplit(s2); MyMoneySplit s3; s3.setAccountId(_transferid); s3.setShares(value); s3.setValue(value); addSplit(s3); } else if ( _action == MyMoneySplit::ActionBuyShares ) { s1.setShares(_shares); s1.setAction(MyMoneySplit::ActionBuyShares); MyMoneySplit s3; s3.setAccountId(_transferid); s3.setShares(-value); s3.setValue(-value); addSplit(s3); } addSplit(s1); //kdDebug(2) << "created transaction, now adding..." << endl; MyMoneyFileTransaction ft; file->addTransaction(*this); //kdDebug(2) << "updating price..." << endl; // update the price, while we're here TQString stockid = stockaccount.currencyId(); TQString basecurrencyid = file->baseCurrency().id(); MyMoneyPrice price = file->price( stockid, basecurrencyid, _date, true ); if ( !price.isValid() ) { MyMoneyPrice newprice( stockid, basecurrencyid, _date, _price, "test" ); file->addPrice(newprice); } ft.commit(); //kdDebug(2) << "successfully added " << id() << endl; } TQString makeAccount( const TQString& _name, MyMoneyAccount::accountTypeE _type, MyMoneyMoney _balance, const TQDate& _open, const TQString& _parent, TQString _currency, bool _taxReport ) { MyMoneyAccount info; MyMoneyFileTransaction ft; info.setName(_name); info.setAccountType(_type); info.setOpeningDate(_open); if ( _currency != "" ) info.setCurrencyId(_currency); else info.setCurrencyId(MyMoneyFile::instance()->baseCurrency().id()); if(_taxReport) info.setValue("Tax", "Yes"); MyMoneyAccount parent = MyMoneyFile::instance()->account(_parent); MyMoneyFile::instance()->addAccount( info, parent ); // create the opening balance transaction if any if(!_balance.isZero()) { MyMoneySecurity sec = MyMoneyFile::instance()->currency(info.currencyId()); MyMoneyFile::instance()->openingBalanceAccount(sec); MyMoneyFile::instance()->createOpeningBalanceTransaction(info, _balance); } ft.commit(); return info.id(); } void makePrice(const TQString& _currencyid, const TQDate& _date, const MyMoneyMoney& _price ) { MyMoneyFileTransaction ft; MyMoneyFile* file = MyMoneyFile::instance(); MyMoneySecurity curr = file->currency(_currencyid); MyMoneyPrice price(_currencyid, file->baseCurrency().id(), _date, _price, "test"); file->addPrice(price); ft.commit(); } TQString makeEquity(const TQString& _name, const TQString& _symbol ) { MyMoneySecurity equity; MyMoneyFileTransaction ft; equity.setName( _name ); equity.setTradingSymbol( _symbol ); equity.setSmallestAccountFraction( 1000 ); equity.setSecurityType( MyMoneySecurity::SECURITY_NONE /*MyMoneyEquity::ETYPE_STOCK*/ ); MyMoneyFile::instance()->addSecurity( equity ); ft.commit(); return equity.id(); } void makeEquityPrice(const TQString& _id, const TQDate& _date, const MyMoneyMoney& _price ) { MyMoneyFile* file = MyMoneyFile::instance(); MyMoneyFileTransaction ft; TQString basecurrencyid = file->baseCurrency().id(); MyMoneyPrice price = file->price( _id, basecurrencyid, _date, true ); if ( !price.isValid() ) { MyMoneyPrice newprice( _id, basecurrencyid, _date, _price, "test" ); file->addPrice(newprice); } ft.commit(); } void writeRCFtoXMLDoc( const MyMoneyReport& filter, TQDomDocument* doc ) { TQDomProcessingInstruction instruct = doc->createProcessingInstruction(TQString("xml"), TQString("version=\"1.0\" encoding=\"utf-8\"")); doc->appendChild(instruct); TQDomElement root = doc->createElement("KMYMONEY-FILE"); doc->appendChild(root); TQDomElement reports = doc->createElement("REPORTS"); root.appendChild(reports); TQDomElement report = doc->createElement("REPORT"); filter.write(report,doc); reports.appendChild(report); } void writeTabletoHTML( const PivotTable& table, const TQString& _filename ) { static unsigned filenumber = 1; TQString filename = _filename; if ( filename.isEmpty() ) { filename = TQString("report-%1%2.html").tqarg((filenumber<10)?"0":"").tqarg(filenumber); ++filenumber; } TQFile g( filename ); g.open( IO_WriteOnly ); TQTextStream(&g) << table.renderHTML(); g.close(); } void writeTabletoHTML( const QueryTable& table, const TQString& _filename ) { static unsigned filenumber = 1; TQString filename = _filename; if ( filename.isEmpty() ) { filename = TQString("report-%1%2.html").tqarg((filenumber<10)?"0":"").tqarg(filenumber); ++filenumber; } TQFile g( filename ); g.open( IO_WriteOnly ); TQTextStream(&g) << table.renderHTML(); g.close(); } void writeTabletoCSV( const PivotTable& table, const TQString& _filename ) { static unsigned filenumber = 1; TQString filename = _filename; if ( filename.isEmpty() ) { filename = TQString("report-%1%2.csv").tqarg((filenumber<10)?"0":"").tqarg(filenumber); ++filenumber; } TQFile g( filename ); g.open( IO_WriteOnly ); TQTextStream(&g) << table.renderCSV(); g.close(); } void writeTabletoCSV( const QueryTable& table, const TQString& _filename ) { static unsigned filenumber = 1; TQString filename = _filename; if ( filename.isEmpty() ) { filename = TQString("qreport-%1%2.csv").tqarg((filenumber<10)?"0":"").tqarg(filenumber); ++filenumber; } TQFile g( filename ); g.open( IO_WriteOnly ); TQTextStream(&g) << table.renderCSV(); g.close(); } void writeRCFtoXML( const MyMoneyReport& filter, const TQString& _filename ) { static unsigned filenum = 1; TQString filename = _filename; if ( filename.isEmpty() ) { filename = TQString("report-%1%2.xml").tqarg(TQString::number(filenum).rightJustify(2, '0')); ++filenum; } TQDomDocument* doc = new TQDomDocument("KMYMONEY-FILE"); Q_CHECK_PTR(doc); writeRCFtoXMLDoc(filter,doc); TQFile g( filename ); g.open( IO_WriteOnly ); TQTextStream stream(&g); #if KDE_IS_VERSION(3,2,0) stream.setEncoding(TQTextStream::UnicodeUTF8); stream << doc->toString(); #else //stream.setEncoding(TQTextStream::Locale); TQString temp = doc->toString(); stream << temp.data(); #endif g.close(); delete doc; } bool readRCFfromXMLDoc( TQValueList<MyMoneyReport>& list, TQDomDocument* doc ) { bool result = false; TQDomElement rootElement = doc->documentElement(); if(!rootElement.isNull()) { TQDomNode child = rootElement.firstChild(); while(!child.isNull() && child.isElement()) { TQDomElement childElement = child.toElement(); if("REPORTS" == childElement.tagName()) { result = true; TQDomNode subchild = child.firstChild(); while(!subchild.isNull() && subchild.isElement()) { MyMoneyReport filter; if ( filter.read(subchild.toElement())) { list += filter; } subchild = subchild.nextSibling(); } } child = child.nextSibling(); } } return result; } bool readRCFfromXML( TQValueList<MyMoneyReport>& list, const TQString& filename ) { int result = false; TQFile f( filename ); f.open( IO_ReadOnly ); TQDomDocument* doc = new TQDomDocument; if(doc->setContent(&f, FALSE)) { result = readRCFfromXMLDoc(list,doc); } delete doc; return result; } void XMLandback( MyMoneyReport& filter ) { // this function writes the filter to XML, and then reads // it back from XML overwriting the original filter; // in all cases, the result should be the same if the read // & write methods are working correctly. TQDomDocument* doc = new TQDomDocument("KMYMONEY-FILE"); Q_CHECK_PTR(doc); writeRCFtoXMLDoc(filter,doc); TQValueList<MyMoneyReport> list; if ( readRCFfromXMLDoc(list,doc) && list.count() > 0 ) filter = list[0]; else throw new MYMONEYEXCEPTION("Failed to load report from XML"); delete doc; } MyMoneyMoney searchHTML(const TQString& _html, const TQString& _search) { TQRegExp re(TQString("%1[<>/td]*([\\-.0-9,]*)").tqarg(_search)); re.search(_html); TQString found = re.cap(1); found.remove(','); return MyMoneyMoney(found.toDouble()); } } // end namespace test // vim:cin:si:ai:et:ts=2:sw=2: