summaryrefslogtreecommitdiffstats
path: root/kmymoney2/reports/reportaccount.cpp
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2011-07-04 22:38:03 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2011-07-04 22:38:03 +0000
commitdadc34655c3ab961b0b0b94a10eaaba710f0b5e8 (patch)
tree99e72842fe687baea16376a147619b6048d7e441 /kmymoney2/reports/reportaccount.cpp
downloadkmymoney-dadc34655c3ab961b0b0b94a10eaaba710f0b5e8.tar.gz
kmymoney-dadc34655c3ab961b0b0b94a10eaaba710f0b5e8.zip
Added kmymoney
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/kmymoney@1239792 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kmymoney2/reports/reportaccount.cpp')
-rw-r--r--kmymoney2/reports/reportaccount.cpp355
1 files changed, 355 insertions, 0 deletions
diff --git a/kmymoney2/reports/reportaccount.cpp b/kmymoney2/reports/reportaccount.cpp
new file mode 100644
index 0000000..5f7e7f8
--- /dev/null
+++ b/kmymoney2/reports/reportaccount.cpp
@@ -0,0 +1,355 @@
+/***************************************************************************
+ reportaccount.cpp
+ -------------------
+ begin : Mon May 17 2004
+ copyright : (C) 2004-2005 by Ace Jones
+ email : <ace.j@hotpop.com>
+ Thomas Baumgart <ipwizard@users.sourceforge.net>
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+// ----------------------------------------------------------------------------
+// QT Includes
+
+// ----------------------------------------------------------------------------
+// KDE Includes
+// This is just needed for i18n(). Once I figure out how to handle i18n
+// without using this macro directly, I'll be freed of KDE dependency. This
+// is a minor problem because we use these terms when rendering to HTML,
+// and a more major problem because we need it to translate account types
+// (e.g. MyMoneyAccount::Checkings) into their text representation. We also
+// use that text representation in the core data structure of the report. (Ace)
+
+#include <klocale.h>
+
+// ----------------------------------------------------------------------------
+// Project Includes
+
+#include "../mymoney/mymoneyfile.h"
+#include "../mymoney/mymoneysecurity.h"
+#include "reportdebug.h"
+#include "reportaccount.h"
+
+namespace reports {
+
+ReportAccount::ReportAccount( void )
+{
+}
+
+ReportAccount::ReportAccount( const ReportAccount& copy ):
+ MyMoneyAccount( copy ), m_nameHierarchy( copy.m_nameHierarchy )
+{
+ // NOTE: I implemented the copy constructor solely for debugging reasons
+
+ DEBUG_ENTER(__PRETTY_FUNCTION__);
+}
+
+ReportAccount::ReportAccount( const QString& accountid ):
+ MyMoneyAccount( MyMoneyFile::instance()->account(accountid) )
+{
+ DEBUG_ENTER(__PRETTY_FUNCTION__);
+ DEBUG_OUTPUT(QString("Account %1").arg(accountid));
+ calculateAccountHierarchy();
+}
+
+ReportAccount::ReportAccount( const MyMoneyAccount& account ):
+ MyMoneyAccount( account )
+{
+ DEBUG_ENTER(__PRETTY_FUNCTION__);
+ DEBUG_OUTPUT(QString("Account %1").arg(account.id()));
+ calculateAccountHierarchy();
+}
+
+void ReportAccount::calculateAccountHierarchy( void )
+{
+ DEBUG_ENTER(__PRETTY_FUNCTION__);
+
+ MyMoneyFile* file = MyMoneyFile::instance();
+ QString resultid = id();
+ QString parentid = parentAccountId();
+
+#ifdef DEBUG_HIDE_SENSITIVE
+ m_nameHierarchy.prepend(file->account(resultid).id());
+#else
+ m_nameHierarchy.prepend(file->account(resultid).name());
+#endif
+ while (!file->isStandardAccount(parentid))
+ {
+ // take on the identity of our parent
+ resultid = parentid;
+
+ // and try again
+ parentid = file->account(resultid).parentAccountId();
+#ifdef DEBUG_HIDE_SENSITIVE
+ m_nameHierarchy.prepend(file->account(resultid).id());
+#else
+ m_nameHierarchy.prepend(file->account(resultid).name());
+#endif
+ }
+}
+
+MyMoneyMoney ReportAccount::deepCurrencyPrice( const QDate& date ) const
+{
+ DEBUG_ENTER(__PRETTY_FUNCTION__);
+
+ MyMoneyMoney result(1, 1);
+ MyMoneyFile* file = MyMoneyFile::instance();
+
+ MyMoneySecurity undersecurity = file->security( currencyId() );
+ if ( ! undersecurity.isCurrency() )
+ {
+ MyMoneyPrice price = file->price(undersecurity.id(),undersecurity.tradingCurrency(),date);
+ if ( price.isValid() )
+ {
+ result = price.rate(undersecurity.tradingCurrency());
+
+ DEBUG_OUTPUT(QString("Converting under %1 to deep %2, price on %3 is %4")
+ .arg(undersecurity.name())
+ .arg(file->security(undersecurity.tradingCurrency()).name())
+ .arg(date.toString())
+ .arg(result.toDouble()));
+ }
+ else
+ {
+ DEBUG_OUTPUT(QString("No price to convert under %1 to deep %2 on %3")
+ .arg(undersecurity.name())
+ .arg(file->security(undersecurity.tradingCurrency()).name())
+ .arg(date.toString()));
+ }
+ }
+
+ return result;
+}
+
+MyMoneyMoney ReportAccount::baseCurrencyPrice( const QDate& date ) const
+{
+ // Note that whether or not the user chooses to convert to base currency, all the values
+ // for a given account/category are converted to the currency for THAT account/category
+ // The "Convert to base currency" tells the report to convert from the account/category
+ // currency to the file's base currency.
+ //
+ // An example where this matters is if Category 'C' and account 'U' are in USD, but
+ // Account 'J' is in JPY. Say there are two transactions, one is US$100 from U to C,
+ // the other is JPY10,000 from J to C. Given a JPY price of USD$0.01, this means
+ // C will show a balance of $200 NO MATTER WHAT the user chooses for 'convert to base
+ // currency. This confused me for a while, which is why I wrote this comment.
+ // --acejones
+
+ DEBUG_ENTER(__PRETTY_FUNCTION__);
+
+ MyMoneyMoney result(1, 1);
+ MyMoneyFile* file = MyMoneyFile::instance();
+
+ if(isForeignCurrency())
+ {
+ result = foreignCurrencyPrice(file->baseCurrency().id(), date);
+ }
+
+ return result;
+}
+
+MyMoneyMoney ReportAccount::foreignCurrencyPrice( const QString foreignCurrency, const QDate& date ) const
+{
+ DEBUG_ENTER(__PRETTY_FUNCTION__);
+
+ MyMoneyPrice price;
+ MyMoneyMoney result(1, 1);
+ MyMoneyFile* file = MyMoneyFile::instance();
+ MyMoneySecurity security = file->security(foreignCurrency);
+
+ //check whether it is a currency or a commodity. In the latter case case, get the trading currency
+ QString tradingCurrency;
+ if(security.isCurrency()) {
+ tradingCurrency = foreignCurrency;
+ } else {
+ tradingCurrency = security.tradingCurrency();
+ }
+
+ //It makes no sense to get the price if both currencies are the same
+ if(currency().id() != tradingCurrency) {
+ price = file->price(currency().id(), tradingCurrency, date);
+
+ if(price.isValid())
+ {
+ result = price.rate(tradingCurrency);
+ DEBUG_OUTPUT(QString("Converting deep %1 to currency %2, price on %3 is %4")
+ .arg(file->currency(currency().id()).name())
+ .arg(file->currency(foreignCurrency).name())
+ .arg(date.toString())
+ .arg(result.toDouble()));
+ }
+ else
+ {
+ DEBUG_OUTPUT(QString("No price to convert deep %1 to currency %2 on %3")
+ .arg(file->currency(currency().id()).name())
+ .arg(file->currency(foreignCurrency).name())
+ .arg(date.toString()));
+ }
+ }
+ return result;
+}
+
+/**
+ * Fetch the trading currency of this account's currency
+ *
+ * @return The account's currency trading currency
+ */
+MyMoneySecurity ReportAccount::currency( void ) const
+{
+ MyMoneyFile* file = MyMoneyFile::instance();
+
+ // First, get the deep currency
+ MyMoneySecurity deepcurrency = file->security( currencyId() );
+ if ( ! deepcurrency.isCurrency() )
+ deepcurrency = file->security( deepcurrency.tradingCurrency() );
+
+ // Return the deep currency's ID
+ return deepcurrency;
+}
+
+/**
+ * Determine if this account's deep currency is different from the file's
+ * base currency
+ *
+ * @return bool True if this account is in a foreign currency
+ */
+bool ReportAccount::isForeignCurrency( void ) const
+{
+ return ( currency().id() != MyMoneyFile::instance()->baseCurrency().id() );
+}
+
+bool ReportAccount::operator<(const ReportAccount& second) const
+{
+// DEBUG_ENTER(__PRETTY_FUNCTION__);
+
+ bool result = false;
+ bool haveresult = false;
+ QStringList::const_iterator it_first = m_nameHierarchy.begin();
+ QStringList::const_iterator it_second = second.m_nameHierarchy.begin();
+ while ( it_first != m_nameHierarchy.end() )
+ {
+ // The first string is longer than the second, but otherwise identical
+ if ( it_second == second.m_nameHierarchy.end() )
+ {
+ result = false;
+ haveresult = true;
+ break;
+ }
+
+ if ( (*it_first) < (*it_second) )
+ {
+ result = true;
+ haveresult = true;
+ break;
+ }
+ else if ( (*it_first) > (*it_second) )
+ {
+ result = false;
+ haveresult = true;
+ break;
+ }
+
+ ++it_first;
+ ++it_second;
+ }
+
+ // The second string is longer than the first, but otherwise identical
+ if ( !haveresult && ( it_second != second.m_nameHierarchy.end() ) )
+ result = true;
+
+// DEBUG_OUTPUT(QString("%1 < %2 is %3").arg(debugName(),second.debugName()).arg(result));
+ return result;
+}
+
+/**
+ * The name of only this account. No matter how deep the hierarchy, this
+ * method only returns the last name in the list, which is the engine name]
+ * of this account.
+ *
+ * @return QString The account's name
+ */
+QString ReportAccount::name( void ) const
+{
+ return m_nameHierarchy.back();
+}
+
+// MyMoneyAccount:fullHierarchyDebug()
+QString ReportAccount::debugName( void ) const
+{
+ return m_nameHierarchy.join("|");
+}
+
+// MyMoneyAccount:fullHierarchy()
+QString ReportAccount::fullName( void ) const
+{
+ return m_nameHierarchy.join(": ");
+}
+
+// MyMoneyAccount:isTopCategory()
+bool ReportAccount::isTopLevel( void ) const
+{
+ return ( m_nameHierarchy.size() == 1 );
+}
+
+// MyMoneyAccount:hierarchyDepth()
+unsigned ReportAccount::hierarchyDepth( void ) const
+{
+ return ( m_nameHierarchy.size() );
+}
+
+ReportAccount ReportAccount::parent( void ) const
+{
+ return ReportAccount( parentAccountId() );
+}
+
+ReportAccount ReportAccount::topParent( void ) const
+{
+ DEBUG_ENTER(__PRETTY_FUNCTION__);
+
+ MyMoneyFile* file = MyMoneyFile::instance();
+ QString resultid = id();
+ QString parentid = parentAccountId();
+
+ while (!file->isStandardAccount(parentid))
+ {
+ // take on the identity of our parent
+ resultid = parentid;
+
+ // and try again
+ parentid = file->account(resultid).parentAccountId();
+ }
+
+ return ReportAccount( resultid );
+}
+
+QString ReportAccount::topParentName( void ) const
+{
+ return m_nameHierarchy.first();
+}
+
+bool ReportAccount::isLiquidAsset( void ) const
+{
+ return accountType() == MyMoneyAccount::Cash ||
+ accountType() == MyMoneyAccount::Checkings ||
+ accountType() == MyMoneyAccount::Savings;
+}
+
+
+bool ReportAccount::isLiquidLiability( void ) const
+{
+ return accountType() == MyMoneyAccount::CreditCard;
+
+}
+
+
+
+
+} // end namespace reports