diff options
Diffstat (limited to 'kmymoney2/kmymoneyutils.cpp')
-rw-r--r-- | kmymoney2/kmymoneyutils.cpp | 480 |
1 files changed, 480 insertions, 0 deletions
diff --git a/kmymoney2/kmymoneyutils.cpp b/kmymoney2/kmymoneyutils.cpp new file mode 100644 index 0000000..83cf113 --- /dev/null +++ b/kmymoney2/kmymoneyutils.cpp @@ -0,0 +1,480 @@ +/*************************************************************************** + kmymoneyutils.cpp - description + ------------------- + begin : Wed Feb 5 2003 + copyright : (C) 2000-2003 by Michael Edwardes + email : mte@users.sourceforge.net + Javier Campos Morales <javi_c@users.sourceforge.net> + Felix Rodriguez <frodriguez@users.sourceforge.net> + John C <thetacoturtle@users.sourceforge.net> + Thomas Baumgart <ipwizard@users.sourceforge.net> + Kevin Tambascio <ktambascio@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 Headers + +#include <klocale.h> +#include <kglobal.h> +#include <kiconloader.h> +#include <kmessagebox.h> +#include <kconfig.h> +#include <kstandarddirs.h> + +// ---------------------------------------------------------------------------- +// Project Includes + +#include <kmymoney/mymoneyfile.h> +#include <kmymoney/mymoneyforecast.h> +#include <kmymoney/kmymoneyglobalsettings.h> +#include <kmymoney/investtransactioneditor.h> + +#include "kmymoneyutils.h" + +KMyMoneyUtils::KMyMoneyUtils() +{ +} + +KMyMoneyUtils::~KMyMoneyUtils() +{ +} + +const QString KMyMoneyUtils::accountTypeToString(const MyMoneyAccount::accountTypeE accountType) +{ + return MyMoneyAccount::accountTypeToString(accountType); +} + +MyMoneyAccount::accountTypeE KMyMoneyUtils::stringToAccountType(const QString& type) +{ + MyMoneyAccount::accountTypeE rc = MyMoneyAccount::UnknownAccountType; + QString tmp = type.lower(); + + if(tmp == i18n("Checking").lower()) + rc = MyMoneyAccount::Checkings; + else if(tmp == i18n("Savings").lower()) + rc = MyMoneyAccount::Savings; + else if(tmp == i18n("Credit Card").lower()) + rc = MyMoneyAccount::CreditCard; + else if(tmp == i18n("Cash").lower()) + rc = MyMoneyAccount::Cash; + else if(tmp == i18n("Loan").lower()) + rc = MyMoneyAccount::Loan; + else if(tmp == i18n("Certificate of Deposit").lower()) + rc = MyMoneyAccount::CertificateDep; + else if(tmp == i18n("Investment").lower()) + rc = MyMoneyAccount::Investment; + else if(tmp == i18n("Money Market").lower()) + rc = MyMoneyAccount::MoneyMarket; + else if(tmp == i18n("Asset").lower()) + rc = MyMoneyAccount::Asset; + else if(tmp == i18n("Liability").lower()) + rc = MyMoneyAccount::Liability; + else if(tmp == i18n("Currency").lower()) + rc = MyMoneyAccount::Currency; + else if(tmp == i18n("Income").lower()) + rc = MyMoneyAccount::Income; + else if(tmp == i18n("Expense").lower()) + rc = MyMoneyAccount::Expense; + else if(tmp == i18n("Investment Loan").lower()) + rc = MyMoneyAccount::AssetLoan; + else if(tmp == i18n("Stock").lower()) + rc = MyMoneyAccount::Stock; + else if(tmp == i18n("Equity").lower()) + rc = MyMoneyAccount::Equity; + + return rc; +} + +MyMoneySecurity::eSECURITYTYPE KMyMoneyUtils::stringToSecurity(const QString& txt) +{ + MyMoneySecurity::eSECURITYTYPE rc = MyMoneySecurity::SECURITY_NONE; + QString tmp = txt.lower(); + + if(tmp == i18n("Stock").lower()) + rc = MyMoneySecurity::SECURITY_STOCK; + else if(tmp == i18n("Mutual Fund").lower()) + rc = MyMoneySecurity::SECURITY_MUTUALFUND; + else if(tmp == i18n("Bond").lower()) + rc = MyMoneySecurity::SECURITY_BOND; + else if(tmp == i18n("Currency").lower()) + rc = MyMoneySecurity::SECURITY_CURRENCY; + + return rc; +} + +const QString KMyMoneyUtils::securityTypeToString(const MyMoneySecurity::eSECURITYTYPE securityType) +{ + return i18n(MyMoneySecurity::securityTypeToString(securityType)); +} + +const QString KMyMoneyUtils::occurenceToString(const MyMoneySchedule::occurenceE occurence) +{ + return i18n(MyMoneySchedule::occurenceToString(occurence)); +} + +const QString KMyMoneyUtils::paymentMethodToString(MyMoneySchedule::paymentTypeE paymentType) +{ + return i18n(MyMoneySchedule::paymentMethodToString(paymentType)); +} + +const QString KMyMoneyUtils::weekendOptionToString(MyMoneySchedule::weekendOptionE weekendOption) +{ + return i18n(MyMoneySchedule::weekendOptionToString(weekendOption)); +} + +const QString KMyMoneyUtils::scheduleTypeToString(MyMoneySchedule::typeE type) +{ + return i18n(MyMoneySchedule::scheduleTypeToString(type)); +} + +KGuiItem KMyMoneyUtils::scheduleNewGuiItem(void) +{ + KIconLoader *ic = KGlobal::iconLoader(); + + KGuiItem splitGuiItem( i18n("&New Schedule..."), + QIconSet(ic->loadIcon("filenew", KIcon::Small, KIcon::SizeSmall)), + i18n("Create a new schedule."), + i18n("Use this to create a new schedule.")); + + return splitGuiItem; +} + +KGuiItem KMyMoneyUtils::accountsFilterGuiItem(void) +{ + KIconLoader *ic = KGlobal::iconLoader(); + + KGuiItem splitGuiItem( i18n("&Filter"), + QIconSet(ic->loadIcon("filter", KIcon::Small, KIcon::SizeSmall)), + i18n("Filter out accounts"), + i18n("Use this to filter out accounts")); + + return splitGuiItem; +} + +QPixmap KMyMoneyUtils::billScheduleIcon(int size) +{ + KIconLoader *ic = KGlobal::iconLoader(); + return ic->loadIcon("billschedule", KIcon::User, size); +} + +QPixmap KMyMoneyUtils::depositScheduleIcon(int size) +{ + KIconLoader *ic = KGlobal::iconLoader(); + return ic->loadIcon("depositschedule", KIcon::User, size); +} + +QPixmap KMyMoneyUtils::transferScheduleIcon(int size) +{ + KIconLoader *ic = KGlobal::iconLoader(); + return ic->loadIcon("transferschedule", KIcon::User, size); +} + +QPixmap KMyMoneyUtils::scheduleIcon(int size) +{ + KIconLoader *ic = KGlobal::iconLoader(); + return ic->loadIcon("schedule", KIcon::User, size); +} + +const char* homePageItems[] = { + I18N_NOOP("Payments"), + I18N_NOOP("Preferred accounts"), + I18N_NOOP("Payment accounts"), + I18N_NOOP("Favorite reports"), + I18N_NOOP("Forecast (schedule)"), + I18N_NOOP("Networth forecast"), + I18N_NOOP("Forecast (history)"), + I18N_NOOP("Assets and Liabilities"), + I18N_NOOP("Budget"), + I18N_NOOP("CashFlow"), + // insert new items above this comment + 0 +}; + +const QString KMyMoneyUtils::homePageItemToString(const int idx) +{ + QString rc; + if(abs(idx) > 0 && abs(idx) < static_cast<int>(sizeof(homePageItems)/sizeof(homePageItems[0]))) { + rc = i18n(homePageItems[abs(idx-1)]); + } + return rc; +} + +int KMyMoneyUtils::stringToHomePageItem(const QString& txt) +{ + int idx = 0; + for(idx = 0; homePageItems[idx] != 0; ++idx) { + if(txt == i18n(homePageItems[idx])) + return idx+1; + } + return 0; +} + +bool KMyMoneyUtils::appendCorrectFileExt(QString& str, const QString& strExtToUse) +{ + bool rc = false; + + if(!str.isEmpty()) { + //find last . delminator + int nLoc = str.findRev('.'); + if(nLoc != -1) { + QString strExt, strTemp; + strTemp = str.left(nLoc + 1); + strExt = str.right(str.length() - (nLoc + 1)); + if(strExt.find(strExtToUse, 0, FALSE) == -1) { + // if the extension given contains a period, we remove our's + if(strExtToUse.find('.') != -1) + strTemp = strTemp.left(strTemp.length()-1); + //append extension to make complete file name + strTemp.append(strExtToUse); + str = strTemp; + rc = true; + } + } else { + str.append("."); + str.append(strExtToUse); + rc = true; + } + } + return rc; +} + +void KMyMoneyUtils::checkConstants(void) +{ + Q_ASSERT(static_cast<int>(KLocale::ParensAround) == static_cast<int>(MyMoneyMoney::ParensAround)); + Q_ASSERT(static_cast<int>(KLocale::BeforeQuantityMoney) == static_cast<int>(MyMoneyMoney::BeforeQuantityMoney)); + Q_ASSERT(static_cast<int>(KLocale::AfterQuantityMoney) == static_cast<int>(MyMoneyMoney::AfterQuantityMoney)); + Q_ASSERT(static_cast<int>(KLocale::BeforeMoney) == static_cast<int>(MyMoneyMoney::BeforeMoney)); + Q_ASSERT(static_cast<int>(KLocale::AfterMoney) == static_cast<int>(MyMoneyMoney::AfterMoney)); +} + +QString KMyMoneyUtils::variableCSS(void) +{ + QColor tcolor = KGlobalSettings::textColor(); + + QString css; + css += "<style type=\"text/css\">\n<!--\n"; + css += QString(".row-even, .item0 { background-color: %1; color: %2 }\n") + .arg((KMyMoneyGlobalSettings::listBGColor()).name()).arg(tcolor.name()); + css += QString(".row-odd, .item1 { background-color: %1; color: %2 }\n") + .arg((KMyMoneyGlobalSettings::listColor()).name()).arg(tcolor.name()); + css += "-->\n</style>\n"; + return css; +} + +QString KMyMoneyUtils::findResource(const char* type, const QString& filename) +{ + QString language = KGlobal::locale()->language(); + QString country = KGlobal::locale()->country(); + QString rc, mask; + + // check that the placeholder is present + if(!filename.find("%1")) { + qWarning("%%1 not found in '%s'", filename.latin1()); + return filename; + } + + // search the given resource + mask = filename.arg("_%1.%2"); + rc = KGlobal::dirs()->findResource(type, mask.arg(country).arg(language)); + if(rc.isEmpty()) { + mask = filename.arg("_%1"); + rc = KGlobal::dirs()->findResource(type, mask.arg(language)); + } + if(rc.isEmpty()) { + // qDebug(QString("html/home_%1.html not found").arg(country).latin1()); + rc = KGlobal::dirs()->findResource(type, mask.arg(country)); + } + if(rc.isEmpty()) { + rc = KGlobal::dirs()->findResource(type, filename.arg("")); + } + + if(rc.isEmpty()) { + qWarning("No resource found for (%s,%s)", type, filename.latin1()); + } + return rc; +} + +const MyMoneySplit KMyMoneyUtils::stockSplit(const MyMoneyTransaction& t) +{ + QValueList<MyMoneySplit>::ConstIterator it_s; + MyMoneySplit investmentAccountSplit; + for(it_s = t.splits().begin(); it_s != t.splits().end(); ++it_s) { + if(!(*it_s).accountId().isEmpty()) { + MyMoneyAccount acc = MyMoneyFile::instance()->account((*it_s).accountId()); + if(acc.isInvest()) { + return *it_s; + } + // if we have a reference to an investment account, we remember it here + if(acc.accountType() == MyMoneyAccount::Investment) + investmentAccountSplit = *it_s; + } + } + // if we haven't found a stock split, we see if we've seen + // an investment account on the way. If so, we return it. + if(!investmentAccountSplit.id().isEmpty()) + return investmentAccountSplit; + + // if none was found, we return an empty split. + return MyMoneySplit(); +} + +KMyMoneyUtils::transactionTypeE KMyMoneyUtils::transactionType(const MyMoneyTransaction& t) +{ + if(!stockSplit(t).id().isEmpty()) + return InvestmentTransaction; + + if(t.splitCount() < 2) { + return Unknown; + } else if(t.splitCount() > 2) { + // FIXME check for loan transaction here + return SplitTransaction; + } + QString ida, idb; + ida = t.splits()[0].accountId(); + idb = t.splits()[1].accountId(); + if(ida.isEmpty() || idb.isEmpty()) + return Unknown; + + MyMoneyAccount a, b; + a = MyMoneyFile::instance()->account(ida); + b = MyMoneyFile::instance()->account(idb); + if((a.accountGroup() == MyMoneyAccount::Asset + || a.accountGroup() == MyMoneyAccount::Liability) + && (b.accountGroup() == MyMoneyAccount::Asset + || b.accountGroup() == MyMoneyAccount::Liability)) + return Transfer; + return Normal; +} + +void KMyMoneyUtils::calculateAutoLoan(const MyMoneySchedule& schedule, MyMoneyTransaction& transaction, const QMap<QString, MyMoneyMoney>& balances) +{ + try { + MyMoneyForecast::calculateAutoLoan(schedule, transaction, balances); + } catch (MyMoneyException* e) { + KMessageBox::detailedError(0, i18n("Unable to load schedule details"), e->what()); + delete e; + } +} + +QString KMyMoneyUtils::nextCheckNumber(const MyMoneyAccount& acc) +{ + // determine next check number + QString number; + QRegExp exp(QString("(.*\\D)?(\\d+)(\\D.*)?")); + if(exp.search(acc.value("lastNumberUsed")) != -1) { + number = QString("%1%2%3").arg(exp.cap(1)).arg(exp.cap(2).toULongLong() + 1).arg(exp.cap(3)); + } else { + number = "1"; + } + return number; +} + +QString KMyMoneyUtils::reconcileStateToString(MyMoneySplit::reconcileFlagE flag, bool text) +{ + QString txt; + if(text) { + switch(flag) { + case MyMoneySplit::NotReconciled: + txt = i18n("Reconcile state 'Not reconciled'", "Not reconciled"); + break; + case MyMoneySplit::Cleared: + txt = i18n("Reconcile state 'Cleared'", "Cleared"); + break; + case MyMoneySplit::Reconciled: + txt = i18n("Reconcile state 'Reconciled'", "Reconciled"); + break; + case MyMoneySplit::Frozen: + txt = i18n("Reconcile state 'Frozen'", "Frozen"); + break; + default: + txt = i18n("Unknown"); + break; + } + } else { + switch(flag) { + case MyMoneySplit::NotReconciled: + break; + case MyMoneySplit::Cleared: + txt = i18n("Reconcile flag C", "C"); + break; + case MyMoneySplit::Reconciled: + txt = i18n("Reconcile flag R", "R"); + break; + case MyMoneySplit::Frozen: + txt = i18n("Reconcile flag F", "F"); + break; + default: + txt = i18n("Flag for unknown reconciliation state", "?"); + break; + } + } + return txt; +} + +MyMoneyTransaction KMyMoneyUtils::scheduledTransaction(const MyMoneySchedule& schedule) +{ + MyMoneyTransaction t = schedule.transaction(); + + try { + if (schedule.type() == MyMoneySchedule::TYPE_LOANPAYMENT) { + calculateAutoLoan(schedule, t, QMap<QString, MyMoneyMoney>()); + } + } catch (MyMoneyException* e) { + qDebug("Unable to load schedule details for '%s' during transaction match: %s", schedule.name().data(), e->what().data()); + delete e; + } + + t.clearId(); + t.setEntryDate(QDate()); + return t; +} + +void KMyMoneyUtils::previouslyUsedCategories(const QString& investmentAccount, QString& feesId, QString& interestId) +{ + feesId = interestId = QString(); + MyMoneyFile* file = MyMoneyFile::instance(); + try { + MyMoneyAccount acc = file->account(investmentAccount); + MyMoneyTransactionFilter filter(investmentAccount); + filter.setReportAllSplits(false); + // since we assume an investment account here, we need to collect the stock accounts as well + filter.addAccount(acc.accountList()); + QValueList< QPair<MyMoneyTransaction, MyMoneySplit> > list; + file->transactionList(list, filter); + QValueList< QPair<MyMoneyTransaction, MyMoneySplit> >::const_iterator it_t; + for(it_t = list.begin(); it_t != list.end(); ++it_t) { + const MyMoneyTransaction& t = (*it_t).first; + const MyMoneySplit&s = (*it_t).second; + MyMoneySplit assetAccountSplit; + QValueList<MyMoneySplit> feeSplits; + QValueList<MyMoneySplit> interestSplits; + MyMoneySecurity security; + MyMoneySecurity currency; + MyMoneySplit::investTransactionTypeE transactionType; + InvestTransactionEditor::dissectTransaction(t, s, assetAccountSplit, feeSplits, interestSplits, security, currency, transactionType); + if(feeSplits.count() == 1) { + feesId = feeSplits.first().accountId(); + } + if(interestSplits.count() == 1) { + interestId = interestSplits.first().accountId(); + } + } + } catch(MyMoneyException *e) { + delete e; + } + +} + + |