diff options
Diffstat (limited to 'kmymoney2/mymoney/mymoneyaccount.cpp')
-rw-r--r-- | kmymoney2/mymoney/mymoneyaccount.cpp | 744 |
1 files changed, 744 insertions, 0 deletions
diff --git a/kmymoney2/mymoney/mymoneyaccount.cpp b/kmymoney2/mymoney/mymoneyaccount.cpp new file mode 100644 index 0000000..8c304cd --- /dev/null +++ b/kmymoney2/mymoney/mymoneyaccount.cpp @@ -0,0 +1,744 @@ +/*************************************************************************** + mymoneyaccount.cpp + ------------------- + copyright : (C) 2000 by Michael Edwardes + (C) 2002 by Thomas Baumagrt + email : mte@users.sourceforge.net + 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 + +#include <qregexp.h> +#include <kstandarddirs.h> +#include <kiconloader.h> + +// ---------------------------------------------------------------------------- +// KDE Includes + +#include <klocale.h> + +// ---------------------------------------------------------------------------- +// Project Includes + +#include <kmymoney/mymoneyexception.h> +#include <kmymoney/mymoneyaccount.h> +#include <kmymoney/mymoneysplit.h> + +MyMoneyAccount::MyMoneyAccount() : + m_fraction(-1) +{ + m_accountType = UnknownAccountType; +} + +MyMoneyAccount::~MyMoneyAccount() +{ +} + +MyMoneyAccount::MyMoneyAccount(const QString& id, const MyMoneyAccount& right) : + MyMoneyObject(id) +{ + *this = right; + setId(id); +} + +MyMoneyAccount::MyMoneyAccount(const QDomElement& node) : + MyMoneyObject(node), + MyMoneyKeyValueContainer(node.elementsByTagName("KEYVALUEPAIRS").item(0).toElement()), + m_fraction(-1) +{ + if("ACCOUNT" != node.tagName()) + throw new MYMONEYEXCEPTION("Node was not ACCOUNT"); + + setName(node.attribute("name")); + + // qDebug("Reading information for account %s", acc.name().data()); + + setParentAccountId(QStringEmpty(node.attribute("parentaccount"))); + setLastModified(stringToDate(QStringEmpty(node.attribute("lastmodified")))); + setLastReconciliationDate(stringToDate(QStringEmpty(node.attribute("lastreconciled")))); + + if(!m_lastReconciliationDate.isValid()) { + // for some reason, I was unable to access our own kvp at this point through + // the value() method. It always returned empty strings. The workaround for + // this is to construct a local kvp the same way as we have done before and + // extract the value from it. + // + // Since we want to get rid of the lastStatementDate record anyway, this seems + // to be ok for now. (ipwizard - 2008-08-14) + QString txt = MyMoneyKeyValueContainer(node.elementsByTagName("KEYVALUEPAIRS").item(0).toElement()).value("lastStatementDate"); + if(!txt.isEmpty()) { + setLastReconciliationDate(QDate::fromString(txt, Qt::ISODate)); + } + } + + setInstitutionId(QStringEmpty(node.attribute("institution"))); + setNumber(QStringEmpty(node.attribute("number"))); + setOpeningDate(stringToDate(QStringEmpty(node.attribute("opened")))); + setCurrencyId(QStringEmpty(node.attribute("currency"))); + + QString tmp = QStringEmpty(node.attribute("type")); + bool bOK = false; + int type = tmp.toInt(&bOK); + if(bOK) { + setAccountType(static_cast<MyMoneyAccount::accountTypeE>(type)); + } else { + qWarning("XMLREADER: Account %s had invalid or no account type information.", name().data()); + } + + if(node.hasAttribute("openingbalance")) { + if(!MyMoneyMoney(node.attribute("openingbalance")).isZero()) { + QString msg = i18n("Account %1 contains an opening balance. Please use a KMyMoney version >= 0.8 and < 0.9 to correct the problem.").arg(m_name); + throw new MYMONEYEXCEPTION(msg); + } + } + setDescription(node.attribute("description")); + + m_id = QStringEmpty(node.attribute("id")); + // qDebug("Account %s has id of %s, type of %d, parent is %s.", acc.name().data(), id.data(), type, acc.parentAccountId().data()); + + // Process any Sub-Account information found inside the account entry. + m_accountList.clear(); + QDomNodeList nodeList = node.elementsByTagName("SUBACCOUNTS"); + if(nodeList.count() > 0) { + nodeList = nodeList.item(0).toElement().elementsByTagName("SUBACCOUNT"); + for(unsigned int i = 0; i < nodeList.count(); ++i) { + addAccountId(QString(nodeList.item(i).toElement().attribute("id"))); + } + } + + nodeList = node.elementsByTagName("ONLINEBANKING"); + if(nodeList.count() > 0) { + QDomNamedNodeMap attributes = nodeList.item(0).toElement().attributes(); + for(unsigned int i = 0; i < attributes.count(); ++i) { + const QDomAttr& it_attr = attributes.item(i).toAttr(); + m_onlineBankingSettings.setValue(it_attr.name().utf8(), it_attr.value()); + } + } + +} + +void MyMoneyAccount::setName(const QString& name) +{ + m_name = name; +} + +void MyMoneyAccount::setNumber(const QString& number) +{ + m_number = number; +} + +void MyMoneyAccount::setDescription(const QString& desc) +{ + m_description = desc; +} + +void MyMoneyAccount::setInstitutionId(const QString& id) +{ + m_institution = id; +} + +void MyMoneyAccount::setLastModified(const QDate& date) +{ + m_lastModified = date; +} + +void MyMoneyAccount::setOpeningDate(const QDate& date) +{ + m_openingDate = date; +} + +void MyMoneyAccount::setLastReconciliationDate(const QDate& date) +{ + // FIXME: for a limited time (maybe until we delivered 1.0) we + // keep the last reconciliation date also in the KVP for backward + // compatability. After that, the setValue() statemetn should be removed + // and the XML ctor should remove the value completely from the KVP + setValue("lastStatementDate", date.toString(Qt::ISODate)); + m_lastReconciliationDate = date; +} + +void MyMoneyAccount::setParentAccountId(const QString& parent) +{ + m_parentAccount = parent; +} + +void MyMoneyAccount::setAccountType(const accountTypeE type) +{ + m_accountType = type; +} + +void MyMoneyAccount::addAccountId(const QString& account) +{ + if(!m_accountList.contains(account)) + m_accountList += account; +} + +void MyMoneyAccount::removeAccountIds(void) +{ + m_accountList.clear(); +} + +void MyMoneyAccount::removeAccountId(const QString& account) +{ + QStringList::Iterator it; + + it = m_accountList.find(account); + if(it != m_accountList.end()) + m_accountList.remove(it); +} + +MyMoneyAccount::accountTypeE MyMoneyAccount::accountGroup(MyMoneyAccount::accountTypeE type) +{ + switch(type) { + case MyMoneyAccount::Checkings: + case MyMoneyAccount::Savings: + case MyMoneyAccount::Cash: + case MyMoneyAccount::Currency: + case MyMoneyAccount::Investment: + case MyMoneyAccount::MoneyMarket: + case MyMoneyAccount::CertificateDep: + case MyMoneyAccount::AssetLoan: + case MyMoneyAccount::Stock: + return MyMoneyAccount::Asset; + + case MyMoneyAccount::CreditCard: + case MyMoneyAccount::Loan: + return MyMoneyAccount::Liability; + + default: + return type; + } +} + +bool MyMoneyAccount::operator == (const MyMoneyAccount& right) const +{ + return (MyMoneyKeyValueContainer::operator==(right) && + MyMoneyObject::operator==(right) && + (m_accountList == right.m_accountList) && + (m_accountType == right.m_accountType) && + (m_lastModified == right.m_lastModified) && + (m_lastReconciliationDate == right.m_lastReconciliationDate) && + ((m_name.length() == 0 && right.m_name.length() == 0) || (m_name == right.m_name)) && + ((m_number.length() == 0 && right.m_number.length() == 0) || (m_number == right.m_number)) && + ((m_description.length() == 0 && right.m_description.length() == 0) || (m_description == right.m_description)) && + (m_openingDate == right.m_openingDate) && + (m_parentAccount == right.m_parentAccount) && + (m_currencyId == right.m_currencyId) && + (m_institution == right.m_institution) ); +} + +MyMoneyAccount::accountTypeE MyMoneyAccount::accountGroup(void) const +{ + return accountGroup(m_accountType); +} + +void MyMoneyAccount::setCurrencyId(const QString& id) +{ + m_currencyId = id; +} + +bool MyMoneyAccount::isAssetLiability(void) const +{ + return accountGroup() == Asset || accountGroup() == Liability; +} + +bool MyMoneyAccount::isIncomeExpense(void) const +{ + return accountGroup() == Income || accountGroup() == Expense; +} + +bool MyMoneyAccount::isLoan(void) const +{ + return accountType() == Loan || accountType() == AssetLoan; +} + +bool MyMoneyAccount::isInvest(void) const +{ + return accountType() == Stock; +} + + +MyMoneyAccountLoan::MyMoneyAccountLoan(const MyMoneyAccount& acc) + : MyMoneyAccount(acc) +{ +} + +const MyMoneyMoney MyMoneyAccountLoan::loanAmount(void) const +{ + return MyMoneyMoney(value("loan-amount")); +} + +void MyMoneyAccountLoan::setLoanAmount(const MyMoneyMoney& amount) +{ + setValue("loan-amount", amount.toString()); +} + +const MyMoneyMoney MyMoneyAccountLoan::interestRate(const QDate& date) const +{ + MyMoneyMoney rate; + QString key; + QString val; + + if(!date.isValid()) + return rate; + + key.sprintf("ir-%04d-%02d-%02d", date.year(), date.month(), date.day()); + + QRegExp regExp("ir-(\\d{4})-(\\d{2})-(\\d{2})"); + + QMap<QString, QString>::ConstIterator it; + + for(it = pairs().begin(); it != pairs().end(); ++it) { + if(regExp.search(it.key()) > -1) { + if(qstrcmp(it.key(),key) <= 0) + val = *it; + else + break; + + } else if(!val.isEmpty()) + break; + } + + if(!val.isEmpty()) { + rate = MyMoneyMoney(val); + } + + return rate; +} + +void MyMoneyAccountLoan::setInterestRate(const QDate& date, const MyMoneyMoney& value) +{ + if(!date.isValid()) + return; + + QString key; + key.sprintf("ir-%04d-%02d-%02d", date.year(), date.month(), date.day()); + setValue(key, value.toString()); +} + +MyMoneyAccountLoan::interestDueE MyMoneyAccountLoan::interestCalculation(void) const +{ + QString payTime(value("interest-calculation")); + if(payTime == "paymentDue") + return paymentDue; + return paymentReceived; +} + +void MyMoneyAccountLoan::setInterestCalculation(const MyMoneyAccountLoan::interestDueE onReception) +{ + if(onReception == paymentDue) + setValue("interest-calculation", "paymentDue"); + else + setValue("interest-calculation", "paymentReceived"); +} + +const QDate MyMoneyAccountLoan::nextInterestChange(void) const +{ + QDate rc; + + QRegExp regExp("(\\d{4})-(\\d{2})-(\\d{2})"); + if(regExp.search(value("interest-nextchange")) != -1) { + rc.setYMD(regExp.cap(1).toInt(), regExp.cap(2).toInt(), regExp.cap(3).toInt()); + } + return rc; +} + +void MyMoneyAccountLoan::setNextInterestChange(const QDate& date) +{ + setValue("interest-nextchange", date.toString(Qt::ISODate)); +} + +int MyMoneyAccountLoan::interestChangeFrequency(int* unit) const +{ + int rc = -1; + + if(unit) + *unit = 1; + + QRegExp regExp("(\\d+)/(\\d{1})"); + if(regExp.search(value("interest-changefrequency")) != -1) { + rc = regExp.cap(1).toInt(); + if(unit != 0) { + *unit = regExp.cap(2).toInt(); + } + } + return rc; +} + +void MyMoneyAccountLoan::setInterestChangeFrequency(const int amount, const int unit) +{ + QString val; + val.sprintf("%d/%d", amount, unit); + setValue("interest-changeFrequency", val); +} + +const QString MyMoneyAccountLoan::schedule(void) const +{ + return QString(value("schedule").latin1()); +} + +void MyMoneyAccountLoan::setSchedule(const QString& sched) +{ + setValue("schedule", sched); +} + +bool MyMoneyAccountLoan::fixedInterestRate(void) const +{ + // make sure, that an empty kvp element returns true + return !(value("fixed-interest") == "no"); +} + +void MyMoneyAccountLoan::setFixedInterestRate(const bool fixed) +{ + setValue("fixed-interest", fixed ? "yes" : "no"); + if(fixed) { + deletePair("interest-nextchange"); + deletePair("interest-changeFrequency"); + } +} + +const MyMoneyMoney MyMoneyAccountLoan::finalPayment(void) const +{ + return MyMoneyMoney(value("final-payment")); +} + +void MyMoneyAccountLoan::setFinalPayment(const MyMoneyMoney& finalPayment) +{ + setValue("final-payment", finalPayment.toString()); +} + +unsigned int MyMoneyAccountLoan::term(void) const +{ + return value("term").toUInt(); +} + +void MyMoneyAccountLoan::setTerm(const unsigned int payments) +{ + setValue("term", QString::number(payments)); +} + +const MyMoneyMoney MyMoneyAccountLoan::periodicPayment(void) const +{ + return MyMoneyMoney(value("periodic-payment")); +} + +void MyMoneyAccountLoan::setPeriodicPayment(const MyMoneyMoney& payment) +{ + setValue("periodic-payment", payment.toString()); +} + +const QString MyMoneyAccountLoan::payee(void) const +{ + return value("payee"); +} + +void MyMoneyAccountLoan::setPayee(const QString& payee) +{ + setValue("payee", payee); +} + +const QString MyMoneyAccountLoan::interestAccountId(void) const +{ + return QString(); +} + +void MyMoneyAccountLoan::setInterestAccountId(const QString& /* id */) +{ + +} + +bool MyMoneyAccountLoan::hasReferenceTo(const QString& id) const +{ + return MyMoneyAccount::hasReferenceTo(id) + || (id == payee()) + || (id == schedule()); +} + +void MyMoneyAccountLoan::setInterestCompounding(int frequency) +{ + setValue("compoundingFrequency", QString("%1").arg(frequency)); +} + +int MyMoneyAccountLoan::interestCompounding(void) const +{ + return value("compoundingFrequency").toInt(); +} + +void MyMoneyAccount::writeXML(QDomDocument& document, QDomElement& parent) const +{ + QDomElement el = document.createElement("ACCOUNT"); + + writeBaseXML(document, el); + + el.setAttribute("parentaccount", parentAccountId()); + el.setAttribute("lastreconciled", dateToString(lastReconciliationDate())); + el.setAttribute("lastmodified", dateToString(lastModified())); + el.setAttribute("institution", institutionId()); + el.setAttribute("opened", dateToString(openingDate())); + el.setAttribute("number", number()); + // el.setAttribute("openingbalance", openingBalance().toString()); + el.setAttribute("type", accountType()); + el.setAttribute("name", name()); + el.setAttribute("description", description()); + if(!currencyId().isEmpty()) + el.setAttribute("currency", currencyId()); + + //Add in subaccount information, if this account has subaccounts. + if(accountCount()) + { + QDomElement subAccounts = document.createElement("SUBACCOUNTS"); + QStringList::ConstIterator it; + for(it = accountList().begin(); it != accountList().end(); ++it) + { + QDomElement temp = document.createElement("SUBACCOUNT"); + temp.setAttribute("id", (*it)); + subAccounts.appendChild(temp); + } + + el.appendChild(subAccounts); + } + + // Write online banking settings + if(m_onlineBankingSettings.pairs().count()) { + QDomElement onlinesettings = document.createElement("ONLINEBANKING"); + QMap<QString,QString>::const_iterator it_key = m_onlineBankingSettings.pairs().begin(); + while ( it_key != m_onlineBankingSettings.pairs().end() ) { + onlinesettings.setAttribute(it_key.key(), it_key.data()); + ++it_key; + } + el.appendChild(onlinesettings); + } + + // FIXME drop the lastStatementDate record from the KVP when it is + // not stored there after setLastReconciliationDate() has been changed + // See comment there when this will happen + // deletePair("lastStatementDate"); + + + //Add in Key-Value Pairs for accounts. + MyMoneyKeyValueContainer::writeXML(document, el); + + parent.appendChild(el); +} + +bool MyMoneyAccount::hasReferenceTo(const QString& id) const +{ + return (id == m_institution) || (id == m_parentAccount) || (id == m_currencyId); +} + +void MyMoneyAccount::setOnlineBankingSettings(const MyMoneyKeyValueContainer& values) +{ + m_onlineBankingSettings = values; +} + +const MyMoneyKeyValueContainer& MyMoneyAccount::onlineBankingSettings(void) const +{ + return m_onlineBankingSettings; +} + +void MyMoneyAccount::setClosed(bool closed) +{ + if(closed) + setValue("mm-closed", "yes"); + else + deletePair("mm-closed"); +} + +bool MyMoneyAccount::isClosed(void) const +{ + return !(value("mm-closed").isEmpty()); +} + +int MyMoneyAccount::fraction(const MyMoneySecurity& sec) const +{ + int fraction; + if(m_accountType == Cash) + fraction = sec.smallestCashFraction(); + else + fraction = sec.smallestAccountFraction(); + return fraction; +} + +int MyMoneyAccount::fraction(const MyMoneySecurity& sec) +{ + if(m_accountType == Cash) + m_fraction = sec.smallestCashFraction(); + else + m_fraction = sec.smallestAccountFraction(); + return m_fraction; +} + +int MyMoneyAccount::fraction(void) const +{ + Q_ASSERT(m_fraction != -1); + + return m_fraction; +} + +bool MyMoneyAccount::isCategory(void) const +{ + return m_accountType == Income || m_accountType == Expense; +} + +QString MyMoneyAccount::brokerageName(void) const +{ + if(m_accountType == Investment) + return QString("%1 (%2)").arg(m_name, i18n("Brokerage (suffix for account names)", "Brokerage")); + return m_name; +} + +void MyMoneyAccount::adjustBalance(const MyMoneySplit& s, bool reverse) +{ + if(s.action() == MyMoneySplit::ActionSplitShares) { + if(reverse) + m_balance = m_balance / s.shares(); + else + m_balance = m_balance * s.shares(); + } else { + if(reverse) + m_balance -= s.shares(); + else + m_balance += s.shares(); + } + +} + +QPixmap MyMoneyAccount::accountPixmap(bool reconcileFlag, int size) const +{ + QString icon; + switch(accountType()) { + default: + if(accountGroup() == MyMoneyAccount::Asset) + icon = "account-types_asset"; + else + icon = "account-types_liability"; + break; + + case MyMoneyAccount::Investment: + case MyMoneyAccount::Stock: + case MyMoneyAccount::MoneyMarket: + case MyMoneyAccount::CertificateDep: + icon = "account-types_investments"; + break; + + case MyMoneyAccount::Checkings: + icon = "account-types_checking"; + break; + case MyMoneyAccount::Savings: + icon = "account-types_savings"; + break; + + case MyMoneyAccount::AssetLoan: + case MyMoneyAccount::Loan: + icon = "account-types_loan"; + break; + + case MyMoneyAccount::CreditCard: + icon = "account-types_credit-card"; + break; + + case MyMoneyAccount::Asset: + icon = "account-types_asset"; + break; + + case MyMoneyAccount::Cash: + icon = "account-types_cash"; + break; + + case MyMoneyAccount::Income: + icon = "account-types_income"; + break; + + case MyMoneyAccount::Expense: + icon = "account-types_expense"; + break; + + case MyMoneyAccount::Equity: + icon = "account"; + break; + } + + QPixmap result = DesktopIcon(icon, size); + if(isClosed()) { + QPixmap ovly = DesktopIcon("account-types_closed", size); + bitBlt(&result, 0, 0, &ovly, 0, 0, ovly.width(), ovly.height(), Qt::CopyROP, false); + } else if(reconcileFlag) { + QPixmap ovly = DesktopIcon("account-types_reconcile.png", size); + bitBlt(&result, 0, 0, &ovly, 0, 0, ovly.width(), ovly.height(), Qt::CopyROP, false); + } else if(!onlineBankingSettings().value("provider").isEmpty()) { + QPixmap ovly = DesktopIcon("account-types_online.png", size); + bitBlt(&result, 0, 0, &ovly, 0, 0, ovly.width(), ovly.height(), Qt::CopyROP, false); + } + return result; +} + +QString MyMoneyAccount::accountTypeToString(const MyMoneyAccount::accountTypeE accountType) +{ + QString returnString; + + switch (accountType) { + case MyMoneyAccount::Checkings: + returnString = i18n("Checking"); + break; + case MyMoneyAccount::Savings: + returnString = i18n("Savings"); + break; + case MyMoneyAccount::CreditCard: + returnString = i18n("Credit Card"); + break; + case MyMoneyAccount::Cash: + returnString = i18n("Cash"); + break; + case MyMoneyAccount::Loan: + returnString = i18n("Loan"); + break; + case MyMoneyAccount::CertificateDep: + returnString = i18n("Certificate of Deposit"); + break; + case MyMoneyAccount::Investment: + returnString = i18n("Investment"); + break; + case MyMoneyAccount::MoneyMarket: + returnString = i18n("Money Market"); + break; + case MyMoneyAccount::Asset: + returnString = i18n("Asset"); + break; + case MyMoneyAccount::Liability: + returnString = i18n("Liability"); + break; + case MyMoneyAccount::Currency: + returnString = i18n("Currency"); + break; + case MyMoneyAccount::Income: + returnString = i18n("Income"); + break; + case MyMoneyAccount::Expense: + returnString = i18n("Expense"); + break; + case MyMoneyAccount::AssetLoan: + returnString = i18n("Investment Loan"); + break; + case MyMoneyAccount::Stock: + returnString = i18n("Stock"); + break; + case MyMoneyAccount::Equity: + returnString = i18n("Equity"); + break; + default: + returnString = i18n("Unknown"); + } + + return returnString; +} |