diff --git a/kmymoney/mymoney/mymoneyaccount.h b/kmymoney/mymoney/mymoneyaccount.h --- a/kmymoney/mymoney/mymoneyaccount.h +++ b/kmymoney/mymoney/mymoneyaccount.h @@ -107,15 +107,6 @@ MyMoneyAccount(const QString& id, const MyMoneyAccount& other); - /** - * This is the constructor for an account that is described by a - * QDomElement (e.g. from a file). - * - * @param el const reference to the QDomElement from which to - * create the object - */ - explicit MyMoneyAccount(const QDomElement& el); - MyMoneyAccount(const MyMoneyAccount & other); MyMoneyAccount(MyMoneyAccount && other); MyMoneyAccount & operator=(MyMoneyAccount other); diff --git a/kmymoney/mymoney/mymoneyaccount.cpp b/kmymoney/mymoney/mymoneyaccount.cpp --- a/kmymoney/mymoney/mymoneyaccount.cpp +++ b/kmymoney/mymoney/mymoneyaccount.cpp @@ -69,89 +69,6 @@ { } -MyMoneyAccount::MyMoneyAccount(const QDomElement& node) : - MyMoneyObject(*new MyMoneyAccountPrivate, node), - MyMoneyKeyValueContainer(node.elementsByTagName(nodeNames[nnKeyValuePairs]).item(0).toElement()) -{ - if (nodeNames[nnAccount] != node.tagName()) - throw MYMONEYEXCEPTION_CSTRING("Node was not ACCOUNT"); - - Q_D(MyMoneyAccount); - setName(node.attribute(d->getAttrName(Account::Attribute::Name))); - - // qDebug("Reading information for account %s", acc.name().data()); - - setParentAccountId(MyMoneyUtils::QStringEmpty(node.attribute(d->getAttrName(Account::Attribute::ParentAccount)))); - setLastModified(MyMoneyUtils::stringToDate(MyMoneyUtils::QStringEmpty(node.attribute(d->getAttrName(Account::Attribute::LastModified))))); - setLastReconciliationDate(MyMoneyUtils::stringToDate(MyMoneyUtils::QStringEmpty(node.attribute(d->getAttrName(Account::Attribute::LastReconciled))))); - - if (!d->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(nodeNames[nnKeyValuePairs]).item(0).toElement()).value("lastStatementDate"); - if (!txt.isEmpty()) { - setLastReconciliationDate(QDate::fromString(txt, Qt::ISODate)); - } - } - - setInstitutionId(MyMoneyUtils::QStringEmpty(node.attribute(d->getAttrName(Account::Attribute::Institution)))); - setNumber(MyMoneyUtils::QStringEmpty(node.attribute(d->getAttrName(Account::Attribute::Number)))); - setOpeningDate(MyMoneyUtils::stringToDate(MyMoneyUtils::QStringEmpty(node.attribute(d->getAttrName(Account::Attribute::Opened))))); - setCurrencyId(MyMoneyUtils::QStringEmpty(node.attribute(d->getAttrName(Account::Attribute::Currency)))); - - QString tmp = MyMoneyUtils::QStringEmpty(node.attribute(d->getAttrName(Account::Attribute::Type))); - bool bOK = false; - int type = tmp.toInt(&bOK); - if (bOK) { - setAccountType(static_cast(type)); - } else { - qWarning("XMLREADER: Account %s had invalid or no account type information.", qPrintable(name())); - } - - if (node.hasAttribute(d->getAttrName(Account::Attribute::OpeningBalance))) - if (!MyMoneyMoney(node.attribute(d->getAttrName(Account::Attribute::OpeningBalance))).isZero()) - throw MYMONEYEXCEPTION(QString::fromLatin1("Account %1 contains an opening balance. Please use KMyMoney version 0.8 or later and earlier than version 0.9 to correct the problem.").arg(d->m_name)); - - setDescription(node.attribute(d->getAttrName(Account::Attribute::Description))); - - d->m_id = MyMoneyUtils::QStringEmpty(node.attribute(d->getAttrName(Account::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. - d->m_accountList.clear(); - QDomNodeList nodeList = node.elementsByTagName(d->getElName(Account::Element::SubAccounts)); - if (nodeList.count() > 0) { - nodeList = nodeList.item(0).toElement().elementsByTagName(d->getElName(Account::Element::SubAccount)); - for (int i = 0; i < nodeList.count(); ++i) { - addAccountId(QString(nodeList.item(i).toElement().attribute(d->getAttrName(Account::Attribute::ID)))); - } - } - - nodeList = node.elementsByTagName(d->getElName(Account::Element::OnlineBanking)); - if (nodeList.count() > 0) { - QDomNamedNodeMap attributes = nodeList.item(0).toElement().attributes(); - for (int i = 0; i < attributes.count(); ++i) { - const QDomAttr& it_attr = attributes.item(i).toAttr(); - d->m_onlineBankingSettings.setValue(it_attr.name(), it_attr.value()); - } - } - - // Up to and including version 4.6.6 the new account dialog stored the iban in the kvp-key "IBAN". - // But the rest of the software uses "iban". So correct this: - if (!value("IBAN").isEmpty()) { - // If "iban" was not set, set it now. If it is set, the user reseted it already, so remove - // the garbage. - if (value(d->getAttrName(Account::Attribute::IBAN)).isEmpty()) - setValue(d->getAttrName(Account::Attribute::IBAN), value("IBAN")); - deletePair("IBAN"); - } -} - MyMoneyAccount::MyMoneyAccount(const MyMoneyAccount& other) : MyMoneyObject(*new MyMoneyAccountPrivate(*other.d_func()), other.id()), MyMoneyKeyValueContainer(other) diff --git a/kmymoney/mymoney/mymoneycostcenter.h b/kmymoney/mymoney/mymoneycostcenter.h --- a/kmymoney/mymoney/mymoneycostcenter.h +++ b/kmymoney/mymoney/mymoneycostcenter.h @@ -45,15 +45,6 @@ MyMoneyCostCenter(); explicit MyMoneyCostCenter(const QString &id); - /** - * This is the constructor for a tag that is described by a - * QDomElement (e.g. from a file). - * - * @param el const reference to the QDomElement from which to - * create the object - */ - explicit MyMoneyCostCenter(const QDomElement& el); - MyMoneyCostCenter(const QString& id, const MyMoneyCostCenter& other); MyMoneyCostCenter(const MyMoneyCostCenter & other); diff --git a/kmymoney/mymoney/mymoneycostcenter.cpp b/kmymoney/mymoney/mymoneycostcenter.cpp --- a/kmymoney/mymoney/mymoneycostcenter.cpp +++ b/kmymoney/mymoney/mymoneycostcenter.cpp @@ -50,16 +50,6 @@ { } -MyMoneyCostCenter::MyMoneyCostCenter(const QDomElement& node) : - MyMoneyObject(*new MyMoneyCostCenterPrivate, node) -{ - if (nodeNames[nnCostCenter] != node.tagName()) - throw MYMONEYEXCEPTION_CSTRING("Node was not COSTCENTER"); - - Q_D(MyMoneyCostCenter); - d->m_name = node.attribute(getAttrName(Attribute::Name)); -} - MyMoneyCostCenter::MyMoneyCostCenter(const MyMoneyCostCenter& other) : MyMoneyObject(*new MyMoneyCostCenterPrivate(*other.d_func()), other.id()) { diff --git a/kmymoney/mymoney/mymoneyenums.h b/kmymoney/mymoney/mymoneyenums.h --- a/kmymoney/mymoney/mymoneyenums.h +++ b/kmymoney/mymoney/mymoneyenums.h @@ -353,7 +353,7 @@ /** * @brief The state of a job given by the onlinePlugin */ - enum sendingState { + enum class sendingState { noBankAnswer, /**< Used during or before sending or if sendDate().isValid() the job was successfully sent */ acceptedByBank, /**< bank definetly confirmed the job */ rejectedByBank, /**< bank definetly rejected this job */ diff --git a/kmymoney/mymoney/mymoneyinstitution.h b/kmymoney/mymoney/mymoneyinstitution.h --- a/kmymoney/mymoney/mymoneyinstitution.h +++ b/kmymoney/mymoney/mymoneyinstitution.h @@ -90,15 +90,6 @@ */ MyMoneyInstitution(const QString& id, const MyMoneyInstitution& other); - /** - * This is the constructor for an institution that is described by a - * QDomElement (e.g. from a file). - * - * @param el const reference to the QDomElement from which to - * create the object - */ - explicit MyMoneyInstitution(const QDomElement& el); - QString manager() const; void setManager(const QString& manager); diff --git a/kmymoney/mymoney/mymoneyinstitution.cpp b/kmymoney/mymoney/mymoneyinstitution.cpp --- a/kmymoney/mymoney/mymoneyinstitution.cpp +++ b/kmymoney/mymoney/mymoneyinstitution.cpp @@ -77,39 +77,6 @@ d->m_sortcode = sortcode; } -MyMoneyInstitution::MyMoneyInstitution(const QDomElement& node) : - MyMoneyObject(*new MyMoneyInstitutionPrivate, node), - MyMoneyKeyValueContainer(node.elementsByTagName(nodeNames[nnKeyValuePairs]).item(0).toElement()) -{ - if (nodeNames[nnInstitution] != node.tagName()) - throw MYMONEYEXCEPTION_CSTRING("Node was not INSTITUTION"); - - Q_D(MyMoneyInstitution); - d->m_sortcode = node.attribute(d->getAttrName(Institution::Attribute::SortCode)); - d->m_name = node.attribute(d->getAttrName(Institution::Attribute::Name)); - d->m_manager = node.attribute(d->getAttrName(Institution::Attribute::Manager)); - - QDomNodeList nodeList = node.elementsByTagName(d->getElName(Institution::Element::Address)); - if (nodeList.isEmpty()) - throw MYMONEYEXCEPTION(QString::fromLatin1("No ADDRESS in institution %1").arg(d->m_name)); - - QDomElement addrNode = nodeList.item(0).toElement(); - d->m_street = addrNode.attribute(d->getAttrName(Institution::Attribute::Street)); - d->m_town = addrNode.attribute(d->getAttrName(Institution::Attribute::City)); - d->m_postcode = addrNode.attribute(d->getAttrName(Institution::Attribute::Zip)); - d->m_telephone = addrNode.attribute(d->getAttrName(Institution::Attribute::Telephone)); - - d->m_accountList.clear(); - - nodeList = node.elementsByTagName(d->getElName(Institution::Element::AccountIDS)); - if (nodeList.count() > 0) { - nodeList = nodeList.item(0).toElement().elementsByTagName(d->getElName(Institution::Element::AccountID)); - for (int i = 0; i < nodeList.count(); ++i) { - d->m_accountList << nodeList.item(i).toElement().attribute(d->getAttrName(Institution::Attribute::ID)); - } - } -} - MyMoneyInstitution::MyMoneyInstitution(const MyMoneyInstitution& other) : MyMoneyObject(*new MyMoneyInstitutionPrivate(*other.d_func()), other.id()), MyMoneyKeyValueContainer(other) diff --git a/kmymoney/mymoney/mymoneypayee.h b/kmymoney/mymoney/mymoneypayee.h --- a/kmymoney/mymoney/mymoneypayee.h +++ b/kmymoney/mymoney/mymoneypayee.h @@ -58,20 +58,12 @@ explicit MyMoneyPayee(const QString &id); explicit MyMoneyPayee(const QString& name, - const QString& address = QString(), + const QString& address, const QString& city = QString(), const QString& state = QString(), const QString& postcode = QString(), const QString& telephone = QString(), const QString& email = QString()); - /** - * This is the constructor for a payee that is described by a - * QDomElement (e.g. from a file). - * - * @param el const reference to the QDomElement from which to - * create the object - */ - explicit MyMoneyPayee(const QDomElement& node); MyMoneyPayee(const QString& id, const MyMoneyPayee& other); diff --git a/kmymoney/mymoney/mymoneypayee.cpp b/kmymoney/mymoney/mymoneypayee.cpp --- a/kmymoney/mymoney/mymoneypayee.cpp +++ b/kmymoney/mymoney/mymoneypayee.cpp @@ -73,48 +73,6 @@ d->m_matchKeyIgnoreCase = true; } -MyMoneyPayee::MyMoneyPayee(const QDomElement& node) : - MyMoneyObject(*new MyMoneyPayeePrivate, node) -{ - if (nodeNames[nnPayee] != node.tagName()) { - throw MYMONEYEXCEPTION_CSTRING("Node was not PAYEE"); - } - - Q_D(MyMoneyPayee); - d->m_name = node.attribute(d->getAttrName(Payee::Attribute::Name)); - d->m_reference = node.attribute(d->getAttrName(Payee::Attribute::Reference)); - d->m_email = node.attribute(d->getAttrName(Payee::Attribute::Email)); - - d->m_matchingEnabled = node.attribute(d->getAttrName(Payee::Attribute::MatchingEnabled), "0").toUInt(); - if (d->m_matchingEnabled) { - setMatchData((node.attribute(d->getAttrName(Payee::Attribute::UsingMatchKey), "0").toUInt() != 0) ? eMyMoney::Payee::MatchType::Key : eMyMoney::Payee::MatchType::Name, - node.attribute(d->getAttrName(Payee::Attribute::MatchIgnoreCase), "0").toUInt(), - node.attribute(d->getAttrName(Payee::Attribute::MatchKey))); - } - - if (node.hasAttribute(d->getAttrName(Payee::Attribute::Notes))) { - d->m_notes = node.attribute(d->getAttrName(Payee::Attribute::Notes)); - } - - if (node.hasAttribute(d->getAttrName(Payee::Attribute::DefaultAccountID))) { - d->m_defaultAccountId = node.attribute(d->getAttrName(Payee::Attribute::DefaultAccountID)); - } - - // Load Address - QDomNodeList nodeList = node.elementsByTagName(d->getElName(Payee::Element::Address)); - if (nodeList.isEmpty()) - throw MYMONEYEXCEPTION(QString::fromLatin1("No ADDRESS in payee %1").arg(d->m_name)); - - QDomElement addrNode = nodeList.item(0).toElement(); - d->m_address = addrNode.attribute(d->getAttrName(Payee::Attribute::Street)); - d->m_city = addrNode.attribute(d->getAttrName(Payee::Attribute::City)); - d->m_postcode = addrNode.attribute(d->getAttrName(Payee::Attribute::PostCode)); - d->m_state = addrNode.attribute(d->getAttrName(Payee::Attribute::State)); - d->m_telephone = addrNode.attribute(d->getAttrName(Payee::Attribute::Telephone)); - - MyMoneyPayeeIdentifierContainer::loadXML(node); -} - MyMoneyPayee::MyMoneyPayee(const MyMoneyPayee& other) : MyMoneyObject(*new MyMoneyPayeePrivate(*other.d_func()), other.id()), MyMoneyPayeeIdentifierContainer(other) diff --git a/kmymoney/mymoney/mymoneypayeeidentifiercontainer.h b/kmymoney/mymoney/mymoneypayeeidentifiercontainer.h --- a/kmymoney/mymoney/mymoneypayeeidentifiercontainer.h +++ b/kmymoney/mymoney/mymoneypayeeidentifiercontainer.h @@ -56,8 +56,8 @@ void resetPayeeIdentifiers(const QList< ::payeeIdentifier >& list = QList< ::payeeIdentifier >()); -protected: void loadXML(QDomElement node); +protected: void writeXML(QDomDocument document, QDomElement parent) const; QList< ::payeeIdentifier > m_payeeIdentifiers; }; diff --git a/kmymoney/mymoney/mymoneyreport.h b/kmymoney/mymoney/mymoneyreport.h --- a/kmymoney/mymoney/mymoneyreport.h +++ b/kmymoney/mymoney/mymoneyreport.h @@ -86,12 +86,6 @@ eMyMoney::Report::DetailLevel ss, const QString& name, const QString& comment); - /** - * This constructor creates an object based on the data found in the - * QDomElement referenced by @p node. If problems arise, the @p id of - * the object is cleared (see MyMoneyObject::clearId()). - */ - explicit MyMoneyReport(const QDomElement& node); MyMoneyReport(const QString& id, const MyMoneyReport& other); @@ -104,6 +98,7 @@ ~MyMoneyReport(); eMyMoney::Report::ReportType reportType() const; + void setReportType(eMyMoney::Report::ReportType rt); QString name() const; void setName(const QString& s); diff --git a/kmymoney/mymoney/mymoneyreport.cpp b/kmymoney/mymoney/mymoneyreport.cpp --- a/kmymoney/mymoney/mymoneyreport.cpp +++ b/kmymoney/mymoney/mymoneyreport.cpp @@ -134,15 +134,6 @@ #endif } -MyMoneyReport::MyMoneyReport(const QDomElement& node) : - MyMoneyObject(*new MyMoneyReportPrivate, node) -{ - // properly initialize the object before reading it - *this = MyMoneyReport(); - if (!read(node)) - clearId(); -} - MyMoneyReport::MyMoneyReport(const MyMoneyReport& other) : MyMoneyObject(*new MyMoneyReportPrivate(*other.d_func()), other.id()), MyMoneyTransactionFilter(other) @@ -168,6 +159,12 @@ return d->m_reportType; } +void MyMoneyReport::setReportType(eMyMoney::Report::ReportType rt) +{ + Q_D(MyMoneyReport); + d->m_reportType = rt; +} + QString MyMoneyReport::name() const { Q_D(const MyMoneyReport); diff --git a/kmymoney/mymoney/mymoneyschedule.h b/kmymoney/mymoney/mymoneyschedule.h --- a/kmymoney/mymoney/mymoneyschedule.h +++ b/kmymoney/mymoney/mymoneyschedule.h @@ -90,8 +90,6 @@ bool fixed, bool autoEnter); - explicit MyMoneySchedule(const QDomElement& node); - MyMoneySchedule(const QString& id, const MyMoneySchedule& other); @@ -213,6 +211,18 @@ */ MyMoneyTransaction transaction() const; + /** + * Simple method that sets the transaction for the schedule. + * The transaction must have a valid postDate set, otherwise + * it will not be accepted. This test is bypassed, if @a noDateCheck + * is set to true + * + * @param transaction The new transaction. + * @param noDateCheck if @a true, the date check is bypassed + * @return none + */ + void setTransaction(const MyMoneyTransaction& transaction, bool noDateCheck); + /** * Simple method that returns the schedules last payment. If the * schedule has never been executed, QDate() will be returned. @@ -663,18 +673,6 @@ */ void fixDate(QDate& date) const; - /** - * Simple method that sets the transaction for the schedule. - * The transaction must have a valid postDate set, otherwise - * it will not be accepted. This test is bypassed, if @a noDateCheck - * is set to true - * - * @param transaction The new transaction. - * @param noDateCheck if @a true, the date check is bypassed - * @return none - */ - void setTransaction(const MyMoneyTransaction& transaction, bool noDateCheck); - /** * This method adds a number of Half Months to the given Date. * This is used for EveryHalfMonth occurrences. diff --git a/kmymoney/mymoney/mymoneyschedule.cpp b/kmymoney/mymoney/mymoneyschedule.cpp --- a/kmymoney/mymoney/mymoneyschedule.cpp +++ b/kmymoney/mymoney/mymoneyschedule.cpp @@ -83,75 +83,6 @@ d->m_endDate = endDate; } -MyMoneySchedule::MyMoneySchedule(const QDomElement& node) : - MyMoneyObject(*new MyMoneySchedulePrivate, node) -{ - if (nodeNames[nnScheduleTX] != node.tagName()) - throw MYMONEYEXCEPTION_CSTRING("Node was not SCHEDULED_TX"); - - Q_D(MyMoneySchedule); - d->m_name = node.attribute(d->getAttrName(Schedule::Attribute::Name)); - d->m_startDate = MyMoneyUtils::stringToDate(node.attribute(d->getAttrName(Schedule::Attribute::StartDate))); - d->m_endDate = MyMoneyUtils::stringToDate(node.attribute(d->getAttrName(Schedule::Attribute::EndDate))); - d->m_lastPayment = MyMoneyUtils::stringToDate(node.attribute(d->getAttrName(Schedule::Attribute::LastPayment))); - - d->m_type = static_cast(node.attribute(d->getAttrName(Schedule::Attribute::Type)).toInt()); - d->m_paymentType = static_cast(node.attribute(d->getAttrName(Schedule::Attribute::PaymentType)).toInt()); - d->m_occurrence = static_cast(node.attribute(d->getAttrName(Schedule::Attribute::Occurrence)).toInt()); - d->m_occurrenceMultiplier = node.attribute(d->getAttrName(Schedule::Attribute::OccurrenceMultiplier), "1").toInt(); - // Convert to compound occurrence - simpleToCompoundOccurrence(d->m_occurrenceMultiplier, d->m_occurrence); - d->m_lastDayInMonth = static_cast(node.attribute("lastDayInMonth").toInt()); - d->m_autoEnter = static_cast(node.attribute(d->getAttrName(Schedule::Attribute::AutoEnter)).toInt()); - d->m_fixed = static_cast(node.attribute(d->getAttrName(Schedule::Attribute::Fixed)).toInt()); - d->m_weekendOption = static_cast(node.attribute(d->getAttrName(Schedule::Attribute::WeekendOption)).toInt()); - - // read in the associated transaction - QDomNodeList nodeList = node.elementsByTagName(nodeNames[nnTransaction]); - if (nodeList.count() == 0) - throw MYMONEYEXCEPTION_CSTRING("SCHEDULED_TX has no TRANSACTION node"); - - setTransaction(MyMoneyTransaction(nodeList.item(0).toElement(), false), true); - - // some old versions did not remove the entry date and post date fields - // in the schedule. So if this is the case, we deal with a very old transaction - // and can't use the post date field as next due date. Hence, we wipe it out here - if (d->m_transaction.entryDate().isValid()) { - d->m_transaction.setPostDate(QDate()); - d->m_transaction.setEntryDate(QDate()); - } - - // readin the recorded payments - nodeList = node.elementsByTagName(d->getElName(Schedule::Element::Payments)); - if (nodeList.count() > 0) { - nodeList = nodeList.item(0).toElement().elementsByTagName(d->getElName(Schedule::Element::Payment)); - for (int i = 0; i < nodeList.count(); ++i) { - d->m_recordedPayments << MyMoneyUtils::stringToDate(nodeList.item(i).toElement().attribute(d->getAttrName(Schedule::Attribute::Date))); - } - } - - // if the next due date is not set (comes from old version) - // then set it up the old way - if (!nextDueDate().isValid() && !d->m_lastPayment.isValid()) { - d->m_transaction.setPostDate(d->m_startDate); - // clear it, because the schedule has never been used - d->m_startDate = QDate(); - } - - // There are reports that lastPayment and nextDueDate are identical or - // that nextDueDate is older than lastPayment. This could - // be caused by older versions of the application. In this case, we just - // clear out the nextDueDate and let it calculate from the lastPayment. - if (nextDueDate().isValid() && nextDueDate() <= d->m_lastPayment) { - d->m_transaction.setPostDate(QDate()); - } - - if (!nextDueDate().isValid()) { - d->m_transaction.setPostDate(d->m_startDate); - d->m_transaction.setPostDate(nextPayment(d->m_lastPayment.addDays(1))); - } -} - MyMoneySchedule::MyMoneySchedule(const MyMoneySchedule& other) : MyMoneyObject(*new MyMoneySchedulePrivate(*other.d_func()), other.id()) { diff --git a/kmymoney/mymoney/mymoneysecurity.h b/kmymoney/mymoney/mymoneysecurity.h --- a/kmymoney/mymoney/mymoneysecurity.h +++ b/kmymoney/mymoney/mymoneysecurity.h @@ -68,8 +68,6 @@ const int smallestAccountFraction = 100, const int pricePrecision = 4); - explicit MyMoneySecurity(const QDomElement& node); - MyMoneySecurity(const QString& id, const MyMoneySecurity& other); diff --git a/kmymoney/mymoney/mymoneysecurity.cpp b/kmymoney/mymoney/mymoneysecurity.cpp --- a/kmymoney/mymoney/mymoneysecurity.cpp +++ b/kmymoney/mymoney/mymoneysecurity.cpp @@ -76,41 +76,6 @@ d->m_smallestAccountFraction = smallestCashFraction; } -MyMoneySecurity::MyMoneySecurity(const QDomElement& node) : - MyMoneyObject(*new MyMoneySecurityPrivate, node), - MyMoneyKeyValueContainer(node.elementsByTagName(nodeNames[nnKeyValuePairs]).item(0).toElement()) -{ - { - const auto tag = node.tagName(); - if ((nodeNames[nnSecurity] != tag) - && (nodeNames[nnEquity] != tag) - && (nodeNames[nnCurrency] != tag)) - throw MYMONEYEXCEPTION_CSTRING("Node was not SECURITY or CURRENCY"); - } - - Q_D(MyMoneySecurity); - d->m_name = node.attribute(d->getAttrName(Security::Attribute::Name)); - d->m_tradingSymbol = node.attribute(d->getAttrName(Security::Attribute::Symbol)); - d->m_securityType = static_cast(node.attribute(d->getAttrName(Security::Attribute::Type)).toInt()); - d->m_roundingMethod = static_cast(node.attribute(d->getAttrName(Security::Attribute::RoundingMethod)).toInt()); - d->m_smallestAccountFraction = node.attribute(d->getAttrName(Security::Attribute::SAF)).toUInt(); - d->m_pricePrecision = node.attribute(d->getAttrName(Security::Attribute::PP)).toUInt(); - - if (d->m_smallestAccountFraction == 0) - d->m_smallestAccountFraction = 100; - if (d->m_pricePrecision == 0 || d->m_pricePrecision > 10) - d->m_pricePrecision = 4; - - if (isCurrency()) { - d->m_smallestCashFraction = node.attribute(d->getAttrName(Security::Attribute::SCF)).toUInt(); - if (d->m_smallestCashFraction == 0) - d->m_smallestCashFraction = 100; - } else { - d->m_tradingCurrency = node.attribute(d->getAttrName(Security::Attribute::TradingCurrency)); - d->m_tradingMarket = node.attribute(d->getAttrName(Security::Attribute::TradingMarket)); - } -} - MyMoneySecurity::MyMoneySecurity(const MyMoneySecurity& other) : MyMoneyObject(*new MyMoneySecurityPrivate(*other.d_func()), other.id()), MyMoneyKeyValueContainer(other) diff --git a/kmymoney/mymoney/mymoneytag.h b/kmymoney/mymoney/mymoneytag.h --- a/kmymoney/mymoney/mymoneytag.h +++ b/kmymoney/mymoney/mymoneytag.h @@ -51,14 +51,6 @@ explicit MyMoneyTag(const QString& name, const QColor& tagColor ); - /** - * This is the constructor for a tag that is described by a - * QDomElement (e.g. from a file). - * - * @param el const reference to the QDomElement from which to - * create the object - */ - explicit MyMoneyTag(const QDomElement& node); MyMoneyTag(const QString& id, const MyMoneyTag& tag); @@ -78,6 +70,7 @@ QColor tagColor() const; void setTagColor(const QColor& val); + void setNamedTagColor(const QString &val); QString notes() const; void setNotes(const QString& val); diff --git a/kmymoney/mymoney/mymoneytag.cpp b/kmymoney/mymoney/mymoneytag.cpp --- a/kmymoney/mymoney/mymoneytag.cpp +++ b/kmymoney/mymoney/mymoneytag.cpp @@ -53,23 +53,6 @@ d->m_tag_color = tabColor; } -MyMoneyTag::MyMoneyTag(const QDomElement& node) : - MyMoneyObject(*new MyMoneyTagPrivate, node) -{ - if (nodeNames[nnTag] != node.tagName()) { - throw MYMONEYEXCEPTION_CSTRING("Node was not TAG"); - } - Q_D(MyMoneyTag); - d->m_name = node.attribute(d->getAttrName(Tag::Attribute::Name)); - if (node.hasAttribute(d->getAttrName(Tag::Attribute::TagColor))) { - d->m_tag_color.setNamedColor(node.attribute(d->getAttrName(Tag::Attribute::TagColor))); - } - if (node.hasAttribute(d->getAttrName(Tag::Attribute::Notes))) { - d->m_notes = node.attribute(d->getAttrName(Tag::Attribute::Notes)); - } - d->m_closed = node.attribute(d->getAttrName(Tag::Attribute::Closed), "0").toUInt(); -} - MyMoneyTag::MyMoneyTag(const MyMoneyTag& other) : MyMoneyObject(*new MyMoneyTagPrivate(*other.d_func()), other.id()) { @@ -122,6 +105,12 @@ d->m_tag_color = val; } +void MyMoneyTag::setNamedTagColor(const QString &val) +{ + Q_D(MyMoneyTag); + d->m_tag_color.setNamedColor(val); +} + QString MyMoneyTag::notes() const { Q_D(const MyMoneyTag); diff --git a/kmymoney/mymoney/onlinejob.h b/kmymoney/mymoney/onlinejob.h --- a/kmymoney/mymoney/onlinejob.h +++ b/kmymoney/mymoney/onlinejob.h @@ -32,6 +32,8 @@ class onlineTask; class MyMoneyAccount; +namespace eMyMoney { namespace OnlineJob { enum class sendingState; } } + /** * @brief Class to share jobs which can be procceded by an online banking plugin * @@ -77,9 +79,6 @@ onlineJob(onlineTask* task, const QString& id); // krazy:exclude=explicit onlineJob(onlineTask* task); // krazy:exclude=explicit - /** @brief Contruct from xml */ - explicit onlineJob(const QDomElement&); - /** * @brief Create new onlineJob as copy of other * @@ -143,17 +142,6 @@ bool hasReferenceTo(const QString &id) const override; void writeXML(QDomDocument &document, QDomElement &parent) const override; - /** - * @brief The state of a job given by the onlinePlugin - */ - enum sendingState { - noBankAnswer, /**< Used during or before sending or if sendDate().isValid() the job was successfully sent */ - acceptedByBank, /**< bank definetly confirmed the job */ - rejectedByBank, /**< bank definetly rejected this job */ - abortedByUser, /**< aborted by user during sending */ - sendingError /**< an error occurred, the job is certainly not executed by the bank */ - }; - /** * @brief Account this job is related to * @@ -222,8 +210,8 @@ * * Set dateTime to QDateTime() and bankAnswer to noState to mark unsend. If bankAnswer == noState dateTime.isNull() must be true! */ - void setBankAnswer(const sendingState state, const QDateTime &dateTime); - void setBankAnswer(const sendingState state); + void setBankAnswer(const eMyMoney::OnlineJob::sendingState state, const QDateTime &dateTime); + void setBankAnswer(const eMyMoney::OnlineJob::sendingState state); /** * @brief DateTime of the last status update by the bank @@ -235,7 +223,7 @@ * @brief Returns last status sand by bank * @return */ - sendingState bankAnswerState() const; + eMyMoney::OnlineJob::sendingState bankAnswerState() const; /** * @brief locks the onlineJob for sending it diff --git a/kmymoney/mymoney/onlinejob.cpp b/kmymoney/mymoney/onlinejob.cpp --- a/kmymoney/mymoney/onlinejob.cpp +++ b/kmymoney/mymoney/onlinejob.cpp @@ -37,7 +37,7 @@ Q_D(onlineJob); d->m_jobSend = QDateTime(); d->m_jobBankAnswerDate = QDateTime(); - d->m_jobBankAnswerState = noBankAnswer; + d->m_jobBankAnswerState = eMyMoney::OnlineJob::sendingState::noBankAnswer; d->m_messageList = QList(); d->m_locked = false; } @@ -55,7 +55,7 @@ Q_D(onlineJob); d->m_jobSend = QDateTime(); d->m_jobBankAnswerDate = QDateTime(); - d->m_jobBankAnswerState = noBankAnswer; + d->m_jobBankAnswerState = eMyMoney::OnlineJob::sendingState::noBankAnswer; d->m_messageList = QList(); d->m_locked = false; } @@ -67,7 +67,7 @@ Q_D(onlineJob); d->m_jobSend = QDateTime(); d->m_jobBankAnswerDate = QDateTime(); - d->m_jobBankAnswerState = noBankAnswer; + d->m_jobBankAnswerState = eMyMoney::OnlineJob::sendingState::noBankAnswer; d->m_messageList = QList(); d->m_locked = false; } @@ -86,36 +86,12 @@ Q_D(onlineJob); d->m_jobSend = QDateTime(); d->m_jobBankAnswerDate = QDateTime(); - d->m_jobBankAnswerState = noBankAnswer; + d->m_jobBankAnswerState = eMyMoney::OnlineJob::sendingState::noBankAnswer; d->m_messageList = QList(); d->m_locked = false; copyPointerFromOtherJob(other); } -onlineJob::onlineJob(const QDomElement& element) : - MyMoneyObject(*new onlineJobPrivate, element, true) -{ - Q_D(onlineJob); - d->m_messageList = QList(); - d->m_locked = false; - d->m_jobSend = QDateTime::fromString(element.attribute(d->getAttrName(OnlineJob::Attribute::Send)), Qt::ISODate); - d->m_jobBankAnswerDate = QDateTime::fromString(element.attribute(d->getAttrName(OnlineJob::Attribute::BankAnswerDate)), Qt::ISODate); - QString state = element.attribute(d->getAttrName(OnlineJob::Attribute::BankAnswerState)); - if (state == d->getAttrName(OnlineJob::Attribute::AbortedByUser)) - d->m_jobBankAnswerState = abortedByUser; - else if (state == d->getAttrName(OnlineJob::Attribute::AcceptedByBank)) - d->m_jobBankAnswerState = acceptedByBank; - else if (state == d->getAttrName(OnlineJob::Attribute::RejectedByBank)) - d->m_jobBankAnswerState = rejectedByBank; - else if (state == d->getAttrName(OnlineJob::Attribute::SendingError)) - d->m_jobBankAnswerState = sendingError; - else - d->m_jobBankAnswerState = noBankAnswer; - - QDomElement taskElem = element.firstChildElement(d->getElName(OnlineJob::Element::OnlineTask)); - m_task = onlineJobAdministration::instance()->createOnlineTaskByXml(taskElem.attribute(d->getAttrName(OnlineJob::Attribute::IID)), taskElem); -} - void onlineJob::copyPointerFromOtherJob(const onlineJob &other) { if (!other.isNull()) @@ -128,7 +104,7 @@ clearId(); d->m_jobSend = QDateTime(); d->m_jobBankAnswerDate = QDateTime(); - d->m_jobBankAnswerState = noBankAnswer; + d->m_jobBankAnswerState = eMyMoney::OnlineJob::sendingState::noBankAnswer; d->m_locked = false; } @@ -205,7 +181,7 @@ bool onlineJob::isEditable() const { Q_D(const onlineJob); - return (!isLocked() && sendDate().isNull() && (d->m_jobBankAnswerState == noBankAnswer || d->m_jobBankAnswerState == sendingError)); + return (!isLocked() && sendDate().isNull() && (d->m_jobBankAnswerState == eMyMoney::OnlineJob::sendingState::noBankAnswer || d->m_jobBankAnswerState == eMyMoney::OnlineJob::sendingState::sendingError)); } bool onlineJob::isNull() const @@ -224,14 +200,14 @@ setJobSend(QDateTime::currentDateTime()); } -void onlineJob::setBankAnswer(const onlineJob::sendingState state, const QDateTime &dateTime) +void onlineJob::setBankAnswer(const eMyMoney::OnlineJob::sendingState state, const QDateTime &dateTime) { Q_D(onlineJob); d->m_jobBankAnswerState = state; d->m_jobBankAnswerDate = dateTime; } -void onlineJob::setBankAnswer(const onlineJob::sendingState state) +void onlineJob::setBankAnswer(const eMyMoney::OnlineJob::sendingState state) { setBankAnswer(state, QDateTime::currentDateTime()); } @@ -242,7 +218,7 @@ return d->m_jobBankAnswerDate; } -onlineJob::sendingState onlineJob::bankAnswerState() const +eMyMoney::OnlineJob::sendingState onlineJob::bankAnswerState() const { Q_D(const onlineJob); return d->m_jobBankAnswerState; @@ -299,11 +275,11 @@ el.setAttribute(d->getAttrName(OnlineJob::Attribute::BankAnswerDate), d->m_jobBankAnswerDate.toString(Qt::ISODate)); switch (d->m_jobBankAnswerState) { - case abortedByUser: el.setAttribute(d->getAttrName(OnlineJob::Attribute::BankAnswerState), d->getAttrName(OnlineJob::Attribute::AbortedByUser)); break; - case acceptedByBank: el.setAttribute(d->getAttrName(OnlineJob::Attribute::BankAnswerState), d->getAttrName(OnlineJob::Attribute::AcceptedByBank)); break; - case rejectedByBank: el.setAttribute(d->getAttrName(OnlineJob::Attribute::BankAnswerState), d->getAttrName(OnlineJob::Attribute::RejectedByBank)); break; - case sendingError: el.setAttribute(d->getAttrName(OnlineJob::Attribute::BankAnswerState), d->getAttrName(OnlineJob::Attribute::SendingError)); break; - case noBankAnswer: + case eMyMoney::OnlineJob::sendingState::abortedByUser: el.setAttribute(d->getAttrName(OnlineJob::Attribute::BankAnswerState), d->getAttrName(OnlineJob::Attribute::AbortedByUser)); break; + case eMyMoney::OnlineJob::sendingState::acceptedByBank: el.setAttribute(d->getAttrName(OnlineJob::Attribute::BankAnswerState), d->getAttrName(OnlineJob::Attribute::AcceptedByBank)); break; + case eMyMoney::OnlineJob::sendingState::rejectedByBank: el.setAttribute(d->getAttrName(OnlineJob::Attribute::BankAnswerState), d->getAttrName(OnlineJob::Attribute::RejectedByBank)); break; + case eMyMoney::OnlineJob::sendingState::sendingError: el.setAttribute(d->getAttrName(OnlineJob::Attribute::BankAnswerState), d->getAttrName(OnlineJob::Attribute::SendingError)); break; + case eMyMoney::OnlineJob::sendingState::noBankAnswer: default: void(); } diff --git a/kmymoney/mymoney/onlinejob_p.h b/kmymoney/mymoney/onlinejob_p.h --- a/kmymoney/mymoney/onlinejob_p.h +++ b/kmymoney/mymoney/onlinejob_p.h @@ -26,6 +26,9 @@ #include "mymoneyobject_p.h" #include "onlinejobmessage.h" +#include "mymoneyenums.h" + +namespace eMyMoney { namespace OnlineJob { enum class sendingState; } } namespace OnlineJob { enum class Element { OnlineTask }; @@ -90,7 +93,7 @@ * * combined with m_jobBankAnswerDate */ - onlineJob::sendingState m_jobBankAnswerState; + eMyMoney::OnlineJob::sendingState m_jobBankAnswerState; /** * @brief Validation result status diff --git a/kmymoney/mymoney/onlinejobadministration.h b/kmymoney/mymoney/onlinejobadministration.h --- a/kmymoney/mymoney/onlinejobadministration.h +++ b/kmymoney/mymoney/onlinejobadministration.h @@ -209,6 +209,12 @@ */ void updateActions(); + /** + * @brief Creates an onlineTask by its iid and xml data + * @return pointer to task, caller gains ownership. Can be 0. + */ + onlineTask* createOnlineTaskByXml(const QString& iid, const QDomElement& element) const; + Q_SIGNALS: /** * @brief Emitted if canSendAnyTask() changed @@ -261,12 +267,6 @@ */ onlineTask* createOnlineTask(const QString& iid) const; - /** - * @brief Creates an onlineTask by its iid and xml data - * @return pointer to task, caller gains ownership. Can be 0. - */ - onlineTask* createOnlineTaskByXml(const QString& iid, const QDomElement& element) const; - // Must be able to call createOnlineTaskByXml friend class onlineJob; diff --git a/kmymoney/mymoney/tests/mymoneyaccount-test.h b/kmymoney/mymoney/tests/mymoneyaccount-test.h --- a/kmymoney/mymoney/tests/mymoneyaccount-test.h +++ b/kmymoney/mymoney/tests/mymoneyaccount-test.h @@ -41,16 +41,13 @@ void testSubAccounts(); void testEquality(); void testWriteXML(); - void testReadXML(); void testHasReferenceTo(); void testAdjustBalance(); void testSetClosed(); void specialAccountTypes(); void specialAccountTypes_data(); void addReconciliation(); void reconciliationHistory(); - void testElementNames(); - void testAttributeNames(); void testHasOnlineMapping(); }; diff --git a/kmymoney/mymoney/tests/mymoneyaccount-test.cpp b/kmymoney/mymoney/tests/mymoneyaccount-test.cpp --- a/kmymoney/mymoney/tests/mymoneyaccount-test.cpp +++ b/kmymoney/mymoney/tests/mymoneyaccount-test.cpp @@ -371,86 +371,6 @@ QCOMPARE(keyValuePair2.childNodes().size(), 0); } -void MyMoneyAccountTest::testReadXML() -{ - MyMoneyAccount a; - QString ref_ok = QString( - "\n" - "\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "\n"). - arg(QDate::currentDate().toString(Qt::ISODate)).arg(QDate::currentDate().toString(Qt::ISODate)); - - QString ref_false = QString( - "\n" - "\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "\n"). - arg(QDate::currentDate().toString(Qt::ISODate)).arg(QDate::currentDate().toString(Qt::ISODate)); - - QDomDocument doc; - QDomElement node; - doc.setContent(ref_false); - node = doc.documentElement().firstChild().toElement(); - - try { - a = MyMoneyAccount(node); - QFAIL("Missing expected exception"); - } catch (const MyMoneyException &) { - } - - doc.setContent(ref_ok); - node = doc.documentElement().firstChild().toElement(); - - a.addAccountId("TEST"); - a.setValue("KEY", "VALUE"); - - try { - a = MyMoneyAccount(node); - QVERIFY(a.id() == "A000001"); - QVERIFY(a.name() == "AccountName"); - QVERIFY(a.parentAccountId() == "Parent"); - QVERIFY(a.lastModified() == QDate::currentDate()); - QVERIFY(a.lastReconciliationDate() == QDate()); - QVERIFY(a.institutionId() == "B000001"); - QVERIFY(a.number() == "465500"); - QVERIFY(a.openingDate() == QDate::currentDate()); - QVERIFY(a.accountType() == eMyMoney::Account::Type::Asset); - QVERIFY(a.description() == "Desc"); - QVERIFY(a.accountList().count() == 2); - QVERIFY(a.accountList()[0] == "A000002"); - QVERIFY(a.accountList()[1] == "A000003"); - QVERIFY(a.pairs().count() == 4); - QVERIFY(a.value("key") == "value"); - QVERIFY(a.value("Key") == "Value"); - QVERIFY(a.value("lastStatementDate").isEmpty()); - QVERIFY(a.reconciliationHistory().count() == 2); - QVERIFY(a.reconciliationHistory()[QDate(2011, 1, 1)] == MyMoneyMoney(123, 100)); - QVERIFY(a.reconciliationHistory()[QDate(2011, 2, 1)] == MyMoneyMoney(456, 100)); - } catch (const MyMoneyException &) { - QFAIL("Unexpected exception"); - } -} - void MyMoneyAccountTest::testHasReferenceTo() { MyMoneyAccount a; @@ -551,26 +471,6 @@ QVERIFY(a.reconciliationHistory().count() == 2); } -void MyMoneyAccountTest::testElementNames() -{ - for (auto i = (int)Account::Element::SubAccount; i <= (int)Account::Element::OnlineBanking; ++i) { - auto isEmpty = MyMoneyAccountPrivate::getElName(static_cast(i)).isEmpty(); - if (isEmpty) - qWarning() << "Empty element's name " << i; - QVERIFY(!isEmpty); - } -} - -void MyMoneyAccountTest::testAttributeNames() -{ - for (auto i = (int)Account::Attribute::ID; i < (int)Account::Attribute::LastAttribute; ++i) { - auto isEmpty = MyMoneyAccountPrivate::getAttrName(static_cast(i)).isEmpty(); - if (isEmpty) - qWarning() << "Empty attribute's name " << i; - QVERIFY(!isEmpty); - } -} - void MyMoneyAccountTest::testHasOnlineMapping() { MyMoneyAccount a; diff --git a/kmymoney/mymoney/tests/mymoneybudget-test.h b/kmymoney/mymoney/tests/mymoneybudget-test.h --- a/kmymoney/mymoney/tests/mymoneybudget-test.h +++ b/kmymoney/mymoney/tests/mymoneybudget-test.h @@ -37,8 +37,6 @@ void addMonthByMonthToYearly(); void addMonthByMonthToMonthByMonth(); void cleanup(); - void testElementNames(); - void testAttributeNames(); }; #endif diff --git a/kmymoney/mymoney/tests/mymoneybudget-test.cpp b/kmymoney/mymoney/tests/mymoneybudget-test.cpp --- a/kmymoney/mymoney/tests/mymoneybudget-test.cpp +++ b/kmymoney/mymoney/tests/mymoneybudget-test.cpp @@ -274,23 +274,3 @@ QVERIFY(a0.totalBalance() == MyMoneyMoney(23400, 1)); QVERIFY(a1.totalBalance() == MyMoneyMoney(15600, 1)); } - -void MyMoneyBudgetTest::testElementNames() -{ - for (auto i = (int)Budget::Element::Budget; i <= (int)Budget::Element::Period; ++i) { - auto isEmpty = MyMoneyBudgetPrivate::getElName(static_cast(i)).isEmpty(); - if (isEmpty) - qWarning() << "Empty element's name " << i; - QVERIFY(!isEmpty); - } -} - -void MyMoneyBudgetTest::testAttributeNames() -{ - for (auto i = (int)Budget::Attribute::ID; i < (int)Budget::Attribute::LastAttribute; ++i) { - auto isEmpty = MyMoneyBudgetPrivate::getAttrName(static_cast(i)).isEmpty(); - if (isEmpty) - qWarning() << "Empty attribute's name " << i; - QVERIFY(!isEmpty); - } -} diff --git a/kmymoney/mymoney/tests/mymoneyinstitution-test.h b/kmymoney/mymoney/tests/mymoneyinstitution-test.h --- a/kmymoney/mymoney/tests/mymoneyinstitution-test.h +++ b/kmymoney/mymoney/tests/mymoneyinstitution-test.h @@ -42,9 +42,6 @@ void testInequality(); void testAccountIDList(); void testWriteXML(); - void testReadXML(); - void testElementNames(); - void testAttributeNames(); }; #endif diff --git a/kmymoney/mymoney/tests/mymoneyinstitution-test.cpp b/kmymoney/mymoney/tests/mymoneyinstitution-test.cpp --- a/kmymoney/mymoney/tests/mymoneyinstitution-test.cpp +++ b/kmymoney/mymoney/tests/mymoneyinstitution-test.cpp @@ -270,90 +270,3 @@ QCOMPARE(keyValuePair1.attribute("value"), QLatin1String("value")); QCOMPARE(keyValuePair1.childNodes().size(), 0); } - -void MyMoneyInstitutionTest::testReadXML() -{ - MyMoneyInstitution i; - QString ref_ok = QString( - "\n" - "\n" - " \n" - "
\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "\n"); - - QString ref_false = QString( - "\n" - "\n" - " \n" - "
\n" - " \n" - " \n" - " \n" - " \n" - " \n" - "\n"); - - QDomDocument doc; - QDomElement node; - - doc.setContent(ref_false); - node = doc.documentElement().firstChild().toElement(); - try { - i = MyMoneyInstitution(node); - QFAIL("Missing expected exception"); - } catch (const MyMoneyException &) { - } - - i.addAccountId("TEST"); - - doc.setContent(ref_ok); - node = doc.documentElement().firstChild().toElement(); - try { - QStringList alist; - alist << "A000001" << "A000003"; - i = MyMoneyInstitution(node); - - QVERIFY(i.sortcode() == "sortcode"); - QVERIFY(i.id() == "I00001"); - QVERIFY(i.manager() == "manager"); - QVERIFY(i.name() == "name"); - QVERIFY(i.street() == "street"); - QVERIFY(i.postcode() == "postcode"); - QVERIFY(i.city() == "town"); - QVERIFY(i.telephone() == "telephone"); - QVERIFY(i.accountList() == alist); - QVERIFY(i.value(QString("key")) == "value"); - - } catch (const MyMoneyException &) { - QFAIL("Unexpected exception"); - } -} - -void MyMoneyInstitutionTest::testElementNames() -{ - for (auto i = (int)Institution::Element::AccountID; i <= (int)Institution::Element::Address; ++i) { - auto isEmpty = MyMoneyInstitutionPrivate::getElName(static_cast(i)).isEmpty(); - if (isEmpty) - qWarning() << "Empty element's name " << i; - QVERIFY(!isEmpty); - } - -} - -void MyMoneyInstitutionTest::testAttributeNames() -{ - for (auto i = (int)Institution::Attribute::ID; i < (int)Institution::Attribute::LastAttribute; ++i) { - auto isEmpty = MyMoneyInstitutionPrivate::getAttrName(static_cast(i)).isEmpty(); - if (isEmpty) - qWarning() << "Empty attribute's name " << i; - QVERIFY(!isEmpty); - } -} diff --git a/kmymoney/mymoney/tests/mymoneypayee-test.h b/kmymoney/mymoney/tests/mymoneypayee-test.h --- a/kmymoney/mymoney/tests/mymoneypayee-test.h +++ b/kmymoney/mymoney/tests/mymoneypayee-test.h @@ -27,7 +27,6 @@ { Q_OBJECT private Q_SLOTS: - void testXml(); void testDefaultAccount(); void testEmptyMatchKeyBegin(); void testEmptyMatchKeyEnd(); @@ -38,8 +37,6 @@ void testMatchKeyAllowSpaceAtStart(); void testMatchKeyAllowSpaceAtEnd(); void testMatchNameExact(); - void testElementNames(); - void testAttributeNames(); }; #endif diff --git a/kmymoney/mymoney/tests/mymoneypayee-test.cpp b/kmymoney/mymoney/tests/mymoneypayee-test.cpp --- a/kmymoney/mymoney/tests/mymoneypayee-test.cpp +++ b/kmymoney/mymoney/tests/mymoneypayee-test.cpp @@ -35,44 +35,6 @@ QTEST_GUILESS_MAIN(MyMoneyPayeeTest) -void MyMoneyPayeeTest::testXml() -{ - QDomDocument doc; - QDomElement parent = doc.createElement("Test"); - doc.appendChild(parent); - MyMoneyPayee payee1; - payee1.d_func()->m_id = "some random id";//if the ID isn't set, w ethrow an exception - payee1.writeXML(doc, parent); - QString temp1 = "Account1"; - payee1.setDefaultAccountId(temp1); - payee1.writeXML(doc, parent); - QString temp2 = "Account2"; - payee1.setDefaultAccountId(temp2); - payee1.writeXML(doc, parent); - payee1.setDefaultAccountId(); - payee1.writeXML(doc, parent); - QDomElement el = parent.firstChild().toElement(); - QVERIFY(!el.isNull()); - MyMoneyPayee payee2(el); - QVERIFY(!payee2.defaultAccountEnabled()); - QVERIFY(payee2.defaultAccountId().isEmpty()); - el = el.nextSibling().toElement(); - QVERIFY(!el.isNull()); - MyMoneyPayee payee3(el); - QVERIFY(payee3.defaultAccountEnabled()); - QVERIFY(payee3.defaultAccountId() == temp1); - el = el.nextSibling().toElement(); - QVERIFY(!el.isNull()); - MyMoneyPayee payee4(el); - QVERIFY(payee4.defaultAccountEnabled()); - QVERIFY(payee4.defaultAccountId() == temp2); - el = el.nextSibling().toElement(); - QVERIFY(!el.isNull()); - MyMoneyPayee payee5(el); - QVERIFY(!payee5.defaultAccountEnabled()); - QVERIFY(payee5.defaultAccountId().isEmpty()); -} - void MyMoneyPayeeTest::testDefaultAccount() { MyMoneyPayee payee; @@ -215,23 +177,3 @@ QCOMPARE(ignoreCase, false); QVERIFY(keys.isEmpty()); } - -void MyMoneyPayeeTest::testElementNames() -{ - for (auto i = (int)Payee::Element::Address; i <= (int)Payee::Element::Address; ++i) { - auto isEmpty = MyMoneyPayeePrivate::getElName(static_cast(i)).isEmpty(); - if (isEmpty) - qWarning() << "Empty element's name " << i; - QVERIFY(!isEmpty); - } -} - -void MyMoneyPayeeTest::testAttributeNames() -{ - for (auto i = (int)Payee::Attribute::Name; i < (int)Payee::Attribute::LastAttribute; ++i) { - auto isEmpty = MyMoneyPayeePrivate::getAttrName(static_cast(i)).isEmpty(); - if (isEmpty) - qWarning() << "Empty attribute's name " << i; - QVERIFY(!isEmpty); - } -} diff --git a/kmymoney/mymoney/tests/mymoneyreport-test.h b/kmymoney/mymoney/tests/mymoneyreport-test.h --- a/kmymoney/mymoney/tests/mymoneyreport-test.h +++ b/kmymoney/mymoney/tests/mymoneyreport-test.h @@ -34,7 +34,5 @@ private Q_SLOTS: void init(); void cleanup(); - void testElementNames(); - void testAttributeNames(); }; #endif diff --git a/kmymoney/mymoney/tests/mymoneyreport-test.cpp b/kmymoney/mymoney/tests/mymoneyreport-test.cpp --- a/kmymoney/mymoney/tests/mymoneyreport-test.cpp +++ b/kmymoney/mymoney/tests/mymoneyreport-test.cpp @@ -34,23 +34,3 @@ { delete m; } - -void MyMoneyReportTest::testElementNames() -{ - for (auto i = (int)Report::Element::Payee; i <= (int)Report::Element::AccountGroup; ++i) { - auto isEmpty = MyMoneyReportPrivate::getElName(static_cast(i)).isEmpty(); - if (isEmpty) - qWarning() << "Empty element's name " << i; - QVERIFY(!isEmpty); - } -} - -void MyMoneyReportTest::testAttributeNames() -{ - for (auto i = (int)Report::Attribute::ID; i < (int)Report::Attribute::LastAttribute; ++i) { - auto isEmpty = MyMoneyReportPrivate::getAttrName(static_cast(i)).isEmpty(); - if (isEmpty) - qWarning() << "Empty attribute's name " << i; - QVERIFY(!isEmpty); - } -} diff --git a/kmymoney/mymoney/tests/mymoneyschedule-test.h b/kmymoney/mymoney/tests/mymoneyschedule-test.h --- a/kmymoney/mymoney/tests/mymoneyschedule-test.h +++ b/kmymoney/mymoney/tests/mymoneyschedule-test.h @@ -31,13 +31,8 @@ void testSetFunctions(); void testCopyConstructor(); void testAssignmentConstructor(); - void testOverdue(); - void testNextPayment(); void testAddHalfMonths(); - void testPaymentDates(); void testWriteXML(); - void testReadXML(); - void testHasReferenceTo(); void testAdjustedNextDueDate(); void testModifyNextDueDate(); void testDaysBetweenEvents(); @@ -47,14 +42,9 @@ void testOccurrencePeriod(); void testSimpleToFromCompoundOccurrence(); void testProcessingDates(); - void testPaidEarlyOneTime(); void testAdjustedNextPayment(); - void testReplaceId(); void testAdjustedWhenItWillEnd(); void testProcessLastDayInMonth(); - void testNextPaymentOnLastDayOfMonth(); - void testElementNames(); - void testAttributeNames(); }; #endif diff --git a/kmymoney/mymoney/tests/mymoneyschedule-test.cpp b/kmymoney/mymoney/tests/mymoneyschedule-test.cpp --- a/kmymoney/mymoney/tests/mymoneyschedule-test.cpp +++ b/kmymoney/mymoney/tests/mymoneyschedule-test.cpp @@ -122,155 +122,6 @@ QCOMPARE(s.type(), s2.type()); } -void MyMoneyScheduleTest::testOverdue() -{ - MyMoneySchedule sch_overdue; - MyMoneySchedule sch_intime; - - // the following checks only work correctly, if currentDate() is - // between the 1st and 27th. If it is between 28th and 31st - // we don't perform them. Note: this should be fixed. - if (QDate::currentDate().day() > 27 || QDate::currentDate().day() == 1) { - qDebug() << "testOverdue() skipped because current day is between 28th and 2nd"; - return; - } - - QDate startDate = QDate::currentDate().addDays(-1).addMonths(-23); - QDate lastPaymentDate = QDate::currentDate().addDays(-1).addMonths(-1); - - QString ref = QString( - "\n" - "\n" - " \n" // krazy:exclude=spelling - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "\n"); - QString ref_overdue = ref.arg(startDate.toString(Qt::ISODate)) - .arg(lastPaymentDate.toString(Qt::ISODate)) - .arg(lastPaymentDate.toString(Qt::ISODate)); - - QString ref_intime = ref.arg(startDate.addDays(1).toString(Qt::ISODate)) - .arg(lastPaymentDate.addDays(1).toString(Qt::ISODate)) - .arg(lastPaymentDate.addDays(1).toString(Qt::ISODate)); - - QDomDocument doc; - QDomElement node; - - // std::cout << ref_intime << std::endl; - try { - doc.setContent(ref_overdue); - node = doc.documentElement().firstChild().toElement(); - sch_overdue = MyMoneySchedule(node); - doc.setContent(ref_intime); - node = doc.documentElement().firstChild().toElement(); - sch_intime = MyMoneySchedule(node); - - QCOMPARE(sch_overdue.isOverdue(), true); - QCOMPARE(sch_intime.isOverdue(), false); - - } catch (const MyMoneyException &) { - QFAIL("Unexpected exception"); - } -} - -void MyMoneyScheduleTest::testNextPayment() -/* - * Test for a schedule where a payment hasn't yet been made. - * First payment is in the future. -*/ -{ - MyMoneySchedule sch; - QString future_sched = QString( - "\n" - "\n" - "\n" // krazy:exclude=spelling - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "\n" - "\n" - ); - - QDomDocument doc; - QDomElement node; - doc.setContent(future_sched); - node = doc.documentElement().firstChild().toElement(); - - try { - sch = MyMoneySchedule(node); - QCOMPARE(sch.nextPayment(QDate(2007, 2, 14)), QDate(2007, 2, 17)); - QCOMPARE(sch.nextPayment(QDate(2007, 2, 17)), QDate(2008, 2, 17)); - QCOMPARE(sch.nextPayment(QDate(2007, 2, 18)), QDate(2008, 2, 17)); - - } catch (const MyMoneyException &) { - QFAIL("Unexpected exception"); - } -} - -void MyMoneyScheduleTest::testNextPaymentOnLastDayOfMonth() -{ - MyMoneySchedule sch; - QString future_sched = QString( - "\n" - "\n" - "\n" // krazy:exclude=spelling - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "\n" - "\n" - ); - - QDomDocument doc; - QDomElement node; - doc.setContent(future_sched); - node = doc.documentElement().firstChild().toElement(); - - try { - sch = MyMoneySchedule(node); - QDate nextPayment; - - // check for the first payment to happen - nextPayment = sch.nextPayment(QDate(2014, 10, 1)); - QCOMPARE(nextPayment, QDate(2014, 10, 31)); - sch.setLastPayment(nextPayment); - - QCOMPARE(sch.nextPayment(QDate(2014, 11, 1)), QDate(2014, 11, 30)); - QCOMPARE(sch.nextPayment(QDate(2014, 12, 1)), QDate(2014, 12, 31)); - QCOMPARE(sch.nextPayment(QDate(2015, 1, 1)), QDate(2015, 1, 31)); - QCOMPARE(sch.nextPayment(QDate(2015, 2, 1)), QDate(2015, 2, 28)); - QCOMPARE(sch.nextPayment(QDate(2015, 3, 1)), QDate(2015, 3, 31)); - - // now check that we also cover leap years - QCOMPARE(sch.nextPayment(QDate(2016, 2, 1)), QDate(2016, 2, 29)); - QCOMPARE(sch.nextPayment(QDate(2016, 3, 1)), QDate(2016, 3, 31)); - - } catch (const MyMoneyException &) { - QFAIL("Unexpected exception"); - } -} - void MyMoneyScheduleTest::testAddHalfMonths() { // addHalfMonths is private @@ -424,293 +275,6 @@ QCOMPARE(s.dateAfter(5).toString(format), QLatin1String("2007-06-30")); } -void MyMoneyScheduleTest::testPaymentDates() -{ - MyMoneySchedule sch; - QString ref_ok = QString( - "\n" - "\n" - - "\n" // krazy:exclude=spelling - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "\n" - - "\n" - ); - - QDomDocument doc; - QDomElement node; - doc.setContent(ref_ok); - node = doc.documentElement().firstChild().toElement(); - - QDate startDate(2006, 1, 28); - QDate endDate(2006, 5, 30); - - try { - sch = MyMoneySchedule(node); - QDate nextPayment = sch.nextPayment(startDate); - QList list = sch.paymentDates(nextPayment, endDate); - QCOMPARE(list.count(), 3); - QCOMPARE(list[0], QDate(2006, 2, 28)); - QCOMPARE(list[1], QDate(2006, 3, 31)); - // Would fall on a Sunday so gets moved back to 28th. - QCOMPARE(list[2], QDate(2006, 4, 28)); - - // Add tests for each possible occurrence. - // Check how paymentDates is meant to work - // Build a list of expected dates and compare - // Schedule::Occurrence::Once - sch.setOccurrence(Schedule::Occurrence::Once); - startDate.setDate(2009, 1, 1); - endDate.setDate(2009, 12, 31); - sch.setStartDate(startDate); - sch.setNextDueDate(startDate); - list = sch.paymentDates(startDate, endDate); - QCOMPARE(list.count(), 1); - QCOMPARE(list[0], QDate(2009, 1, 1)); - // Schedule::Occurrence::Daily - sch.setOccurrence(Schedule::Occurrence::Daily); - startDate.setDate(2009, 1, 1); - endDate.setDate(2009, 1, 5); - sch.setStartDate(startDate); - sch.setNextDueDate(startDate); - list = sch.paymentDates(startDate, endDate); - QCOMPARE(list.count(), 5); - QCOMPARE(list[0], QDate(2009, 1, 1)); - QCOMPARE(list[1], QDate(2009, 1, 2)); - // Would fall on Saturday so gets moved to 2nd. - QCOMPARE(list[2], QDate(2009, 1, 2)); - // Would fall on Sunday so gets moved to 2nd. - QCOMPARE(list[3], QDate(2009, 1, 2)); - QCOMPARE(list[4], QDate(2009, 1, 5)); - // Schedule::Occurrence::Daily with multiplier 2 - sch.setOccurrenceMultiplier(2); - list = sch.paymentDates(startDate.addDays(1), endDate); - QCOMPARE(list.count(), 2); - // Would fall on Sunday so gets moved to 2nd. - QCOMPARE(list[0], QDate(2009, 1, 2)); - QCOMPARE(list[1], QDate(2009, 1, 5)); - sch.setOccurrenceMultiplier(1); - // Schedule::Occurrence::Weekly - sch.setOccurrence(Schedule::Occurrence::Weekly); - startDate.setDate(2009, 1, 6); - endDate.setDate(2009, 2, 4); - sch.setStartDate(startDate); - sch.setNextDueDate(startDate); - list = sch.paymentDates(startDate, endDate); - QCOMPARE(list.count(), 5); - QCOMPARE(list[0], QDate(2009, 1, 6)); - QCOMPARE(list[1], QDate(2009, 1, 13)); - QCOMPARE(list[2], QDate(2009, 1, 20)); - QCOMPARE(list[3], QDate(2009, 1, 27)); - QCOMPARE(list[4], QDate(2009, 2, 3)); - // Schedule::Occurrence::EveryOtherWeek - sch.setOccurrence(Schedule::Occurrence::EveryOtherWeek); - startDate.setDate(2009, 2, 5); - endDate.setDate(2009, 4, 3); - sch.setStartDate(startDate); - sch.setNextDueDate(startDate); - list = sch.paymentDates(startDate, endDate); - QCOMPARE(list.count(), 5); - QCOMPARE(list[0], QDate(2009, 2, 5)); - QCOMPARE(list[1], QDate(2009, 2, 19)); - QCOMPARE(list[2], QDate(2009, 3, 5)); - QCOMPARE(list[3], QDate(2009, 3, 19)); - QCOMPARE(list[4], QDate(2009, 4, 2)); - // Schedule::Occurrence::Fortnightly - sch.setOccurrence(Schedule::Occurrence::Fortnightly); - startDate.setDate(2009, 4, 4); - endDate.setDate(2009, 5, 31); - sch.setStartDate(startDate); - sch.setNextDueDate(startDate); - list = sch.paymentDates(startDate, endDate); - QCOMPARE(list.count(), 4); - // First one would fall on a Saturday and would get moved - // to 3rd which is before start date so is not in list. - // Would fall on a Saturday so gets moved to 17th. - QCOMPARE(list[0], QDate(2009, 4, 17)); - // Would fall on a Saturday so gets moved to 1st. - QCOMPARE(list[1], QDate(2009, 5, 1)); - // Would fall on a Saturday so gets moved to 15th. - QCOMPARE(list[2], QDate(2009, 5, 15)); - // Would fall on a Saturday so gets moved to 29th. - QCOMPARE(list[3], QDate(2009, 5, 29)); - // Schedule::Occurrence::EveryHalfMonth - sch.setOccurrence(Schedule::Occurrence::EveryHalfMonth); - startDate.setDate(2009, 6, 1); - endDate.setDate(2009, 8, 11); - sch.setStartDate(startDate); - sch.setNextDueDate(startDate); - list = sch.paymentDates(startDate, endDate); - QCOMPARE(list.count(), 5); - QCOMPARE(list[0], QDate(2009, 6, 1)); - QCOMPARE(list[1], QDate(2009, 6, 16)); - QCOMPARE(list[2], QDate(2009, 7, 1)); - QCOMPARE(list[3], QDate(2009, 7, 16)); - // Would fall on a Saturday so gets moved to 31st. - QCOMPARE(list[4], QDate(2009, 7, 31)); - // Schedule::Occurrence::EveryThreeWeeks - sch.setOccurrence(Schedule::Occurrence::EveryThreeWeeks); - startDate.setDate(2009, 8, 12); - endDate.setDate(2009, 11, 12); - sch.setStartDate(startDate); - sch.setNextDueDate(startDate); - list = sch.paymentDates(startDate, endDate); - QCOMPARE(list.count(), 5); - QCOMPARE(list[0], QDate(2009, 8, 12)); - QCOMPARE(list[1], QDate(2009, 9, 2)); - QCOMPARE(list[2], QDate(2009, 9, 23)); - QCOMPARE(list[3], QDate(2009, 10, 14)); - QCOMPARE(list[4], QDate(2009, 11, 4)); - // Schedule::Occurrence::EveryFourWeeks - sch.setOccurrence(Schedule::Occurrence::EveryFourWeeks); - startDate.setDate(2009, 11, 13); - endDate.setDate(2010, 3, 13); - sch.setStartDate(startDate); - sch.setNextDueDate(startDate); - list = sch.paymentDates(startDate, endDate); - QCOMPARE(list.count(), 5); - QCOMPARE(list[0], QDate(2009, 11, 13)); - QCOMPARE(list[1], QDate(2009, 12, 11)); - QCOMPARE(list[2], QDate(2010, 1, 8)); - QCOMPARE(list[3], QDate(2010, 2, 5)); - QCOMPARE(list[4], QDate(2010, 3, 5)); - // Schedule::Occurrence::EveryThirtyDays - sch.setOccurrence(Schedule::Occurrence::EveryThirtyDays); - startDate.setDate(2010, 3, 19); - endDate.setDate(2010, 7, 19); - sch.setStartDate(startDate); - sch.setNextDueDate(startDate); - list = sch.paymentDates(startDate, endDate); - QCOMPARE(list.count(), 5); - QCOMPARE(list[0], QDate(2010, 3, 19)); - // Would fall on a Sunday so gets moved to 16th. - QCOMPARE(list[1], QDate(2010, 4, 16)); - QCOMPARE(list[2], QDate(2010, 5, 18)); - QCOMPARE(list[3], QDate(2010, 6, 17)); - // Would fall on a Saturday so gets moved to 16th. - QCOMPARE(list[4], QDate(2010, 7, 16)); - // Schedule::Occurrence::EveryEightWeeks - sch.setOccurrence(Schedule::Occurrence::EveryEightWeeks); - startDate.setDate(2010, 7, 26); - endDate.setDate(2011, 3, 26); - sch.setStartDate(startDate); - sch.setNextDueDate(startDate); - list = sch.paymentDates(startDate, endDate); - QCOMPARE(list.count(), 5); - QCOMPARE(list[0], QDate(2010, 7, 26)); - QCOMPARE(list[1], QDate(2010, 9, 20)); - QCOMPARE(list[2], QDate(2010, 11, 15)); - QCOMPARE(list[3], QDate(2011, 1, 10)); - QCOMPARE(list[4], QDate(2011, 3, 7)); - // Schedule::Occurrence::EveryOtherMonth - sch.setOccurrence(Schedule::Occurrence::EveryOtherMonth); - startDate.setDate(2011, 3, 14); - endDate.setDate(2011, 11, 20); - sch.setStartDate(startDate); - sch.setNextDueDate(startDate); - list = sch.paymentDates(startDate, endDate); - QCOMPARE(list.count(), 5); - QCOMPARE(list[0], QDate(2011, 3, 14)); - // Would fall on a Saturday so gets moved to 13th. - QCOMPARE(list[1], QDate(2011, 5, 13)); - QCOMPARE(list[2], QDate(2011, 7, 14)); - QCOMPARE(list[3], QDate(2011, 9, 14)); - QCOMPARE(list[4], QDate(2011, 11, 14)); - // Schedule::Occurrence::EveryThreeMonths - sch.setOccurrence(Schedule::Occurrence::EveryThreeMonths); - startDate.setDate(2011, 11, 15); - endDate.setDate(2012, 11, 19); - sch.setStartDate(startDate); - sch.setNextDueDate(startDate); - list = sch.paymentDates(startDate, endDate); - QCOMPARE(list.count(), 5); - QCOMPARE(list[0], QDate(2011, 11, 15)); - QCOMPARE(list[1], QDate(2012, 2, 15)); - QCOMPARE(list[2], QDate(2012, 5, 15)); - QCOMPARE(list[3], QDate(2012, 8, 15)); - QCOMPARE(list[4], QDate(2012, 11, 15)); - // Schedule::Occurrence::Quarterly - sch.setOccurrence(Schedule::Occurrence::Quarterly); - startDate.setDate(2012, 11, 20); - endDate.setDate(2013, 11, 23); - sch.setStartDate(startDate); - sch.setNextDueDate(startDate); - list = sch.paymentDates(startDate, endDate); - QCOMPARE(list.count(), 5); - QCOMPARE(list[0], QDate(2012, 11, 20)); - QCOMPARE(list[1], QDate(2013, 2, 20)); - QCOMPARE(list[2], QDate(2013, 5, 20)); - QCOMPARE(list[3], QDate(2013, 8, 20)); - QCOMPARE(list[4], QDate(2013, 11, 20)); - // Schedule::Occurrence::EveryFourMonths - sch.setOccurrence(Schedule::Occurrence::EveryFourMonths); - startDate.setDate(2013, 11, 21); - endDate.setDate(2015, 3, 23); - sch.setStartDate(startDate); - sch.setNextDueDate(startDate); - list = sch.paymentDates(startDate, endDate); - QCOMPARE(list.count(), 5); - QCOMPARE(list[0], QDate(2013, 11, 21)); - QCOMPARE(list[1], QDate(2014, 3, 21)); - QCOMPARE(list[2], QDate(2014, 7, 21)); - QCOMPARE(list[3], QDate(2014, 11, 21)); - // Would fall on a Saturday so gets moved to 20th. - QCOMPARE(list[4], QDate(2015, 3, 20)); - // Schedule::Occurrence::TwiceYearly - sch.setOccurrence(Schedule::Occurrence::TwiceYearly); - startDate.setDate(2015, 3, 22); - endDate.setDate(2017, 3, 29); - sch.setStartDate(startDate); - sch.setNextDueDate(startDate); - list = sch.paymentDates(startDate, endDate); - QCOMPARE(list.count(), 4); - // First date would fall on a Sunday which would get moved - // to 20th which is before start date so not in list. - QCOMPARE(list[0], QDate(2015, 9, 22)); - QCOMPARE(list[1], QDate(2016, 3, 22)); - QCOMPARE(list[2], QDate(2016, 9, 22)); - QCOMPARE(list[3], QDate(2017, 3, 22)); - // Schedule::Occurrence::Yearly - sch.setOccurrence(Schedule::Occurrence::Yearly); - startDate.setDate(2017, 3, 23); - endDate.setDate(2021, 3, 29); - sch.setStartDate(startDate); - sch.setNextDueDate(startDate); - list = sch.paymentDates(startDate, endDate); - QCOMPARE(list.count(), 5); - QCOMPARE(list[0], QDate(2017, 3, 23)); - QCOMPARE(list[1], QDate(2018, 3, 23)); - // Would fall on a Saturday so gets moved to 22nd. - QCOMPARE(list[2], QDate(2019, 3, 22)); - QCOMPARE(list[3], QDate(2020, 3, 23)); - QCOMPARE(list[4], QDate(2021, 3, 23)); - // Schedule::Occurrence::EveryOtherYear - sch.setOccurrence(Schedule::Occurrence::EveryOtherYear); - startDate.setDate(2021, 3, 24); - endDate.setDate(2029, 3, 30); - sch.setStartDate(startDate); - sch.setNextDueDate(startDate); - list = sch.paymentDates(startDate, endDate); - QCOMPARE(list.count(), 5); - QCOMPARE(list[0], QDate(2021, 3, 24)); - QCOMPARE(list[1], QDate(2023, 3, 24)); - QCOMPARE(list[2], QDate(2025, 3, 24)); - QCOMPARE(list[3], QDate(2027, 3, 24)); - // Would fall on a Saturday so gets moved to 23rd. - QCOMPARE(list[4], QDate(2029, 3, 23)); - } catch (const MyMoneyException &) { - QFAIL("Unexpected exception"); - } -} - void MyMoneyScheduleTest::testWriteXML() { MyMoneySchedule sch("A Name", @@ -843,185 +407,6 @@ QCOMPARE(keyValuePair1.childNodes().size(), 0); } -void MyMoneyScheduleTest::testReadXML() -{ - MyMoneySchedule sch; - - QString ref_ok1 = QString( - "\n" - "\n" - " \n" // krazy:exclude=spelling - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "\n" - ).arg(QDate::currentDate().toString(Qt::ISODate)) - .arg(QDate::currentDate().toString(Qt::ISODate)) - .arg(QDate::currentDate().toString(Qt::ISODate)); - - // diff to ref_ok1 is that we now have an empty entrydate - // in the transaction parameters - QString ref_ok2 = QString( - "\n" - "\n" - " \n" // krazy:exclude=spelling - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "\n" - ).arg(QDate::currentDate().toString(Qt::ISODate)) - .arg(QDate::currentDate().toString(Qt::ISODate)) - .arg(QDate::currentDate().toString(Qt::ISODate)); - - QString ref_false = QString( - "\n" - "\n" - " \n" // krazy:exclude=spelling - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "\n" - ).arg(QDate::currentDate().toString(Qt::ISODate)) - .arg(QDate::currentDate().toString(Qt::ISODate)) - .arg(QDate::currentDate().toString(Qt::ISODate)); - - QDomDocument doc; - QDomElement node; - doc.setContent(ref_false); - node = doc.documentElement().firstChild().toElement(); - - try { - sch = MyMoneySchedule(node); - QFAIL("Missing expected exception"); - } catch (const MyMoneyException &) { - } - - doc.setContent(ref_ok1); - node = doc.documentElement().firstChild().toElement(); - - - try { - sch = MyMoneySchedule(node); - QCOMPARE(sch.id(), QLatin1String("SCH0002")); - QCOMPARE(sch.nextDueDate(), QDate::currentDate().addDays(7)); - QCOMPARE(sch.startDate(), QDate::currentDate()); - QCOMPARE(sch.endDate(), QDate()); - QCOMPARE(sch.autoEnter(), true); - QCOMPARE(sch.isFixed(), true); - QCOMPARE(sch.weekendOption(), Schedule::WeekendOption::MoveNothing); - QCOMPARE(sch.lastPayment(), QDate::currentDate()); - QCOMPARE(sch.paymentType(), Schedule::PaymentType::DirectDebit); - QCOMPARE(sch.type(), Schedule::Type::Bill); - QCOMPARE(sch.name(), QLatin1String("A Name")); - QCOMPARE(sch.occurrence(), Schedule::Occurrence::Weekly); - QCOMPARE(sch.occurrenceMultiplier(), 1); - QCOMPARE(sch.nextDueDate(), sch.lastPayment().addDays(7)); - QCOMPARE(sch.recordedPayments().count(), 1); - QCOMPARE(sch.recordedPayments()[0], QDate::currentDate()); - } catch (const MyMoneyException &) { - QFAIL("Unexpected exception"); - } - - doc.setContent(ref_ok2); - node = doc.documentElement().firstChild().toElement(); - - - try { - sch = MyMoneySchedule(node); - QCOMPARE(sch.id(), QLatin1String("SCH0002")); - QCOMPARE(sch.nextDueDate(), QDate::currentDate().addDays(7)); - QCOMPARE(sch.startDate(), QDate::currentDate()); - QCOMPARE(sch.endDate(), QDate()); - QCOMPARE(sch.autoEnter(), true); - QCOMPARE(sch.isFixed(), true); - QCOMPARE(sch.weekendOption(), Schedule::WeekendOption::MoveNothing); - QCOMPARE(sch.lastPayment(), QDate::currentDate()); - QCOMPARE(sch.paymentType(), Schedule::PaymentType::DirectDebit); - QCOMPARE(sch.type(), Schedule::Type::Bill); - QCOMPARE(sch.name(), QLatin1String("A Name")); - QCOMPARE(sch.occurrence(), Schedule::Occurrence::Weekly); - QCOMPARE(sch.occurrenceMultiplier(), 1); - QCOMPARE(sch.nextDueDate(), sch.lastPayment().addDays(7)); - QCOMPARE(sch.recordedPayments().count(), 1); - QCOMPARE(sch.recordedPayments()[0], QDate::currentDate()); - } catch (const MyMoneyException &) { - QFAIL("Unexpected exception"); - } -} - -void MyMoneyScheduleTest::testHasReferenceTo() -{ - MyMoneySchedule sch; - QString ref_ok = QString( - "\n" - "\n" - " \n" // krazy:exclude=spelling - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "\n" - ).arg(QDate::currentDate().toString(Qt::ISODate)) - .arg(QDate::currentDate().toString(Qt::ISODate)) - .arg(QDate::currentDate().toString(Qt::ISODate)); - - QDomDocument doc; - QDomElement node; - doc.setContent(ref_ok); - node = doc.documentElement().firstChild().toElement(); - - try { - sch = MyMoneySchedule(node); - - } catch (const MyMoneyException &) { - QFAIL("Unexpected exception"); - } - - QCOMPARE(sch.hasReferenceTo(QLatin1String("P000001")), true); - QCOMPARE(sch.hasReferenceTo(QLatin1String("A000276")), true); - QCOMPARE(sch.hasReferenceTo(QLatin1String("A000076")), true); - QCOMPARE(sch.hasReferenceTo(QLatin1String("EUR")), true); -} - void MyMoneyScheduleTest::testAdjustedNextDueDate() { MyMoneySchedule s; @@ -1605,46 +990,7 @@ QCOMPARE(s.isProcessingDate(QDate(2010, 1, 2)), false); } -void MyMoneyScheduleTest::testPaidEarlyOneTime() -{ -// this tries to figure out what's wrong with -// https://bugs.kde.org/show_bug.cgi?id=231029 - - MyMoneySchedule sch; - QDate paymentInFuture = QDate::currentDate().addDays(7); - - QString ref_ok = QString( - "\n" - "\n" - " \n" // krazy:exclude=spelling - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "\n" - ).arg(paymentInFuture.toString(Qt::ISODate)) - .arg(paymentInFuture.toString(Qt::ISODate)) - .arg(paymentInFuture.toString(Qt::ISODate)); - - QDomDocument doc; - QDomElement node; - doc.setContent(ref_ok); - node = doc.documentElement().firstChild().toElement(); - - try { - sch = MyMoneySchedule(node); - QCOMPARE(sch.isFinished(), true); - QCOMPARE(sch.occurrencePeriod(), Schedule::Occurrence::Monthly); - QCOMPARE(sch.paymentDates(QDate::currentDate(), QDate::currentDate().addDays(21)).count(), 0); - } catch (const MyMoneyException &) { - QFAIL("Unexpected exception"); - } -} void MyMoneyScheduleTest::testAdjustedNextPayment() { @@ -1665,48 +1011,6 @@ QCOMPARE(s.adjustedNextPayment(s.adjustedNextDueDate()), s.adjustedDate(nextDueDate, s.weekendOption())); } -void MyMoneyScheduleTest::testReplaceId() -{ - MyMoneySchedule sch; - QDate paymentInFuture = QDate::currentDate().addDays(7); - - QString ref_ok = QString( - "\n" - "\n" - " \n" // krazy:exclude=spelling - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "\n" - ).arg(paymentInFuture.toString(Qt::ISODate)) - .arg(paymentInFuture.toString(Qt::ISODate)) - .arg(paymentInFuture.toString(Qt::ISODate)); - - QDomDocument doc; - QDomElement node; - doc.setContent(ref_ok); - node = doc.documentElement().firstChild().toElement(); - - try { - sch = MyMoneySchedule(node); - QCOMPARE(sch.transaction().postDate().isValid(), false); - QCOMPARE(sch.transaction().splits()[0].accountId(), QLatin1String("A000076")); - QCOMPARE(sch.transaction().splits()[1].accountId(), QLatin1String("A000276")); - QCOMPARE(sch.replaceId(QLatin1String("A000079"), QLatin1String("A000076")), true); - QCOMPARE(sch.transaction().splits()[0].accountId(), QLatin1String("A000079")); - QCOMPARE(sch.transaction().splits()[1].accountId(), QLatin1String("A000276")); - - } catch (const MyMoneyException &) { - QFAIL("Unexpected exception"); - } - -} - void MyMoneyScheduleTest::testAdjustedWhenItWillEnd() { MyMoneySchedule s; @@ -1744,26 +1048,6 @@ QCOMPARE(s.transactionsRemaining(), 2); } -void MyMoneyScheduleTest::testElementNames() -{ - for (auto i = (int)Schedule::Element::Payment; i <= (int)Schedule::Element::Payments; ++i) { - auto isEmpty = MyMoneySchedulePrivate::getElName(static_cast(i)).isEmpty(); - if (isEmpty) - qWarning() << "Empty element's name " << i; - QVERIFY(!isEmpty); - } -} - -void MyMoneyScheduleTest::testAttributeNames() -{ - for (auto i = (int)Schedule::Attribute::Name; i < (int)Schedule::Attribute::LastAttribute; ++i) { - auto isEmpty = MyMoneySchedulePrivate::getAttrName(static_cast(i)).isEmpty(); - if (isEmpty) - qWarning() << "Empty attribute's name " << i; - QVERIFY(!isEmpty); - } -} - void MyMoneyScheduleTest::testProcessLastDayInMonth() { MyMoneySchedule s; diff --git a/kmymoney/mymoney/tests/mymoneysecurity-test.h b/kmymoney/mymoney/tests/mymoneysecurity-test.h --- a/kmymoney/mymoney/tests/mymoneysecurity-test.h +++ b/kmymoney/mymoney/tests/mymoneysecurity-test.h @@ -41,7 +41,6 @@ void testInequality(); // void testMyMoneyFileConstructor(); // void testAccountIDList (); - void testAttributeNames(); }; #endif diff --git a/kmymoney/mymoney/tests/mymoneysecurity-test.cpp b/kmymoney/mymoney/tests/mymoneysecurity-test.cpp --- a/kmymoney/mymoney/tests/mymoneysecurity-test.cpp +++ b/kmymoney/mymoney/tests/mymoneysecurity-test.cpp @@ -213,13 +213,3 @@ } */ - -void MyMoneySecurityTest::testAttributeNames() -{ - for (auto i = (int)Security::Attribute::Name; i < (int)Security::Attribute::LastAttribute; ++i) { - auto isEmpty = MyMoneySecurityPrivate::getAttrName(static_cast(i)).isEmpty(); - if (isEmpty) - qWarning() << "Empty attribute's name " << i; - QVERIFY(!isEmpty); - } -} diff --git a/kmymoney/mymoney/tests/mymoneytag-test.h b/kmymoney/mymoney/tests/mymoneytag-test.h deleted file mode 100644 --- a/kmymoney/mymoney/tests/mymoneytag-test.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2012 Alessandro Russo - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef MYMONEYTAGTEST_H -#define MYMONEYTAGTEST_H - -#include - -class MyMoneyTagTest : public QObject -{ - Q_OBJECT -private Q_SLOTS: - void testXml(); - void testAttributeNames(); -}; - -#endif diff --git a/kmymoney/mymoney/tests/mymoneytag-test.cpp b/kmymoney/mymoney/tests/mymoneytag-test.cpp deleted file mode 100644 --- a/kmymoney/mymoney/tests/mymoneytag-test.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2012 Alessandro Russo - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "mymoneytag-test.h" - -#include -#include - -#include - -#define KMM_MYMONEY_UNIT_TESTABLE friend class MyMoneyTagTest; - -#include "mymoneytag.h" -#include "mymoneytag_p.h" - -using namespace std; - -QTEST_GUILESS_MAIN(MyMoneyTagTest) - -void MyMoneyTagTest::testXml() -{ - QDomDocument doc; - QDomElement parent = doc.createElement("Test"); - doc.appendChild(parent); - MyMoneyTag tag1; - tag1.d_func()->m_id = "some random id";//if the ID isn't set, w ethrow an exception - tag1.writeXML(doc, parent); - QDomElement el = parent.firstChild().toElement(); - QVERIFY(!el.isNull()); - MyMoneyTag tag2(el); -} - -void MyMoneyTagTest::testAttributeNames() -{ - for (auto i = (int)Tag::Attribute::Name; i < (int)Tag::Attribute::LastAttribute; ++i) { - auto isEmpty = MyMoneyTagPrivate::getAttrName(static_cast(i)).isEmpty(); - if (isEmpty) - qWarning() << "Empty attribute's name " << i; - QVERIFY(!isEmpty); - } -} diff --git a/kmymoney/mymoney/tests/mymoneytransaction-test.h b/kmymoney/mymoney/tests/mymoneytransaction-test.h --- a/kmymoney/mymoney/tests/mymoneytransaction-test.h +++ b/kmymoney/mymoney/tests/mymoneytransaction-test.h @@ -52,15 +52,11 @@ //void testAddDuplicateAccount(); //void testModifyDuplicateAccount(); void testWriteXML(); - void testReadXML(); - void testReadXMLEx(); void testAutoCalc(); void testHasReferenceTo(); void testIsStockSplit(); void testAddMissingAccountId(); void testModifyMissingAccountId(); void testReplaceId(); - void testElementNames(); - void testAttributeNames(); }; #endif diff --git a/kmymoney/mymoney/tests/mymoneytransaction-test.cpp b/kmymoney/mymoney/tests/mymoneytransaction-test.cpp --- a/kmymoney/mymoney/tests/mymoneytransaction-test.cpp +++ b/kmymoney/mymoney/tests/mymoneytransaction-test.cpp @@ -493,124 +493,6 @@ QCOMPARE(keyValuePair1.childNodes().size(), 0); } -void MyMoneyTransactionTest::testReadXML() -{ - MyMoneyTransaction t; - - QString ref_ok = QString( - "\n" - "\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "\n" - ); - - QString ref_false = QString( - "\n" - "\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "\n" - ); - - QDomDocument doc; - QDomElement node; - doc.setContent(ref_false); - node = doc.documentElement().firstChild().toElement(); - - try { - t = MyMoneyTransaction(node); - QFAIL("Missing expected exception"); - } catch (const MyMoneyException &) { - } - - doc.setContent(ref_ok); - node = doc.documentElement().firstChild().toElement(); - - t.setValue("key", "VALUE"); - try { - t = MyMoneyTransaction(node); - QVERIFY(t.postDate() == QDate(2001, 12, 28)); - QVERIFY(t.entryDate() == QDate(2003, 9, 29)); - QVERIFY(t.id() == "T000000000000000001"); - QVERIFY(t.memo() == "Wohnung:Miete"); - QVERIFY(t.commodity() == "EUR"); - QVERIFY(t.pairs().count() == 1); - QVERIFY(t.value("key") == "value"); - QVERIFY(t.splits().count() == 1); - } catch (const MyMoneyException &) { - QFAIL("Unexpected exception"); - } -} - -void MyMoneyTransactionTest::testReadXMLEx() -{ - MyMoneyTransaction t; - - QString ref_ok = QString( - "\n" - "\n" - "\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " &lt;CONTAINER>\n" - " &lt;TRANSACTION postdate="2010-03-05" memo="UMBUCHUNG" id="" commodity="EUR" entrydate="2010-03-08" >\n" - " &lt;SPLITS>\n" - " &lt;SPLIT payee="P000010" reconciledate="" shares="125000/100" action="Transfer" bankid="" number="" reconcileflag="0" memo="UMBUCHUNG" value="125000/100" id="S0001" account="A000087" />\n" - " &lt;SPLIT payee="P000010" reconciledate="" shares="-125000/100" action="" bankid="A000076-2010-03-05-b6850c0-1" number="" reconcileflag="0" memo="UMBUCHUNG" value="-125000/100" id="S0002" account="A000076" />\n" - " &lt;/SPLITS>\n" - " &lt;KEYVALUEPAIRS>\n" - " &lt;PAIR key="Imported" value="true" />\n" - " &lt;/KEYVALUEPAIRS>\n" - " &lt;/TRANSACTION>\n" - " &lt;/CONTAINER>\n" - "\" />\n" - " \n" - " \n" - " \n" - " \n" - " \n" - "\n" - "\n" - ); - QDomDocument doc; - QDomElement node; - doc.setContent(ref_ok); - node = doc.documentElement().firstChild().toElement(); - - try { - t = MyMoneyTransaction(node); - QVERIFY(t.pairs().count() == 0); - QVERIFY(t.splits().size() == 2); - QVERIFY(t.splits()[0].pairs().count() == 3); - QVERIFY(t.splits()[1].pairs().count() == 0); - QVERIFY(t.splits()[0].isMatched()); - - MyMoneyTransaction ti = t.splits()[0].matchedTransaction(); - QVERIFY(ti.pairs().count() == 1); - QVERIFY(ti.isImported()); - QVERIFY(ti.splits().count() == 2); - } catch (const MyMoneyException &) { - QFAIL("Unexpected exception"); - } -} - void MyMoneyTransactionTest::testHasReferenceTo() { MyMoneyTransaction t; @@ -718,23 +600,3 @@ unexpectedException(e); } } - -void MyMoneyTransactionTest::testElementNames() -{ - for (auto i = (int)Transaction::Element::Split; i <= (int)Transaction::Element::Splits; ++i) { - auto isEmpty = MyMoneyTransactionPrivate::getElName(static_cast(i)).isEmpty(); - if (isEmpty) - qWarning() << "Empty element's name " << i; - QVERIFY(!isEmpty); - } -} - -void MyMoneyTransactionTest::testAttributeNames() -{ - for (auto i = (int)Transaction::Attribute::Name; i < (int)Transaction::Attribute::LastAttribute; ++i) { - auto isEmpty = MyMoneyTransactionPrivate::getAttrName(static_cast(i)).isEmpty(); - if (isEmpty) - qWarning() << "Empty attribute's name " << i; - QVERIFY(!isEmpty); - } -} diff --git a/kmymoney/mymoney/tests/onlinejob-test.h b/kmymoney/mymoney/tests/onlinejob-test.h --- a/kmymoney/mymoney/tests/onlinejob-test.h +++ b/kmymoney/mymoney/tests/onlinejob-test.h @@ -33,8 +33,6 @@ void testCopyConstructor(); void testCopyAssignment(); void testCopyConstructorWithNewId(); - void testElementNames(); - void testAttributeNames(); }; #endif // ONLINEJOBTEST_H diff --git a/kmymoney/mymoney/tests/onlinejob-test.cpp b/kmymoney/mymoney/tests/onlinejob-test.cpp --- a/kmymoney/mymoney/tests/onlinejob-test.cpp +++ b/kmymoney/mymoney/tests/onlinejob-test.cpp @@ -35,7 +35,7 @@ QVERIFY(job.isNull()); QVERIFY(job.sendDate().isNull()); QVERIFY(job.bankAnswerDate().isNull()); - QVERIFY(job.bankAnswerState() == onlineJob::noBankAnswer); + QVERIFY(job.bankAnswerState() == eMyMoney::OnlineJob::sendingState::noBankAnswer); QVERIFY(job.jobMessageList().isEmpty()); QVERIFY(job.isLocked() == false); @@ -70,32 +70,12 @@ void onlineJobTest::testCopyConstructorWithNewId() { onlineJob originalJob = onlineJob(new dummyTask, "O000001"); - originalJob.setBankAnswer(onlineJob::acceptedByBank); + originalJob.setBankAnswer(eMyMoney::OnlineJob::sendingState::acceptedByBank); QVERIFY(!originalJob.isNull()); onlineJob jobCopy = onlineJob("O000002", originalJob); QVERIFY(!jobCopy.isNull()); QCOMPARE(jobCopy.id(), QString("O000002")); QVERIFY(originalJob.task() != jobCopy.task()); QVERIFY(jobCopy.bankAnswerDate().isNull()); } - -void onlineJobTest::testElementNames() -{ - for (auto i = (int)OnlineJob::Element::OnlineTask; i <= (int)OnlineJob::Element::OnlineTask; ++i) { - auto isEmpty = onlineJobPrivate::getElName(static_cast(i)).isEmpty(); - if (isEmpty) - qWarning() << "Empty element's name " << i; - QVERIFY(!isEmpty); - } -} - -void onlineJobTest::testAttributeNames() -{ - for (auto i = (int)OnlineJob::Attribute::Send; i < (int)OnlineJob::Attribute::LastAttribute; ++i) { - auto isEmpty = onlineJobPrivate::getAttrName(static_cast(i)).isEmpty(); - if (isEmpty) - qWarning() << "Empty attribute's name " << i; - QVERIFY(!isEmpty); - } -} diff --git a/kmymoney/plugins/kbanking/kbanking.cpp b/kmymoney/plugins/kbanking/kbanking.cpp --- a/kmymoney/plugins/kbanking/kbanking.cpp +++ b/kmymoney/plugins/kbanking/kbanking.cpp @@ -920,9 +920,9 @@ job.setJobSend(); if (abStatus == AB_Job_StatusFinished) - job.setBankAnswer(onlineJob::acceptedByBank); + job.setBankAnswer(eMyMoney::OnlineJob::sendingState::acceptedByBank); else if (abStatus == AB_Job_StatusError || abStatus == AB_Job_StatusUnknown) - job.setBankAnswer(onlineJob::sendingError); + job.setBankAnswer(eMyMoney::OnlineJob::sendingState::sendingError); job.addJobMessage(onlineJobMessage(eMyMoney::OnlineJob::MessageType::Debug, "KBanking", "Job was processed")); m_parent->m_onlineJobQueue.insert(jobIdent, job); diff --git a/kmymoney/plugins/sql/mymoneystoragesql.cpp b/kmymoney/plugins/sql/mymoneystoragesql.cpp --- a/kmymoney/plugins/sql/mymoneystoragesql.cpp +++ b/kmymoney/plugins/sql/mymoneystoragesql.cpp @@ -1380,18 +1380,18 @@ onlineTask *const task = d->createOnlineTaskObject(query.value(1).toString(), id, *this); onlineJob job = onlineJob(task, id); job.setJobSend(query.value(2).toDateTime()); - onlineJob::sendingState state; + eMyMoney::OnlineJob::sendingState state; const QString stateString = query.value(4).toString(); if (stateString == "acceptedByBank") - state = onlineJob::acceptedByBank; + state = eMyMoney::OnlineJob::sendingState::acceptedByBank; else if (stateString == "rejectedByBank") - state = onlineJob::rejectedByBank; + state = eMyMoney::OnlineJob::sendingState::rejectedByBank; else if (stateString == "abortedByUser") - state = onlineJob::abortedByUser; + state = eMyMoney::OnlineJob::sendingState::abortedByUser; else if (stateString == "sendingError") - state = onlineJob::sendingError; + state = eMyMoney::OnlineJob::sendingState::sendingError; else // includes: stateString == "noBankAnswer" - state = onlineJob::noBankAnswer; + state = eMyMoney::OnlineJob::sendingState::noBankAnswer; job.setBankAnswer(state, query.value(4).toDateTime()); job.setLock(query.value(5).toString() == QLatin1String("Y") ? true : false); diff --git a/kmymoney/plugins/sql/mymoneystoragesql_p.h b/kmymoney/plugins/sql/mymoneystoragesql_p.h --- a/kmymoney/plugins/sql/mymoneystoragesql_p.h +++ b/kmymoney/plugins/sql/mymoneystoragesql_p.h @@ -1517,11 +1517,11 @@ query.bindValue(":jobSend", job.sendDate()); query.bindValue(":bankAnswerDate", job.bankAnswerDate()); switch (job.bankAnswerState()) { - case onlineJob::acceptedByBank: query.bindValue(":state", QLatin1String("acceptedByBank")); break; - case onlineJob::rejectedByBank: query.bindValue(":state", QLatin1String("rejectedByBank")); break; - case onlineJob::abortedByUser: query.bindValue(":state", QLatin1String("abortedByUser")); break; - case onlineJob::sendingError: query.bindValue(":state", QLatin1String("sendingError")); break; - case onlineJob::noBankAnswer: + case eMyMoney::OnlineJob::sendingState::acceptedByBank: query.bindValue(":state", QLatin1String("acceptedByBank")); break; + case eMyMoney::OnlineJob::sendingState::rejectedByBank: query.bindValue(":state", QLatin1String("rejectedByBank")); break; + case eMyMoney::OnlineJob::sendingState::abortedByUser: query.bindValue(":state", QLatin1String("abortedByUser")); break; + case eMyMoney::OnlineJob::sendingState::sendingError: query.bindValue(":state", QLatin1String("sendingError")); break; + case eMyMoney::OnlineJob::sendingState::noBankAnswer: default: query.bindValue(":state", QLatin1String("noBankAnswer")); } query.bindValue(":locked", QVariant::fromValue(job.isLocked() ? QLatin1String("Y") : QLatin1String("N"))); diff --git a/kmymoney/plugins/views/onlinejoboutbox/onlinejobmodel.cpp b/kmymoney/plugins/views/onlinejoboutbox/onlinejobmodel.cpp --- a/kmymoney/plugins/views/onlinejoboutbox/onlinejobmodel.cpp +++ b/kmymoney/plugins/views/onlinejoboutbox/onlinejobmodel.cpp @@ -144,11 +144,11 @@ return Icons::get(Icon::TaskOngoing); switch (job.bankAnswerState()) { - case onlineJob::acceptedByBank: return Icons::get(Icon::TaskComplete); - case onlineJob::sendingError: - case onlineJob::abortedByUser: - case onlineJob::rejectedByBank: return Icons::get(Icon::TaskReject); - case onlineJob::noBankAnswer: break; + case eMyMoney::OnlineJob::sendingState::acceptedByBank: return Icons::get(Icon::TaskComplete); + case eMyMoney::OnlineJob::sendingState::sendingError: + case eMyMoney::OnlineJob::sendingState::abortedByUser: + case eMyMoney::OnlineJob::sendingState::rejectedByBank: return Icons::get(Icon::TaskReject); + case eMyMoney::OnlineJob::sendingState::noBankAnswer: break; } if (job.sendDate().isValid()) { return Icons::get(Icon::TaskAccepted); @@ -160,11 +160,11 @@ return i18n("Job is being processed at the moment."); switch (job.bankAnswerState()) { - case onlineJob::acceptedByBank: return i18nc("Arg 1 is a date/time", "This job was accepted by the bank on %1.", job.bankAnswerDate().toString(Qt::DefaultLocaleShortDate)); - case onlineJob::sendingError: return i18nc("Arg 1 is a date/time", "Sending this job failed (tried on %1).", job.sendDate().toString(Qt::DefaultLocaleShortDate)); - case onlineJob::abortedByUser: return i18n("Sending this job was manually aborted."); - case onlineJob::rejectedByBank: return i18nc("Arg 1 is a date/time", "The bank rejected this job on %1.", job.bankAnswerDate().toString(Qt::DefaultLocaleShortDate)); - case onlineJob::noBankAnswer: + case eMyMoney::OnlineJob::sendingState::acceptedByBank: return i18nc("Arg 1 is a date/time", "This job was accepted by the bank on %1.", job.bankAnswerDate().toString(Qt::DefaultLocaleShortDate)); + case eMyMoney::OnlineJob::sendingState::sendingError: return i18nc("Arg 1 is a date/time", "Sending this job failed (tried on %1).", job.sendDate().toString(Qt::DefaultLocaleShortDate)); + case eMyMoney::OnlineJob::sendingState::abortedByUser: return i18n("Sending this job was manually aborted."); + case eMyMoney::OnlineJob::sendingState::rejectedByBank: return i18nc("Arg 1 is a date/time", "The bank rejected this job on %1.", job.bankAnswerDate().toString(Qt::DefaultLocaleShortDate)); + case eMyMoney::OnlineJob::sendingState::noBankAnswer: if (job.sendDate().isValid()) return i18nc("Arg 1 is a date/time", "The bank accepted this job on %1.", job.sendDate().toString(Qt::DefaultLocaleShortDate)); else if (!job.isValid()) diff --git a/kmymoney/plugins/xml/CMakeLists.txt b/kmymoney/plugins/xml/CMakeLists.txt --- a/kmymoney/plugins/xml/CMakeLists.txt +++ b/kmymoney/plugins/xml/CMakeLists.txt @@ -38,9 +38,9 @@ # DESTINATION ${SERVICETYPES_INSTALL_DIR} # ) -# if(BUILD_TESTING) -# add_subdirectory(tests) -# endif() +if(BUILD_TESTING) + add_subdirectory(tests) +endif() # the KCM module diff --git a/kmymoney/plugins/xml/mymoneystoragenames.h b/kmymoney/plugins/xml/mymoneystoragenames.h --- a/kmymoney/plugins/xml/mymoneystoragenames.h +++ b/kmymoney/plugins/xml/mymoneystoragenames.h @@ -68,4 +68,397 @@ extern const QHash stdAccNames; } +enum class StdAccName { + Liability, + Asset, + Expense, + Income, + Equity +}; + +enum class Tag { + Institutions, + Payees, + CostCenters, + Tags, + Accounts, + Transactions, + Schedules, + Securities, + Currencies, + Prices, + Reports, + Budgets, + OnlineJobs, + KMMFile, + FileInfo, + User +}; + +enum class Node { + Institution, + Payee, + CostCenter, + Tag, + Account, + Transaction, + ScheduleTX, + Security, + Currency, + Price, + PricePair, + Report, + Budget, + OnlineJob, + KeyValuePairs, + Equity +}; + +namespace Element { + enum class General { + Address, + CreationDate, + LastModifiedDate, + Version, + FixVersion, + Pair + }; + + enum class Transaction { + Split = 0, + Splits + }; + + enum class Account { + SubAccount, + SubAccounts, + OnlineBanking + }; + + enum class Payee { + Address + }; + + enum class KVP { + Pair + }; + + enum class Institution { + AccountID, + AccountIDS, + Address + }; + + enum class Report { + Payee, + Tag, + Account, + Text, + Type, + State, + Number, + Amount, + Dates, + Category, + AccountGroup + }; + + enum class Budget { + Budget = 0, + Account, + Period + }; + + enum class Schedule { + Payment, + Payments + }; + + enum class OnlineJob { + OnlineTask + }; +} + +namespace Attribute { + enum class General { + ID = 0, + Date, + Count, + From, + To, + Source, + Key, + Value, + Price, + Name, + Email, + Country, + City, + ZipCode, + Street, + Telephone, + // insert new entries above this line + LastAttribute + }; + + enum class Transaction { + Name = 0, + Type, + PostDate, + Memo, + EntryDate, + Commodity, + BankID, + // insert new entries above this line + LastAttribute + }; + + enum class Account { + ID = 0, + Name, + Type, + ParentAccount, + LastReconciled, + LastModified, + Institution, + Opened, + Number, + Description, + Currency, + OpeningBalance, + IBAN, + BIC, + // insert new entries above this line + LastAttribute + }; + + enum class Payee { + ID = 0, + Name, + Type, + Reference, + Notes, + MatchingEnabled, + UsingMatchKey, + MatchIgnoreCase, + MatchKey, + DefaultAccountID, + Street, + City, + PostCode, + Email, + State, + Telephone, + // insert new entries above this line + LastAttribute + }; + + enum class Tag { + ID = 0, + Name, + Type, + TagColor, + Closed, + Notes, + // insert new entries above this line + LastAttribute + }; + + enum class Security { + ID = 0, + Name, + Symbol, + Type, + RoundingMethod, + SAF, + PP, + SCF, + TradingCurrency, + TradingMarket, + // insert new entries above this line + LastAttribute + }; + + enum class KVP { + Key, + Value, + // insert new entries above this line + LastAttribute + }; + + enum class Institution { + ID = 0, + Name, + Manager, + SortCode, + Street, + City, + Zip, + Telephone, + // insert new entries above this line + LastAttribute + }; + + enum class Report { + ID = 0, Group, Type, Name, Comment, ConvertCurrency, Favorite, + SkipZero, DateLock, DataLock, MovingAverageDays, + IncludesActuals, IncludesForecast, IncludesPrice, + IncludesAveragePrice, IncludesMovingAverage, + IncludesSchedules, IncludesTransfers, IncludesUnused, + MixedTime, Investments, Budget, + ShowRowTotals, ShowColumnTotals, Detail, + ColumnsAreDays, ChartType, + ChartCHGridLines, ChartSVGridLines, + ChartDataLabels, ChartByDefault, + LogYAxis, ChartLineWidth, ColumnType, RowType, + DataRangeStart, DataRangeEnd, + DataMajorTick, DataMinorTick, + YLabelsPrecision, QueryColumns, + Tax, Loans, HideTransactions, InvestmentSum, + SettlementPeriod, ShowSTLTCapitalGains, TermsSeparator, + Pattern, CaseSensitive, RegEx, InvertText, State, + From, To, + // insert new entries above this line + LastAttribute + }; + + enum class Budget { + ID = 0, + Name, + Start, + Version, + BudgetLevel, + BudgetSubAccounts, + Amount, + // insert new entries above this line + LastAttribute + }; + + enum class Schedule { + ID = 0, + Name, + Type, + Occurrence, + OccurrenceMultiplier, + PaymentType, + Fixed, + AutoEnter, + LastPayment, + WeekendOption, + Date, + StartDate, + EndDate, + LastDayInMonth, + // insert new entries above this line + LastAttribute + }; + + enum class OnlineJob { + ID = 0, + Send, + BankAnswerDate, + BankAnswerState, + IID, + AbortedByUser, + AcceptedByBank, + RejectedByBank, + SendingError, + // insert new entries above this line + LastAttribute + }; + + enum class CostCenter { + ID = 0, + Name, + // insert new entries above this line + LastAttribute + }; +} + +QString elementName(Element::General elementID); +QString attributeName(Attribute::General attributeID); + +QString elementName(Element::Transaction elementID); +QString attributeName(Attribute::Transaction attributeID); + +QString elementName(Element::Account elementID); +QString attributeName(Attribute::Account attributeID); + +QString elementName(Element::Payee elementID); +QString attributeName(Attribute::Payee attributeID); + +QString attributeName(Attribute::Tag attributeID); + +QString attributeName(Attribute::Security attributeID); + +QString elementName(Element::KVP elementID); +QString attributeName(Attribute::KVP attributeID); + +QString elementName(Element::Institution elementID); +QString attributeName(Attribute::Institution attributeID); + +QString elementName(Element::Report elementID); +QString attributeName(Attribute::Report attributeID); + +QString elementName(Element::Budget elementID); +QString attributeName(Attribute::Budget attributeID); + +QString elementName(Element::Schedule elementID); +QString attributeName(Attribute::Schedule attributeID); + +QString elementName(Element::OnlineJob elementID); +QString attributeName(Attribute::OnlineJob attributeID); + +QString attributeName(Attribute::CostCenter attributeID); + +QString stdAccName(StdAccName stdAccID); +QString tagName(Tag tagID); +QString nodeName(Node nodeID); + +namespace eMyMoney { namespace Report { enum class RowType; } } +namespace eMyMoney { namespace Report { enum class ColumnType; } } +namespace eMyMoney { namespace Report { enum QueryColumn : int; } } +namespace eMyMoney { namespace Report { enum class ChartType; } } +namespace eMyMoney { namespace Report { enum class DataLock; } } +namespace eMyMoney { namespace Report { enum class ReportType; } } +namespace eMyMoney { namespace Report { enum class DetailLevel; } } + +QHash rowTypesLUT(); +QString reportNames(eMyMoney::Report::RowType textID); +eMyMoney::Report::RowType stringToRowType(const QString &text); +QHash columTypesLUT(); +QString reportNames(eMyMoney::Report::ColumnType textID); +eMyMoney::Report::ColumnType stringToColumnType(const QString &text); +QHash queryColumnsLUT(); +QString reportNamesForQC(eMyMoney::Report::QueryColumn textID); +eMyMoney::Report::QueryColumn stringToQueryColumn(const QString &text); +QHash detailLevelLUT(); +QString reportNames(eMyMoney::Report::DetailLevel textID); +eMyMoney::Report::DetailLevel stringToDetailLevel(const QString &text); +QHash chartTypeLUT(); +QString reportNames(eMyMoney::Report::ChartType textID); +eMyMoney::Report::ChartType stringToChartType(const QString &text); +QHash typeAttributeLUT(); +QString typeAttributeToString(int textID); +int stringToTypeAttribute(const QString &text); +QHash stateAttributeLUT(); +QString stateAttributeToString(int textID); +int stringToStateAttribute(const QString &text); +QHash dateLockLUT(); +QString dateLockAttributeToString(int textID); +int stringToDateLockAttribute(const QString &text); +QHash dataLockLUT(); +QString reportNames(eMyMoney::Report::DataLock textID); +eMyMoney::Report::DataLock stringToDataLockAttribute(const QString &text); +QHash accountTypeAttributeLUT(); +QString accountTypeAttributeToString(int textID); +int stringToAccountTypeAttribute(const QString &text); +eMyMoney::Report::ReportType rowTypeToReportType(eMyMoney::Report::RowType rowType); + +namespace eMyMoney { namespace Budget { enum class Level; } } + +QHash budgetLevelLUT(); +QString budgetNames(eMyMoney::Budget::Level textID); +eMyMoney::Budget::Level stringToBudgetLevel(const QString &text); + #endif diff --git a/kmymoney/plugins/xml/mymoneystoragenames.cpp b/kmymoney/plugins/xml/mymoneystoragenames.cpp --- a/kmymoney/plugins/xml/mymoneystoragenames.cpp +++ b/kmymoney/plugins/xml/mymoneystoragenames.cpp @@ -17,84 +17,796 @@ #include "mymoneystoragenames.h" -namespace MyMoneyStorageTags { - -const QHash tagNames = { - {tnInstitutions, QStringLiteral("INSTITUTIONS")}, - {tnPayees, QStringLiteral("PAYEES")}, - {tnCostCenters, QStringLiteral("COSTCENTERS")}, - {tnTags, QStringLiteral("TAGS")}, - {tnAccounts, QStringLiteral("ACCOUNTS")}, - {tnTransactions, QStringLiteral("TRANSACTIONS")}, - {tnSchedules, QStringLiteral("SCHEDULES")}, - {tnSecurities, QStringLiteral("SECURITIES")}, - {tnCurrencies, QStringLiteral("CURRENCIES")}, - {tnPrices, QStringLiteral("PRICES")}, - {tnReports, QStringLiteral("REPORTS")}, - {tnBudgets, QStringLiteral("BUDGETS")}, - {tnOnlineJobs, QStringLiteral("ONLINEJOBS")}, - {tnKMMFile, QStringLiteral("KMYMONEY-FILE")}, - {tnFileInfo, QStringLiteral("FILEINFO")}, - {tnUser, QStringLiteral("USER")} -}; - -} - -namespace MyMoneyStorageNodes { - -const QHash nodeNames = { - {nnInstitution, QStringLiteral("INSTITUTION")}, - {nnPayee, QStringLiteral("PAYEE")}, - {nnCostCenter, QStringLiteral("COSTCENTER")}, - {nnTag, QStringLiteral("TAG")}, - {nnAccount, QStringLiteral("ACCOUNT")}, - {nnTransaction, QStringLiteral("TRANSACTION")}, - {nnScheduleTX, QStringLiteral("SCHEDULED_TX")}, - {nnSecurity, QStringLiteral("SECURITY")}, - {nnCurrency, QStringLiteral("CURRENCY")}, - {nnPrice, QStringLiteral("PRICE")}, - {nnPricePair, QStringLiteral("PRICEPAIR")}, - {nnReport, QStringLiteral("REPORT")}, - {nnBudget, QStringLiteral("BUDGET")}, - {nnOnlineJob, QStringLiteral("ONLINEJOB")}, - {nnKeyValuePairs, QStringLiteral("KEYVALUEPAIRS")}, - {nnEquity, QStringLiteral("EQUITY")}, -}; - -} - -namespace MyMoneyStorageAttributes { - -const QHash attrNames = { - {anID, QStringLiteral("id")}, - {anDate, QStringLiteral("date")}, - {anCount, QStringLiteral("count")}, - {anFrom, QStringLiteral("from")}, - {anTo, QStringLiteral("to")}, - {anSource, QStringLiteral("source")}, - {anKey, QStringLiteral("key")}, - {anValue, QStringLiteral("value")}, - {anPrice, QStringLiteral("price")}, - {anName, QStringLiteral("name")}, - {anEmail, QStringLiteral("email")}, - {anCountry, QStringLiteral("county")}, - {anCity, QStringLiteral("city")}, - {anZipCode, QStringLiteral("zipcode")}, - {anStreet, QStringLiteral("street")}, - {anTelephone, QStringLiteral("telephone")} -}; - -} - -namespace MyMoneyStandardAccounts { - - // definitions for the ID's of the standard accounts - const QHash stdAccNames { - {stdAccLiability, QStringLiteral("AStd::Liability")}, - {stdAccAsset, QStringLiteral("AStd::Asset")}, - {stdAccExpense, QStringLiteral("AStd::Expense")}, - {stdAccIncome, QStringLiteral("AStd::Income")}, - {stdAccEquity, QStringLiteral("AStd::Equity")}, +#include + +#include "mymoneyenums.h" + +QString stdAccName(StdAccName stdAccID) +{ + static const QHash stdAccNames { + {StdAccName::Liability, QStringLiteral("AStd::Liability")}, + {StdAccName::Asset, QStringLiteral("AStd::Asset")}, + {StdAccName::Expense, QStringLiteral("AStd::Expense")}, + {StdAccName::Income, QStringLiteral("AStd::Income")}, + {StdAccName::Equity, QStringLiteral("AStd::Equity")}, + }; + return stdAccNames.value(stdAccID); +} + +uint qHash(const StdAccName key, uint seed) { return ::qHash(static_cast(key), seed); } + +QString tagName(Tag tagID) +{ + static const QHash tagNames { + {Tag::Institutions, QStringLiteral("INSTITUTIONS")}, + {Tag::Payees, QStringLiteral("PAYEES")}, + {Tag::CostCenters, QStringLiteral("COSTCENTERS")}, + {Tag::Tags, QStringLiteral("TAGS")}, + {Tag::Accounts, QStringLiteral("ACCOUNTS")}, + {Tag::Transactions, QStringLiteral("TRANSACTIONS")}, + {Tag::Schedules, QStringLiteral("SCHEDULES")}, + {Tag::Securities, QStringLiteral("SECURITIES")}, + {Tag::Currencies, QStringLiteral("CURRENCIES")}, + {Tag::Prices, QStringLiteral("PRICES")}, + {Tag::Reports, QStringLiteral("REPORTS")}, + {Tag::Budgets, QStringLiteral("BUDGETS")}, + {Tag::OnlineJobs, QStringLiteral("ONLINEJOBS")}, + {Tag::KMMFile, QStringLiteral("KMYMONEY-FILE")}, + {Tag::FileInfo, QStringLiteral("FILEINFO")}, + {Tag::User, QStringLiteral("USER")} + }; + return tagNames.value(tagID); +} + +uint qHash(const Tag key, uint seed) { return ::qHash(static_cast(key), seed); } + +QString nodeName(Node nodeID) +{ + static const QHash nodeNames { + {Node::Institution, QStringLiteral("INSTITUTION")}, + {Node::Payee, QStringLiteral("PAYEE")}, + {Node::CostCenter, QStringLiteral("COSTCENTER")}, + {Node::Tag, QStringLiteral("TAG")}, + {Node::Account, QStringLiteral("ACCOUNT")}, + {Node::Transaction, QStringLiteral("TRANSACTION")}, + {Node::ScheduleTX, QStringLiteral("SCHEDULED_TX")}, + {Node::Security, QStringLiteral("SECURITY")}, + {Node::Currency, QStringLiteral("CURRENCY")}, + {Node::Price, QStringLiteral("PRICE")}, + {Node::PricePair, QStringLiteral("PRICEPAIR")}, + {Node::Report, QStringLiteral("REPORT")}, + {Node::Budget, QStringLiteral("BUDGET")}, + {Node::OnlineJob, QStringLiteral("ONLINEJOB")}, + {Node::KeyValuePairs, QStringLiteral("KEYVALUEPAIRS")}, + {Node::Equity, QStringLiteral("EQUITY")}, + }; + return nodeNames.value(nodeID); +} + +uint qHash(const Node key, uint seed) { return ::qHash(static_cast(key), seed); } + +namespace Element { + uint qHash(const General key, uint seed) { return ::qHash(static_cast(key), seed); } + uint qHash(const Transaction key, uint seed) { return ::qHash(static_cast(key), seed); } + uint qHash(const Account key, uint seed) { return ::qHash(static_cast(key), seed); } + uint qHash(const Payee key, uint seed) { return ::qHash(static_cast(key), seed); } + uint qHash(const KVP key, uint seed) { return ::qHash(static_cast(key), seed); } + uint qHash(const Institution key, uint seed) { return ::qHash(static_cast(key), seed); } + uint qHash(const Report key, uint seed) { return ::qHash(static_cast(key), seed); } + uint qHash(const Budget key, uint seed) { return ::qHash(static_cast(key), seed); } + uint qHash(const Schedule key, uint seed) { return ::qHash(static_cast(key), seed); } + uint qHash(const OnlineJob key, uint seed) { return ::qHash(static_cast(key), seed); } +} + +namespace Attribute { + uint qHash(const General key, uint seed) { return ::qHash(static_cast(key), seed); } + uint qHash(const Transaction key, uint seed) { return ::qHash(static_cast(key), seed); } + uint qHash(const Account key, uint seed) { return ::qHash(static_cast(key), seed); } + uint qHash(const Payee key, uint seed) { return ::qHash(static_cast(key), seed); } + uint qHash(const Tag key, uint seed) { return ::qHash(static_cast(key), seed); } + uint qHash(const Security key, uint seed) { return ::qHash(static_cast(key), seed); } + uint qHash(const KVP key, uint seed) { return ::qHash(static_cast(key), seed); } + uint qHash(const Institution key, uint seed) { return ::qHash(static_cast(key), seed); } + uint qHash(const Report key, uint seed) { return ::qHash(static_cast(key), seed); } + uint qHash(const Budget key, uint seed) { return ::qHash(static_cast(key), seed); } + uint qHash(const Schedule key, uint seed) { return ::qHash(static_cast(key), seed); } + uint qHash(const OnlineJob key, uint seed) { return ::qHash(static_cast(key), seed); } +} + +QString elementName(Element::General elementID) +{ + static const QMap elementNames { + {Element::General::Address, QStringLiteral("ADDRESS")}, + {Element::General::CreationDate, QStringLiteral("CREATION_DATE")}, + {Element::General::LastModifiedDate, QStringLiteral("LAST_MODIFIED_DATE")}, + {Element::General::Version, QStringLiteral("VERSION")}, + {Element::General::FixVersion, QStringLiteral("FIXVERSION")}, + {Element::General::Pair, QStringLiteral("PAIR")} + }; + return elementNames.value(elementID); +} + +QString attributeName(Attribute::General attributeID) +{ + static const QMap attributeNames { + {Attribute::General::ID, QStringLiteral("id")}, + {Attribute::General::Date, QStringLiteral("date")}, + {Attribute::General::Count, QStringLiteral("count")}, + {Attribute::General::From, QStringLiteral("from")}, + {Attribute::General::To, QStringLiteral("to")}, + {Attribute::General::Source, QStringLiteral("source")}, + {Attribute::General::Key, QStringLiteral("key")}, + {Attribute::General::Value, QStringLiteral("value")}, + {Attribute::General::Price, QStringLiteral("price")}, + {Attribute::General::Name, QStringLiteral("name")}, + {Attribute::General::Email, QStringLiteral("email")}, + {Attribute::General::Country, QStringLiteral("county")}, + {Attribute::General::City, QStringLiteral("city")}, + {Attribute::General::ZipCode, QStringLiteral("zipcode")}, + {Attribute::General::Street, QStringLiteral("street")}, + {Attribute::General::Telephone, QStringLiteral("telephone")} + }; + return attributeNames.value(attributeID); +} + +QString elementName(Element::Transaction elementID) +{ + static const QMap elementNames { + {Element::Transaction::Split, QStringLiteral("SPLIT")}, + {Element::Transaction::Splits, QStringLiteral("SPLITS")} + }; + return elementNames.value(elementID); +} + +QString attributeName(Attribute::Transaction attributeID) +{ + static const QMap attributeNames { + {Attribute::Transaction::Name, QStringLiteral("name")}, + {Attribute::Transaction::Type, QStringLiteral("type")}, + {Attribute::Transaction::PostDate, QStringLiteral("postdate")}, + {Attribute::Transaction::Memo, QStringLiteral("memo")}, + {Attribute::Transaction::EntryDate, QStringLiteral("entrydate")}, + {Attribute::Transaction::Commodity, QStringLiteral("commodity")}, + {Attribute::Transaction::BankID, QStringLiteral("bankid")}, + }; + return attributeNames.value(attributeID); +} + +QString elementName(Element::Account elementID) +{ + static const QMap elementNames { + {Element::Account::SubAccount, QStringLiteral("SUBACCOUNT")}, + {Element::Account::SubAccounts, QStringLiteral("SUBACCOUNTS")}, + {Element::Account::OnlineBanking, QStringLiteral("ONLINEBANKING")} + }; + return elementNames.value(elementID); +} + +QString attributeName(Attribute::Account attributeID) +{ + static const QHash attributeNames { + {Attribute::Account::ID, QStringLiteral("id")}, + {Attribute::Account::Name, QStringLiteral("name")}, + {Attribute::Account::Type, QStringLiteral("type")}, + {Attribute::Account::ParentAccount, QStringLiteral("parentaccount")}, + {Attribute::Account::LastReconciled, QStringLiteral("lastreconciled")}, + {Attribute::Account::LastModified, QStringLiteral("lastmodified")}, + {Attribute::Account::Institution, QStringLiteral("institution")}, + {Attribute::Account::Opened, QStringLiteral("opened")}, + {Attribute::Account::Number, QStringLiteral("number")}, + {Attribute::Account::Type, QStringLiteral("type")}, + {Attribute::Account::Description, QStringLiteral("description")}, + {Attribute::Account::Currency, QStringLiteral("currency")}, + {Attribute::Account::OpeningBalance, QStringLiteral("openingbalance")}, + {Attribute::Account::IBAN, QStringLiteral("iban")}, + {Attribute::Account::BIC, QStringLiteral("bic")}, + }; + return attributeNames.value(attributeID); +} + +QString elementName(Element::Payee elementID) +{ + static const QMap elementNames { + {Element::Payee::Address, QStringLiteral("ADDRESS")} + }; + return elementNames.value(elementID); +} + +QString attributeName(Attribute::Payee attributeID) +{ + static const QMap attributeNames { + {Attribute::Payee::Name, QStringLiteral("name")}, + {Attribute::Payee::Type, QStringLiteral("type")}, + {Attribute::Payee::Reference, QStringLiteral("reference")}, + {Attribute::Payee::Notes, QStringLiteral("notes")}, + {Attribute::Payee::MatchingEnabled, QStringLiteral("matchingenabled")}, + {Attribute::Payee::UsingMatchKey, QStringLiteral("usingmatchkey")}, + {Attribute::Payee::MatchIgnoreCase, QStringLiteral("matchignorecase")}, + {Attribute::Payee::MatchKey, QStringLiteral("matchkey")}, + {Attribute::Payee::DefaultAccountID, QStringLiteral("defaultaccountid")}, + {Attribute::Payee::Street, QStringLiteral("street")}, + {Attribute::Payee::City, QStringLiteral("city")}, + {Attribute::Payee::PostCode, QStringLiteral("postcode")}, + {Attribute::Payee::Email, QStringLiteral("email")}, + {Attribute::Payee::State, QStringLiteral("state")}, + {Attribute::Payee::Telephone, QStringLiteral("telephone")} + }; + return attributeNames.value(attributeID); +} + +QString attributeName(Attribute::Tag attributeID) +{ + static const QMap attributeNames { + {Attribute::Tag::Name, QStringLiteral("name")}, + {Attribute::Tag::Type, QStringLiteral("type")}, + {Attribute::Tag::TagColor, QStringLiteral("tagcolor")}, + {Attribute::Tag::Closed, QStringLiteral("closed")}, + {Attribute::Tag::Notes, QStringLiteral("notes")}, + }; + return attributeNames.value(attributeID); +} + +QString attributeName(Attribute::Security attributeID) +{ + static const QMap attributeNames { + {Attribute::Security::Name, QStringLiteral("name")}, + {Attribute::Security::Symbol, QStringLiteral("symbol")}, + {Attribute::Security::Type, QStringLiteral("type")}, + {Attribute::Security::RoundingMethod, QStringLiteral("rounding-method")}, + {Attribute::Security::SAF, QStringLiteral("saf")}, + {Attribute::Security::PP, QStringLiteral("pp")}, + {Attribute::Security::SCF, QStringLiteral("scf")}, + {Attribute::Security::TradingCurrency, QStringLiteral("trading-currency")}, + {Attribute::Security::TradingMarket, QStringLiteral("trading-market")} }; + return attributeNames.value(attributeID); +} + +QString elementName(Element::KVP elementID) +{ + static const QMap elementNames { + {Element::KVP::Pair, QStringLiteral("PAIR")} + }; + return elementNames.value(elementID); +} + +QString attributeName(Attribute::KVP attributeID) +{ + static const QMap attributeNames { + {Attribute::KVP::Key, QStringLiteral("key")}, + {Attribute::KVP::Value, QStringLiteral("value")} + }; + return attributeNames.value(attributeID); +} + +QString elementName(Element::Institution elementID) +{ + static const QMap elementNames { + {Element::Institution::AccountID, QStringLiteral("ACCOUNTID")}, + {Element::Institution::AccountIDS, QStringLiteral("ACCOUNTIDS")}, + {Element::Institution::Address, QStringLiteral("ADDRESS")} + }; + return elementNames.value(elementID); +} + +QString attributeName(Attribute::Institution attributeID) +{ + static const QMap attributeNames { + {Attribute::Institution::ID, QStringLiteral("id")}, + {Attribute::Institution::Name, QStringLiteral("name")}, + {Attribute::Institution::Manager, QStringLiteral("manager")}, + {Attribute::Institution::SortCode, QStringLiteral("sortcode")}, + {Attribute::Institution::Street, QStringLiteral("street")}, + {Attribute::Institution::City, QStringLiteral("city")}, + {Attribute::Institution::Zip, QStringLiteral("zip")}, + {Attribute::Institution::Telephone, QStringLiteral("telephone")} + }; + return attributeNames.value(attributeID); +} + +QString elementName(Element::Report elementID) +{ + static const QMap elementNames { + {Element::Report::Payee, QStringLiteral("PAYEE")}, + {Element::Report::Tag, QStringLiteral("TAG")}, + {Element::Report::Account, QStringLiteral("ACCOUNT")}, + {Element::Report::Text, QStringLiteral("TEXT")}, + {Element::Report::Type, QStringLiteral("TYPE")}, + {Element::Report::State, QStringLiteral("STATE")}, + {Element::Report::Number, QStringLiteral("NUMBER")}, + {Element::Report::Amount, QStringLiteral("AMOUNT")}, + {Element::Report::Dates, QStringLiteral("DATES")}, + {Element::Report::Category, QStringLiteral("CATEGORY")}, + {Element::Report::AccountGroup, QStringLiteral("ACCOUNTGROUP")} + }; + return elementNames.value(elementID); +} + +QString attributeName(Attribute::Report attributeID) +{ + static const QMap attributeNames { + {Attribute::Report::ID, QStringLiteral("id")}, + {Attribute::Report::Group, QStringLiteral("group")}, + {Attribute::Report::Type, QStringLiteral("type")}, + {Attribute::Report::Name, QStringLiteral("name")}, + {Attribute::Report::Comment, QStringLiteral("comment")}, + {Attribute::Report::ConvertCurrency, QStringLiteral("convertcurrency")}, + {Attribute::Report::Favorite, QStringLiteral("favorite")}, + {Attribute::Report::SkipZero, QStringLiteral("skipZero")}, + {Attribute::Report::DateLock, QStringLiteral("datelock")}, + {Attribute::Report::DataLock, QStringLiteral("datalock")}, + {Attribute::Report::MovingAverageDays, QStringLiteral("movingaveragedays")}, + {Attribute::Report::IncludesActuals, QStringLiteral("includesactuals")}, + {Attribute::Report::IncludesForecast, QStringLiteral("includesforecast")}, + {Attribute::Report::IncludesPrice, QStringLiteral("includesprice")}, + {Attribute::Report::IncludesAveragePrice, QStringLiteral("includesaverageprice")}, + {Attribute::Report::IncludesMovingAverage, QStringLiteral("includesmovingaverage")}, + {Attribute::Report::IncludesSchedules, QStringLiteral("includeschedules")}, + {Attribute::Report::IncludesTransfers, QStringLiteral("includestransfers")}, + {Attribute::Report::IncludesUnused, QStringLiteral("includeunused")}, + {Attribute::Report::MixedTime, QStringLiteral("mixedtime")}, + {Attribute::Report::Investments, QStringLiteral("investments")}, + {Attribute::Report::Budget, QStringLiteral("budget")}, + {Attribute::Report::ShowRowTotals, QStringLiteral("showrowtotals")}, + {Attribute::Report::ShowColumnTotals, QStringLiteral("showcolumntotals")}, + {Attribute::Report::Detail, QStringLiteral("detail")}, + {Attribute::Report::ColumnsAreDays, QStringLiteral("columnsaredays")}, + {Attribute::Report::ChartType, QStringLiteral("charttype")}, + {Attribute::Report::ChartCHGridLines, QStringLiteral("chartchgridlines")}, + {Attribute::Report::ChartSVGridLines, QStringLiteral("chartsvgridlines")}, + {Attribute::Report::ChartDataLabels, QStringLiteral("chartdatalabels")}, + {Attribute::Report::ChartByDefault, QStringLiteral("chartbydefault")}, + {Attribute::Report::LogYAxis, QStringLiteral("logYaxis")}, + {Attribute::Report::ChartLineWidth, QStringLiteral("chartlinewidth")}, + {Attribute::Report::ColumnType, QStringLiteral("columntype")}, + {Attribute::Report::RowType, QStringLiteral("rowtype")}, + {Attribute::Report::DataRangeStart, QStringLiteral("dataRangeStart")}, + {Attribute::Report::DataRangeEnd, QStringLiteral("dataRangeEnd")}, + {Attribute::Report::DataMajorTick, QStringLiteral("dataMajorTick")}, + {Attribute::Report::DataMinorTick, QStringLiteral("dataMinorTick")}, + {Attribute::Report::YLabelsPrecision, QStringLiteral("yLabelsPrecision")}, + {Attribute::Report::QueryColumns, QStringLiteral("querycolumns")}, + {Attribute::Report::Tax, QStringLiteral("tax")}, + {Attribute::Report::Loans, QStringLiteral("loans")}, + {Attribute::Report::HideTransactions, QStringLiteral("hidetransactions")}, + {Attribute::Report::InvestmentSum, QStringLiteral("investmentsum")}, + {Attribute::Report::SettlementPeriod, QStringLiteral("settlementperiod")}, + {Attribute::Report::ShowSTLTCapitalGains, QStringLiteral("showSTLTCapitalGains")}, + {Attribute::Report::TermsSeparator, QStringLiteral("tseparator")}, + {Attribute::Report::Pattern, QStringLiteral("pattern")}, + {Attribute::Report::CaseSensitive, QStringLiteral("casesensitive")}, + {Attribute::Report::RegEx, QStringLiteral("regex")}, + {Attribute::Report::InvertText, QStringLiteral("inverttext")}, + {Attribute::Report::State, QStringLiteral("state")}, + {Attribute::Report::From, QStringLiteral("from")}, + {Attribute::Report::To, QStringLiteral("to")} + }; + return attributeNames.value(attributeID); +} + +QString elementName(Element::Budget elementID) +{ + static const QMap elementNames { + {Element::Budget::Budget, QStringLiteral("BUDGET")}, + {Element::Budget::Account, QStringLiteral("ACCOUNT")}, + {Element::Budget::Period, QStringLiteral("PERIOD")} + }; + return elementNames.value(elementID); +} + +QString attributeName(Attribute::Budget attributeID) +{ + static const QMap attributeNames { + {Attribute::Budget::ID, QStringLiteral("id")}, + {Attribute::Budget::Name, QStringLiteral("name")}, + {Attribute::Budget::Start, QStringLiteral("start")}, + {Attribute::Budget::Version, QStringLiteral("version")}, + {Attribute::Budget::BudgetLevel, QStringLiteral("budgetlevel")}, + {Attribute::Budget::BudgetSubAccounts, QStringLiteral("budgetsubaccounts")}, + {Attribute::Budget::Amount, QStringLiteral("amount")} + }; + return attributeNames.value(attributeID); +} + +QString elementName(Element::Schedule elementID) +{ + static const QMap elementNames { + {Element::Schedule::Payment, QStringLiteral("PAYMENT")}, + {Element::Schedule::Payments, QStringLiteral("PAYMENTS")} + }; + return elementNames.value(elementID); +} + +QString attributeName(Attribute::Schedule attributeID) +{ + static const QMap attributeNames { + {Attribute::Schedule::Name, QStringLiteral("name")}, + {Attribute::Schedule::Type, QStringLiteral("type")}, + {Attribute::Schedule::Occurrence, QStringLiteral("occurence")}, // krazy:exclude=spelling + {Attribute::Schedule::OccurrenceMultiplier, QStringLiteral("occurenceMultiplier")}, // krazy:exclude=spelling + {Attribute::Schedule::PaymentType, QStringLiteral("paymentType")}, + {Attribute::Schedule::Fixed, QStringLiteral("fixed")}, + {Attribute::Schedule::AutoEnter, QStringLiteral("autoEnter")}, + {Attribute::Schedule::LastPayment, QStringLiteral("lastPayment")}, + {Attribute::Schedule::WeekendOption, QStringLiteral("weekendOption")}, + {Attribute::Schedule::Date, QStringLiteral("date")}, + {Attribute::Schedule::StartDate, QStringLiteral("startDate")}, + {Attribute::Schedule::EndDate, QStringLiteral("endDate")}, + {Attribute::Schedule::LastDayInMonth, QStringLiteral("lastDayInMonth")} + }; + return attributeNames.value(attributeID); +} + +QString elementName(Element::OnlineJob elementID) +{ + static const QMap elementNames { + {Element::OnlineJob::OnlineTask, QStringLiteral("onlineTask")} + }; + return elementNames.value(elementID); +} + +QString attributeName(Attribute::OnlineJob attributeID) +{ + static const QMap attributeNames { + {Attribute::OnlineJob::Send, QStringLiteral("send")}, + {Attribute::OnlineJob::BankAnswerDate, QStringLiteral("bankAnswerDate")}, + {Attribute::OnlineJob::BankAnswerState, QStringLiteral("bankAnswerState")}, + {Attribute::OnlineJob::IID, QStringLiteral("iid")}, + {Attribute::OnlineJob::AbortedByUser, QStringLiteral("abortedByUser")}, + {Attribute::OnlineJob::AcceptedByBank, QStringLiteral("acceptedByBank")}, + {Attribute::OnlineJob::RejectedByBank, QStringLiteral("rejectedByBank")}, + {Attribute::OnlineJob::SendingError, QStringLiteral("sendingError")}, + }; + return attributeNames.value(attributeID); +} + +QString attributeName(Attribute::CostCenter attributeID) +{ + static const QMap attributeNames { + {Attribute::CostCenter::Name, QStringLiteral("name")}, + }; + return attributeNames.value(attributeID); +} + +QHash rowTypesLUT() +{ + static const QHash lut { + {eMyMoney::Report::RowType::NoRows, QStringLiteral("none")}, + {eMyMoney::Report::RowType::AssetLiability, QStringLiteral("assetliability")}, + {eMyMoney::Report::RowType::ExpenseIncome, QStringLiteral("expenseincome")}, + {eMyMoney::Report::RowType::Category, QStringLiteral("category")}, + {eMyMoney::Report::RowType::TopCategory, QStringLiteral("topcategory")}, + {eMyMoney::Report::RowType::Account, QStringLiteral("account")}, + {eMyMoney::Report::RowType::Tag, QStringLiteral("tag")}, + {eMyMoney::Report::RowType::Payee, QStringLiteral("payee")}, + {eMyMoney::Report::RowType::Month, QStringLiteral("month")}, + {eMyMoney::Report::RowType::Week, QStringLiteral("week")}, + {eMyMoney::Report::RowType::TopAccount, QStringLiteral("topaccount")}, + {eMyMoney::Report::RowType::AccountByTopAccount, QStringLiteral("topaccount-account")}, + {eMyMoney::Report::RowType::EquityType, QStringLiteral("equitytype")}, + {eMyMoney::Report::RowType::AccountType, QStringLiteral("accounttype")}, + {eMyMoney::Report::RowType::Institution, QStringLiteral("institution")}, + {eMyMoney::Report::RowType::Budget, QStringLiteral("budget")}, + {eMyMoney::Report::RowType::BudgetActual, QStringLiteral("budgetactual")}, + {eMyMoney::Report::RowType::Schedule, QStringLiteral("schedule")}, + {eMyMoney::Report::RowType::AccountInfo, QStringLiteral("accountinfo")}, + {eMyMoney::Report::RowType::AccountLoanInfo, QStringLiteral("accountloaninfo")}, + {eMyMoney::Report::RowType::AccountReconcile, QStringLiteral("accountreconcile")}, + {eMyMoney::Report::RowType::CashFlow, QStringLiteral("cashflow")}, + }; + return lut; +} + +QString reportNames(eMyMoney::Report::RowType textID) +{ + return rowTypesLUT().value(textID); +} + +eMyMoney::Report::RowType stringToRowType(const QString &text) +{ + return rowTypesLUT().key(text, eMyMoney::Report::RowType::Invalid); +} + +QHash columTypesLUT() +{ + static const QHash lut { + {eMyMoney::Report::ColumnType::NoColumns, QStringLiteral("none")}, + {eMyMoney::Report::ColumnType::Months, QStringLiteral("months")}, + {eMyMoney::Report::ColumnType::BiMonths, QStringLiteral("bimonths")}, + {eMyMoney::Report::ColumnType::Quarters, QStringLiteral("quarters")}, +// {eMyMoney::Report::ColumnType::, QStringLiteral("4")} +// {eMyMoney::Report::ColumnType::, QStringLiteral("5")} +// {eMyMoney::Report::ColumnType::, QStringLiteral("6")} + {eMyMoney::Report::ColumnType::Weeks, QStringLiteral("weeks")}, +// {eMyMoney::Report::ColumnType::, QStringLiteral("8")} +// {eMyMoney::Report::ColumnType::, QStringLiteral("9")} +// {eMyMoney::Report::ColumnType::, QStringLiteral("10")} +// {eMyMoney::Report::ColumnType::, QStringLiteral("11")} + {eMyMoney::Report::ColumnType::Years, QStringLiteral("years")} + }; + return lut; +} + +QString reportNames(eMyMoney::Report::ColumnType textID) +{ + return columTypesLUT().value(textID); +} + +eMyMoney::Report::ColumnType stringToColumnType(const QString &text) +{ + return columTypesLUT().key(text, eMyMoney::Report::ColumnType::Invalid); +} + +QHash queryColumnsLUT() +{ + static const QHash lut { + {eMyMoney::Report::QueryColumn::None, QStringLiteral("none")}, + {eMyMoney::Report::QueryColumn::Number, QStringLiteral("number")}, + {eMyMoney::Report::QueryColumn::Payee, QStringLiteral("payee")}, + {eMyMoney::Report::QueryColumn::Category, QStringLiteral("category")}, + {eMyMoney::Report::QueryColumn::Tag, QStringLiteral("tag")}, + {eMyMoney::Report::QueryColumn::Memo, QStringLiteral("memo")}, + {eMyMoney::Report::QueryColumn::Account, QStringLiteral("account")}, + {eMyMoney::Report::QueryColumn::Reconciled, QStringLiteral("reconcileflag")}, + {eMyMoney::Report::QueryColumn::Action, QStringLiteral("action")}, + {eMyMoney::Report::QueryColumn::Shares, QStringLiteral("shares")}, + {eMyMoney::Report::QueryColumn::Price, QStringLiteral("price")}, + {eMyMoney::Report::QueryColumn::Performance, QStringLiteral("performance")}, + {eMyMoney::Report::QueryColumn::Loan, QStringLiteral("loan")}, + {eMyMoney::Report::QueryColumn::Balance, QStringLiteral("balance")}, + {eMyMoney::Report::QueryColumn::CapitalGain, QStringLiteral("capitalgain")} + }; + return lut; +} + +QString reportNamesForQC(eMyMoney::Report::QueryColumn textID) +{ + return queryColumnsLUT().value(textID); +} + +eMyMoney::Report::QueryColumn stringToQueryColumn(const QString &text) +{ + return queryColumnsLUT().key(text, eMyMoney::Report::QueryColumn::End); +} + +QHash detailLevelLUT() +{ + static const QHash lut { + {eMyMoney::Report::DetailLevel::None, QStringLiteral("none")}, + {eMyMoney::Report::DetailLevel::All, QStringLiteral("all")}, + {eMyMoney::Report::DetailLevel::Top, QStringLiteral("top")}, + {eMyMoney::Report::DetailLevel::Group, QStringLiteral("group")}, + {eMyMoney::Report::DetailLevel::Total, QStringLiteral("total")}, + {eMyMoney::Report::DetailLevel::End, QStringLiteral("invalid")} + }; + return lut; +} + +QString reportNames(eMyMoney::Report::DetailLevel textID) +{ + return detailLevelLUT().value(textID); +} + +eMyMoney::Report::DetailLevel stringToDetailLevel(const QString &text) +{ + return detailLevelLUT().key(text, eMyMoney::Report::DetailLevel::End); +} + +QHash chartTypeLUT() +{ + static const QHash lut { + {eMyMoney::Report::ChartType::None, QStringLiteral("none")}, + {eMyMoney::Report::ChartType::Line, QStringLiteral("line")}, + {eMyMoney::Report::ChartType::Bar, QStringLiteral("bar")}, + {eMyMoney::Report::ChartType::Pie, QStringLiteral("pie")}, + {eMyMoney::Report::ChartType::Ring, QStringLiteral("ring")}, + {eMyMoney::Report::ChartType::StackedBar, QStringLiteral("stackedbar")} + }; + return lut; +} + +QString reportNames(eMyMoney::Report::ChartType textID) +{ + return chartTypeLUT().value(textID); +} + +eMyMoney::Report::ChartType stringToChartType(const QString &text) +{ + return chartTypeLUT().key(text, eMyMoney::Report::ChartType::End); +} + +QHash typeAttributeLUT() +{ + static const QHash lut { + {0, QStringLiteral("all")}, + {1, QStringLiteral("payments")}, + {2, QStringLiteral("deposits")}, + {3, QStringLiteral("transfers")}, + {4, QStringLiteral("none")}, + }; + return lut; +} + +QString typeAttributeToString(int textID) +{ + return typeAttributeLUT().value(textID); +} + +int stringToTypeAttribute(const QString &text) +{ + return typeAttributeLUT().key(text, 4); +} + +QHash stateAttributeLUT() +{ + static const QHash lut { + {0, QStringLiteral("all")}, + {1, QStringLiteral("notreconciled")}, + {2, QStringLiteral("cleared")}, + {3, QStringLiteral("reconciled")}, + {4, QStringLiteral("frozen")}, + {5, QStringLiteral("none")} + }; + return lut; +} + +QString stateAttributeToString(int textID) +{ + return stateAttributeLUT().value(textID); +} + +int stringToStateAttribute(const QString &text) +{ + return stateAttributeLUT().key(text, 5); +} + +QHash dateLockLUT() +{ + static const QHash lut { + {0, QStringLiteral("alldates")}, + {1, QStringLiteral("untiltoday")}, + {2, QStringLiteral("currentmonth")}, + {3, QStringLiteral("currentyear")}, + {4, QStringLiteral("monthtodate")}, + {5, QStringLiteral("yeartodate")}, + {6, QStringLiteral("yeartomonth")}, + {7, QStringLiteral("lastmonth")}, + {8, QStringLiteral("lastyear")}, + {9, QStringLiteral("last7days")}, + {10, QStringLiteral("last30days")}, + {11, QStringLiteral("last3months")}, + {12, QStringLiteral("last6months")}, + {13, QStringLiteral("last12months")}, + {14, QStringLiteral("next7days")}, + {15, QStringLiteral("next30days")}, + {16, QStringLiteral("next3months")}, + {17, QStringLiteral("next6months")}, + {18, QStringLiteral("next12months")}, + {19, QStringLiteral("userdefined")}, + {20, QStringLiteral("last3tonext3months")}, + {21, QStringLiteral("last11Months")}, + {22, QStringLiteral("currentQuarter")}, + {23, QStringLiteral("lastQuarter")}, + {24, QStringLiteral("nextQuarter")}, + {25, QStringLiteral("currentFiscalYear")}, + {26, QStringLiteral("lastFiscalYear")}, + {27, QStringLiteral("today")}, + {28, QStringLiteral("next18months")} + }; + return lut; +} + +QString dateLockAttributeToString(int textID) +{ + return dateLockLUT().value(textID); +} + +int stringToDateLockAttribute(const QString &text) +{ + return dateLockLUT().key(text, 0); +} + +QHash dataLockLUT() +{ + static const QHash lut { + {eMyMoney::Report::DataLock::Automatic, QStringLiteral("automatic")}, + {eMyMoney::Report::DataLock::UserDefined, QStringLiteral("userdefined")} + }; + return lut; +} + +QString reportNames(eMyMoney::Report::DataLock textID) +{ + return dataLockLUT().value(textID); +} + +eMyMoney::Report::DataLock stringToDataLockAttribute(const QString &text) +{ + return dataLockLUT().key(text, eMyMoney::Report::DataLock::DataOptionCount); +} + +QHash accountTypeAttributeLUT() +{ + static const QHash lut { + {0, QStringLiteral("unknown")}, + {1, QStringLiteral("checkings")}, + {2, QStringLiteral("savings")}, + {3, QStringLiteral("cash")}, + {4, QStringLiteral("creditcard")}, + {5, QStringLiteral("loan")}, + {6, QStringLiteral("certificatedep")}, + {7, QStringLiteral("investment")}, + {8, QStringLiteral("moneymarket")}, + {10, QStringLiteral("asset")}, + {11, QStringLiteral("liability")}, + {12, QStringLiteral("currency")}, + {13, QStringLiteral("income")}, + {14, QStringLiteral("expense")}, + {15, QStringLiteral("assetloan")}, + {16, QStringLiteral("stock")}, + {17, QStringLiteral("equity")}, + {18, QStringLiteral("invalid")} + }; + return lut; +} + +QString accountTypeAttributeToString(int textID) +{ + return accountTypeAttributeLUT().value(textID); +} + +int stringToAccountTypeAttribute(const QString &text) +{ + return accountTypeAttributeLUT().key(text, 0); +} + +eMyMoney::Report::ReportType rowTypeToReportType(eMyMoney::Report::RowType rowType) +{ + static const QHash reportTypes { + {eMyMoney::Report::RowType::NoRows, eMyMoney::Report::ReportType::NoReport}, + {eMyMoney::Report::RowType::AssetLiability, eMyMoney::Report::ReportType::PivotTable}, + {eMyMoney::Report::RowType::ExpenseIncome, eMyMoney::Report::ReportType::PivotTable}, + {eMyMoney::Report::RowType::Category, eMyMoney::Report::ReportType::QueryTable}, + {eMyMoney::Report::RowType::TopCategory, eMyMoney::Report::ReportType::QueryTable}, + {eMyMoney::Report::RowType::Account, eMyMoney::Report::ReportType::QueryTable}, + {eMyMoney::Report::RowType::Tag, eMyMoney::Report::ReportType::QueryTable}, + {eMyMoney::Report::RowType::Payee, eMyMoney::Report::ReportType::QueryTable}, + {eMyMoney::Report::RowType::Month, eMyMoney::Report::ReportType::QueryTable}, + {eMyMoney::Report::RowType::Week, eMyMoney::Report::ReportType::QueryTable}, + {eMyMoney::Report::RowType::TopAccount, eMyMoney::Report::ReportType::QueryTable}, + {eMyMoney::Report::RowType::AccountByTopAccount, eMyMoney::Report::ReportType::QueryTable}, + {eMyMoney::Report::RowType::EquityType, eMyMoney::Report::ReportType::QueryTable}, + {eMyMoney::Report::RowType::AccountType, eMyMoney::Report::ReportType::QueryTable}, + {eMyMoney::Report::RowType::Institution, eMyMoney::Report::ReportType::QueryTable}, + {eMyMoney::Report::RowType::Budget, eMyMoney::Report::ReportType::PivotTable}, + {eMyMoney::Report::RowType::BudgetActual, eMyMoney::Report::ReportType::PivotTable}, + {eMyMoney::Report::RowType::Schedule, eMyMoney::Report::ReportType::InfoTable}, + {eMyMoney::Report::RowType::AccountInfo, eMyMoney::Report::ReportType::InfoTable}, + {eMyMoney::Report::RowType::AccountLoanInfo, eMyMoney::Report::ReportType::InfoTable}, + {eMyMoney::Report::RowType::AccountReconcile, eMyMoney::Report::ReportType::QueryTable}, + {eMyMoney::Report::RowType::CashFlow, eMyMoney::Report::ReportType::QueryTable}, + }; + return reportTypes.value(rowType, eMyMoney::Report::ReportType::Invalid); +} + +QHash budgetLevelLUT() +{ + static const QHash lut { + {eMyMoney::Budget::Level::None, QStringLiteral("none")}, + {eMyMoney::Budget::Level::Monthly, QStringLiteral("monthly")}, + {eMyMoney::Budget::Level::MonthByMonth, QStringLiteral("monthbymonth")}, + {eMyMoney::Budget::Level::Yearly, QStringLiteral("yearly")}, + {eMyMoney::Budget::Level::Max, QStringLiteral("invalid")}, + }; + return lut; +} + +QString budgetNames(eMyMoney::Budget::Level textID) +{ + return budgetLevelLUT().value(textID); +} +eMyMoney::Budget::Level stringToBudgetLevel(const QString &text) +{ + return budgetLevelLUT().key(text, eMyMoney::Budget::Level::Max); } diff --git a/kmymoney/plugins/xml/mymoneystoragexml.h b/kmymoney/plugins/xml/mymoneystoragexml.h --- a/kmymoney/plugins/xml/mymoneystoragexml.h +++ b/kmymoney/plugins/xml/mymoneystoragexml.h @@ -157,13 +157,6 @@ private: void (*m_progressCallback)(int, int, const QString&); - - enum elNameE { enAddress, enCreationDate, enLastModifiedDate, - enVersion, enFixVersion, enPair - }; - - static const QString getElName(const elNameE _el); - protected: MyMoneyStorageMgr *m_storage; QDomDocument *m_doc; diff --git a/kmymoney/plugins/xml/mymoneystoragexml.cpp b/kmymoney/plugins/xml/mymoneystoragexml.cpp --- a/kmymoney/plugins/xml/mymoneystoragexml.cpp +++ b/kmymoney/plugins/xml/mymoneystoragexml.cpp @@ -58,16 +58,20 @@ #include "mymoneyprice.h" #include "mymoneycostcenter.h" #include "mymoneytransaction.h" +#include "mymoneysplit.h" #include "onlinejob.h" +#include "onlinejobadministration.h" #include "mymoneyenums.h" using namespace MyMoneyStorageTags; using namespace MyMoneyStorageNodes; using namespace MyMoneyStorageAttributes; +using namespace eMyMoney; unsigned int MyMoneyStorageXML::fileVersionRead = 0; unsigned int MyMoneyStorageXML::fileVersionWrite = 0; + class MyMoneyStorageXML::Private { friend class MyMoneyStorageXML; @@ -98,12 +102,12 @@ id = 'T' + id.rightJustified(TRANSACTION_ID_SIZE, '0'); return id; } - - }; class MyMoneyXmlContentHandler : public QXmlContentHandler { + friend class MyMoneyXmlContentHandlerTest; + public: MyMoneyXmlContentHandler(MyMoneyStorageXML* reader); virtual ~MyMoneyXmlContentHandler() {} @@ -138,6 +142,19 @@ */ QDomElement m_currNode; QString m_errMsg; + + static void addToKeyValueContainer(MyMoneyKeyValueContainer &container, const QDomElement &node); + static MyMoneyTransaction readTransaction(const QDomElement &node); + static MyMoneyAccount readAccount(const QDomElement &node); + static MyMoneyPayee readPayee(const QDomElement &node); + static MyMoneyTag readTag(const QDomElement &node); + static MyMoneySecurity readSecurity(const QDomElement &node); + static MyMoneyInstitution readInstitution(const QDomElement &node); + static MyMoneyReport readReport(const QDomElement &node); + static MyMoneyBudget readBudget(const QDomElement &node); + static MyMoneySchedule readSchedule(const QDomElement &node); + static onlineJob readOnlineJob(const QDomElement &node); + static MyMoneyCostCenter readCostCenter(const QDomElement &node); }; MyMoneyXmlContentHandler::MyMoneyXmlContentHandler(MyMoneyStorageXML* reader) : @@ -182,74 +199,74 @@ { if (m_level == 0) { QString s = qName.toUpper(); - if (s == nodeNames[nnTransaction] - || s == nodeNames[nnAccount] - || s == nodeNames[nnPrice] - || s == nodeNames[nnPayee] - || s == nodeNames[nnTag] - || s == nodeNames[nnCostCenter] - || s == nodeNames[nnCurrency] - || s == nodeNames[nnSecurity] - || s == nodeNames[nnKeyValuePairs] - || s == nodeNames[nnInstitution] - || s == nodeNames[nnReport] - || s == nodeNames[nnBudget] - || s == tagNames[tnFileInfo] - || s == tagNames[tnUser] - || s == nodeNames[nnScheduleTX] - || s == nodeNames[nnOnlineJob]) { + if (s == nodeName(Node::Transaction) + || s == nodeName(Node::Account) + || s == nodeName(Node::Price) + || s == nodeName(Node::Payee) + || s == nodeName(Node::Tag) + || s == nodeName(Node::CostCenter) + || s == nodeName(Node::Currency) + || s == nodeName(Node::Security) + || s == nodeName(Node::KeyValuePairs) + || s == nodeName(Node::Institution) + || s == nodeName(Node::Report) + || s == nodeName(Node::Budget) + || s == tagName(Tag::FileInfo) + || s == tagName(Tag::User) + || s == nodeName(Node::ScheduleTX) + || s == nodeName(Node::OnlineJob)) { m_baseNode = m_doc.createElement(qName); for (int i = 0; i < atts.count(); ++i) { m_baseNode.setAttribute(atts.qName(i), atts.value(i)); } m_currNode = m_baseNode; m_level = 1; - } else if (s == tagNames[tnTransactions]) { + } else if (s == tagName(Tag::Transactions)) { if (atts.count()) { - int count = atts.value(attrNames[anCount]).toInt(); + int count = atts.value(attributeName(Attribute::General::Count)).toInt(); m_reader->signalProgress(0, count, i18n("Loading transactions...")); m_elementCount = 0; } - } else if (s == tagNames[tnAccounts]) { + } else if (s == tagName(Tag::Accounts)) { if (atts.count()) { - int count = atts.value(attrNames[anCount]).toInt(); + int count = atts.value(attributeName(Attribute::General::Count)).toInt(); m_reader->signalProgress(0, count, i18n("Loading accounts...")); m_elementCount = 0; } - } else if (s == tagNames[tnSecurities]) { + } else if (s == tagName(Tag::Securities)) { qDebug("reading securities"); if (atts.count()) { - int count = atts.value(attrNames[anCount]).toInt(); + int count = atts.value(attributeName(Attribute::General::Count)).toInt(); m_reader->signalProgress(0, count, i18n("Loading securities...")); m_elementCount = 0; } - } else if (s == tagNames[tnCurrencies]) { + } else if (s == tagName(Tag::Currencies)) { if (atts.count()) { - int count = atts.value(attrNames[anCount]).toInt(); + int count = atts.value(attributeName(Attribute::General::Count)).toInt(); m_reader->signalProgress(0, count, i18n("Loading currencies...")); m_elementCount = 0; } - } else if (s == tagNames[tnReports]) { + } else if (s == tagName(Tag::Reports)) { if (atts.count()) { - int count = atts.value(attrNames[anCount]).toInt(); + int count = atts.value(attributeName(Attribute::General::Count)).toInt(); m_reader->signalProgress(0, count, i18n("Loading reports...")); m_elementCount = 0; } - } else if (s == tagNames[tnPrices]) { + } else if (s == tagName(Tag::Prices)) { if (atts.count()) { - int count = atts.value(attrNames[anCount]).toInt(); + int count = atts.value(attributeName(Attribute::General::Count)).toInt(); m_reader->signalProgress(0, count, i18n("Loading prices...")); m_elementCount = 0; } - } else if (s == nodeNames[nnPricePair]) { + } else if (s == nodeName(Node::PricePair)) { if (atts.count()) { - m_reader->d->m_fromSecurity = atts.value(attrNames[anFrom]); - m_reader->d->m_toSecurity = atts.value(attrNames[anTo]); + m_reader->d->m_fromSecurity = atts.value(attributeName(Attribute::General::From)); + m_reader->d->m_toSecurity = atts.value(attributeName(Attribute::General::To)); } - } else if (s == tagNames[tnCostCenters]) { + } else if (s == tagName(Tag::CostCenters)) { if(atts.count()) { - int count = atts.value(attrNames[anCount]).toInt(); + int count = atts.value(attributeName(Attribute::General::Count)).toInt(); m_reader->signalProgress(0, count, i18n("Loading cost center...")); m_elementCount = 0; } @@ -277,74 +294,76 @@ m_level--; if (!m_level) { try { - if (s == nodeNames[nnTransaction]) { - MyMoneyTransaction t0(m_baseNode); + if (s == nodeName(Node::Transaction)) { + auto t0 = readTransaction(m_baseNode); if (!t0.id().isEmpty()) { MyMoneyTransaction t1(m_reader->d->nextTransactionID(), t0); m_reader->d->tList[t1.uniqueSortKey()] = t1; } m_reader->signalProgress(++m_elementCount, 0); - } else if (s == nodeNames[nnAccount]) { - MyMoneyAccount a(m_baseNode); + } else if (s == nodeName(Node::Account)) { + auto a = readAccount(m_baseNode); if (!a.id().isEmpty()) m_reader->d->aList[a.id()] = a; m_reader->signalProgress(++m_elementCount, 0); - } else if (s == nodeNames[nnPayee]) { - MyMoneyPayee p(m_baseNode); + } else if (s == nodeName(Node::Payee)) { + auto p = readPayee(m_baseNode); if (!p.id().isEmpty()) m_reader->d->pList[p.id()] = p; m_reader->signalProgress(++m_elementCount, 0); - } else if (s == nodeNames[nnTag]) { - MyMoneyTag ta(m_baseNode); + } else if (s == nodeName(Node::Tag)) { + auto ta = readTag(m_baseNode); if (!ta.id().isEmpty()) m_reader->d->taList[ta.id()] = ta; m_reader->signalProgress(++m_elementCount, 0); - } else if (s == nodeNames[nnCurrency]) { - MyMoneySecurity sec(m_baseNode); + } else if (s == nodeName(Node::Currency)) { + auto sec = readSecurity(m_baseNode); if (!sec.id().isEmpty()) m_reader->d->secList[sec.id()] = sec; m_reader->signalProgress(++m_elementCount, 0); - } else if (s == nodeNames[nnSecurity]) { - MyMoneySecurity sec(m_baseNode); + } else if (s == nodeName(Node::Security)) { + auto sec = readSecurity(m_baseNode); if (!sec.id().isEmpty()) m_reader->d->secList[sec.id()] = sec; m_reader->signalProgress(++m_elementCount, 0); - } else if (s == nodeNames[nnKeyValuePairs]) { + } else if (s == nodeName(Node::KeyValuePairs)) { + addToKeyValueContainer(*m_reader->m_storage, m_baseNode); MyMoneyKeyValueContainer kvp(m_baseNode); - m_reader->m_storage->setPairs(kvp.pairs()); - } else if (s == nodeNames[nnInstitution]) { - MyMoneyInstitution i(m_baseNode); + if (!(kvp.pairs() == m_reader->m_storage->pairs())) + qDebug() << "KVP is not equal."; + } else if (s == nodeName(Node::Institution)) { + auto i = readInstitution(m_baseNode); if (!i.id().isEmpty()) m_reader->d->iList[i.id()] = i; - } else if (s == nodeNames[nnReport]) { - MyMoneyReport r(m_baseNode); + } else if (s == nodeName(Node::Report)) { + auto r = readReport(m_baseNode); if (!r.id().isEmpty()) m_reader->d->rList[r.id()] = r; m_reader->signalProgress(++m_elementCount, 0); - } else if (s == nodeNames[nnBudget]) { - MyMoneyBudget b(m_baseNode); + } else if (s == nodeName(Node::Budget)) { + auto b = readBudget(m_baseNode); if (!b.id().isEmpty()) m_reader->d->bList[b.id()] = b; - } else if (s == tagNames[tnFileInfo]) { + } else if (s == tagName(Tag::FileInfo)) { rc = m_reader->readFileInformation(m_baseNode); m_reader->signalProgress(-1, -1); - } else if (s == tagNames[tnUser]) { + } else if (s == tagName(Tag::User)) { rc = m_reader->readUserInformation(m_baseNode); m_reader->signalProgress(-1, -1); - } else if (s == nodeNames[nnScheduleTX]) { - MyMoneySchedule sch(m_baseNode); + } else if (s == nodeName(Node::ScheduleTX)) { + auto sch = readSchedule(m_baseNode); if (!sch.id().isEmpty()) m_reader->d->sList[sch.id()] = sch; - } else if (s == nodeNames[nnPrice]) { + } else if (s == nodeName(Node::Price)) { MyMoneyPrice p(m_reader->d->m_fromSecurity, m_reader->d->m_toSecurity, m_baseNode); m_reader->d->prList[MyMoneySecurityPair(m_reader->d->m_fromSecurity, m_reader->d->m_toSecurity)][p.date()] = p; m_reader->signalProgress(++m_elementCount, 0); - } else if (s == nodeNames[nnOnlineJob]) { - onlineJob job(m_baseNode); + } else if (s == nodeName(Node::OnlineJob)) { + auto job = readOnlineJob(m_baseNode); if (!job.id().isEmpty()) m_reader->d->onlineJobList[job.id()] = job; - } else if (s == nodeNames[nnCostCenter]) { - MyMoneyCostCenter c(m_baseNode); + } else if (s == nodeName(Node::CostCenter)) { + auto c = readCostCenter(m_baseNode); if(!c.id().isEmpty()) { m_reader->d->ccList[c.id()] = c; } @@ -362,60 +381,60 @@ m_doc = QDomDocument(); } } else { - if (s == tagNames[tnInstitutions]) { + if (s == tagName(Tag::Institutions)) { // last institution read, now dump them into the engine m_reader->m_storage->loadInstitutions(m_reader->d->iList); m_reader->d->iList.clear(); - } else if (s == tagNames[tnAccounts]) { + } else if (s == tagName(Tag::Accounts)) { // last account read, now dump them into the engine m_reader->m_storage->loadAccounts(m_reader->d->aList); m_reader->d->aList.clear(); m_reader->signalProgress(-1, -1); - } else if (s == tagNames[tnPayees]) { + } else if (s == tagName(Tag::Payees)) { // last payee read, now dump them into the engine m_reader->m_storage->loadPayees(m_reader->d->pList); m_reader->d->pList.clear(); - } else if (s == tagNames[tnTags]) { + } else if (s == tagName(Tag::Tags)) { // last tag read, now dump them into the engine m_reader->m_storage->loadTags(m_reader->d->taList); m_reader->d->taList.clear(); - } else if (s == tagNames[tnTransactions]) { + } else if (s == tagName(Tag::Transactions)) { // last transaction read, now dump them into the engine m_reader->m_storage->loadTransactions(m_reader->d->tList); m_reader->d->tList.clear(); m_reader->signalProgress(-1, -1); - } else if (s == tagNames[tnSchedules]) { + } else if (s == tagName(Tag::Schedules)) { // last schedule read, now dump them into the engine m_reader->m_storage->loadSchedules(m_reader->d->sList); m_reader->d->sList.clear(); - } else if (s == tagNames[tnSecurities]) { + } else if (s == tagName(Tag::Securities)) { // last security read, now dump them into the engine m_reader->m_storage->loadSecurities(m_reader->d->secList); m_reader->d->secList.clear(); m_reader->signalProgress(-1, -1); - } else if (s == tagNames[tnCurrencies]) { + } else if (s == tagName(Tag::Currencies)) { // last currency read, now dump them into the engine m_reader->m_storage->loadCurrencies(m_reader->d->secList); m_reader->d->secList.clear(); m_reader->signalProgress(-1, -1); - } else if (s == tagNames[tnReports]) { + } else if (s == tagName(Tag::Reports)) { // last report read, now dump them into the engine m_reader->m_storage->loadReports(m_reader->d->rList); m_reader->d->rList.clear(); m_reader->signalProgress(-1, -1); - } else if (s == tagNames[tnBudgets]) { + } else if (s == tagName(Tag::Budgets)) { // last budget read, now dump them into the engine m_reader->m_storage->loadBudgets(m_reader->d->bList); m_reader->d->bList.clear(); - } else if (s == tagNames[tnPrices]) { + } else if (s == tagName(Tag::Prices)) { // last price read, now dump them into the engine m_reader->m_storage->loadPrices(m_reader->d->prList); m_reader->d->bList.clear(); m_reader->signalProgress(-1, -1); - } else if (s == tagNames[tnOnlineJobs]) { + } else if (s == tagName(Tag::OnlineJobs)) { m_reader->m_storage->loadOnlineJobs(m_reader->d->onlineJobList); m_reader->d->onlineJobList.clear(); - } else if (s == tagNames[tnCostCenters]) { + } else if (s == tagName(Tag::CostCenters)) { m_reader->m_storage->loadCostCenters(m_reader->d->ccList); m_reader->d->ccList.clear(); m_reader->signalProgress(-1, -1); @@ -444,6 +463,670 @@ return m_errMsg; } +void MyMoneyXmlContentHandler::addToKeyValueContainer(MyMoneyKeyValueContainer &container, const QDomElement &node) +{ + if (!node.isNull()) { + if (nodeName(Node::KeyValuePairs) != node.tagName()) + throw MYMONEYEXCEPTION_CSTRING("Node was not KEYVALUEPAIRS"); +// container.clear(); + + QDomNodeList nodeList = node.elementsByTagName(elementName(Element::KVP::Pair)); + for (int i = 0; i < nodeList.count(); ++i) { + const auto& el(nodeList.item(i).toElement()); + container.setValue(el.attribute(attributeName(Attribute::KVP::Key)), + el.attribute(attributeName(Attribute::KVP::Value))); + } + } +} + +MyMoneyTransaction MyMoneyXmlContentHandler::readTransaction(const QDomElement &node) +{ + if (nodeName(Node::Transaction) != node.tagName()) + throw MYMONEYEXCEPTION_CSTRING("Node was not TRANSACTION"); + + MyMoneyTransaction transaction(node.attribute(attributeName(Attribute::Account::ID))); + + // d->m_nextSplitID = 1; + + transaction.setPostDate(QDate::fromString(node.attribute(attributeName(Attribute::Transaction::PostDate)), Qt::ISODate)); + transaction.setEntryDate(QDate::fromString(node.attribute(attributeName(Attribute::Transaction::EntryDate)),Qt::ISODate)); + transaction.setBankID(node.attribute(attributeName(Attribute::Transaction::BankID))); + transaction.setMemo(node.attribute(attributeName(Attribute::Transaction::Memo))); + transaction.setCommodity(node.attribute(attributeName(Attribute::Transaction::Commodity))); + + QDomNode child = node.firstChild(); + while (!child.isNull() && child.isElement()) { + QDomElement c = child.toElement(); + if (c.tagName() == elementName(Element::Transaction::Splits)) { + + // Process any split information found inside the transaction entry. + QDomNodeList nodeList = c.elementsByTagName(elementName(Element::Transaction::Split)); + for (int i = 0; i < nodeList.count(); ++i) { + MyMoneySplit s(nodeList.item(i).toElement()); + if (!transaction.bankID().isEmpty()) + s.setBankID(transaction.bankID()); + if (!s.accountId().isEmpty()) + transaction.addSplit(s); + else + qDebug("Dropped split because it did not have an account id"); + } + + } else if (c.tagName() == nodeName(Node::KeyValuePairs)) { + addToKeyValueContainer(transaction, c.toElement()); + } + + child = child.nextSibling(); + } + transaction.setBankID(QString()); + + return transaction; +} + +MyMoneyAccount MyMoneyXmlContentHandler::readAccount(const QDomElement &node) +{ + if (nodeName(Node::Account) != node.tagName()) + throw MYMONEYEXCEPTION_CSTRING("Node was not ACCOUNT"); + + MyMoneyAccount acc(node.attribute(attributeName(Attribute::Account::ID))); + + addToKeyValueContainer(acc, node.elementsByTagName(nodeName(Node::KeyValuePairs)).item(0).toElement()); + + acc.setName(node.attribute(attributeName(Attribute::Account::Name))); + + // qDebug("Reading information for account %s", acc.name().data()); + + acc.setParentAccountId(node.attribute(attributeName(Attribute::Account::ParentAccount))); + acc.setLastModified(QDate::fromString(node.attribute(attributeName(Attribute::Account::LastModified)), Qt::ISODate)); + acc.setLastReconciliationDate(QDate::fromString(node.attribute(attributeName(Attribute::Account::LastReconciled)), Qt::ISODate)); + + if (!acc.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(nodeName(Node::KeyValuePairs)).item(0).toElement()).value("lastStatementDate"); + if (!txt.isEmpty()) { + acc.setLastReconciliationDate(QDate::fromString(txt, Qt::ISODate)); + } + } + + acc.setInstitutionId(node.attribute(attributeName(Attribute::Account::Institution))); + acc.setNumber(node.attribute(attributeName(Attribute::Account::Number))); + acc.setOpeningDate(QDate::fromString(node.attribute(attributeName(Attribute::Account::Opened)), Qt::ISODate)); + acc.setCurrencyId(node.attribute(attributeName(Attribute::Account::Currency))); + + auto tmp = node.attribute(attributeName(Attribute::Account::Type)); + auto bOK = false; + auto type = tmp.toInt(&bOK); + if (bOK) { + acc.setAccountType(static_cast(type)); + } else { + qWarning("XMLREADER: Account %s had invalid or no account type information.", qPrintable(acc.name())); + } + + const auto openingBalance = node.attribute(attributeName(Attribute::Account::OpeningBalance)); + if (!openingBalance.isEmpty()) + if (!MyMoneyMoney(openingBalance).isZero()) + throw MYMONEYEXCEPTION(QString::fromLatin1("Account %1 contains an opening balance. Please use KMyMoney version 0.8 or later and earlier than version 0.9 to correct the problem.").arg(acc.name())); + + acc.setDescription(node.attribute(attributeName(Attribute::Account::Description))); + + // 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. + acc.removeAccountIds(); + QDomNodeList nodeList = node.elementsByTagName(elementName(Element::Account::SubAccounts)); + if (!nodeList.isEmpty()) { + nodeList = nodeList.item(0).toElement().elementsByTagName(elementName(Element::Account::SubAccount)); + for (int i = 0; i < nodeList.count(); ++i) { + acc.addAccountId(QString(nodeList.item(i).toElement().attribute(attributeName(Attribute::Account::ID)))); + } + } + + nodeList = node.elementsByTagName(elementName(Element::Account::OnlineBanking)); + if (!nodeList.isEmpty()) { + MyMoneyKeyValueContainer kvp; + const auto attributes = nodeList.item(0).toElement().attributes(); + for (auto i = 0; i < attributes.count(); ++i) { + const auto it_attr = attributes.item(i).toAttr(); + kvp.setValue(it_attr.name(), it_attr.value()); + } + acc.setOnlineBankingSettings(kvp); + } + + // Up to and including version 4.6.6 the new account dialog stored the iban in the kvp-key "IBAN". + // But the rest of the software uses "iban". So correct this: + if (!acc.value("IBAN").isEmpty()) { + // If "iban" was not set, set it now. If it is set, the user reseted it already, so remove + // the garbage. + if (acc.value(attributeName(Attribute::Account::IBAN)).isEmpty()) + acc.setValue(attributeName(Attribute::Account::IBAN), acc.value("IBAN")); + acc.deletePair("IBAN"); + } + return acc; +} + +MyMoneyPayee MyMoneyXmlContentHandler::readPayee(const QDomElement &node) +{ + if (nodeName(Node::Payee) != node.tagName()) + throw MYMONEYEXCEPTION_CSTRING("Node was not PAYEE"); + + MyMoneyPayee payee(node.attribute(attributeName(Attribute::Account::ID))); + + // MyMoneyPayee payee(node.attribute(attributeName(Attribute::Payee::ID))); + payee.setName(node.attribute(attributeName(Attribute::Payee::Name))); + payee.setReference(node.attribute(attributeName(Attribute::Payee::Reference))); + payee.setEmail(node.attribute(attributeName(Attribute::Payee::Email))); + auto type = static_cast(node.attribute(attributeName(Attribute::Payee::MatchingEnabled), "0").toUInt()); + payee.setMatchData(eMyMoney::Payee::MatchType::Disabled, true, QString()); + if (type != eMyMoney::Payee::MatchType::Disabled) { + payee.setMatchData((node.attribute(attributeName(Attribute::Payee::UsingMatchKey), "0").toUInt() != 0) ? eMyMoney::Payee::MatchType::Key : eMyMoney::Payee::MatchType::Name, + node.attribute(attributeName(Attribute::Payee::MatchIgnoreCase), "0").toUInt(), + node.attribute(attributeName(Attribute::Payee::MatchKey))); + } + + if (node.hasAttribute(attributeName(Attribute::Payee::Notes))) + payee.setNotes(node.attribute(attributeName(Attribute::Payee::Notes))); + + if (node.hasAttribute(attributeName(Attribute::Payee::DefaultAccountID))) + payee.setDefaultAccountId(node.attribute(attributeName(Attribute::Payee::DefaultAccountID))); + + // Load Address + QDomNodeList nodeList = node.elementsByTagName(elementName(Element::Payee::Address)); + if (nodeList.isEmpty()) + throw MYMONEYEXCEPTION(QString::fromLatin1("No ADDRESS in payee %1").arg(payee.name())); + + QDomElement addrNode = nodeList.item(0).toElement(); + payee.setAddress(addrNode.attribute(attributeName(Attribute::Payee::Street))); + payee.setCity(addrNode.attribute(attributeName(Attribute::Payee::City))); + payee.setPostcode(addrNode.attribute(attributeName(Attribute::Payee::PostCode))); + payee.setState(addrNode.attribute(attributeName(Attribute::Payee::State))); + payee.setTelephone(addrNode.attribute(attributeName(Attribute::Payee::Telephone))); + + payee.loadXML(node); + + return payee; +} + +MyMoneyTag MyMoneyXmlContentHandler::readTag(const QDomElement &node) +{ + if (nodeName(Node::Tag) != node.tagName()) + throw MYMONEYEXCEPTION_CSTRING("Node was not TAG"); + + MyMoneyTag tag(node.attribute(attributeName(Attribute::Account::ID))); + + tag.setName(node.attribute(attributeName(Attribute::Tag::Name))); + if (node.hasAttribute(attributeName(Attribute::Tag::TagColor))) { + tag.setNamedTagColor(attributeName(Attribute::Tag::TagColor)); + } + if (node.hasAttribute(attributeName(Attribute::Tag::Notes))) { + tag.setNotes(node.attribute(attributeName(Attribute::Tag::Notes))); + } + tag.setClosed(node.attribute(attributeName(Attribute::Tag::Closed), "0").toUInt()); + + return tag; +} + +MyMoneySecurity MyMoneyXmlContentHandler::readSecurity(const QDomElement &node) +{ + const auto tag = node.tagName(); + if ((nodeName(Node::Security) != tag) + && (nodeName(Node::Equity) != tag) + && (nodeName(Node::Currency) != tag)) + throw MYMONEYEXCEPTION_CSTRING("Node was not SECURITY or CURRENCY"); + + MyMoneySecurity security(node.attribute(attributeName(Attribute::Account::ID))); + + addToKeyValueContainer(security, node.elementsByTagName(nodeName(Node::KeyValuePairs)).item(0).toElement()); + + security.setName(node.attribute(attributeName(Attribute::Security::Name))); + security.setTradingSymbol(node.attribute(attributeName(Attribute::Security::Symbol))); + security.setSecurityType(static_cast(node.attribute(attributeName(Attribute::Security::Type)).toInt())); + security.setRoundingMethod(static_cast(node.attribute(attributeName(Attribute::Security::RoundingMethod)).toInt())); + security.setSmallestAccountFraction(node.attribute(attributeName(Attribute::Security::SAF)).toUInt()); + security.setPricePrecision(node.attribute(attributeName(Attribute::Security::PP)).toUInt()); + + if (security.smallestAccountFraction() == 0) + security.setSmallestAccountFraction(100); + if (security.pricePrecision() == 0 || security.pricePrecision() > 10) + security.setPricePrecision(4); + + if (security.isCurrency()) { + security.setSmallestCashFraction(node.attribute(attributeName(Attribute::Security::SCF)).toUInt()); + if (security.smallestCashFraction() == 0) + security.setSmallestCashFraction(100); + } else { + security.setTradingCurrency(node.attribute(attributeName(Attribute::Security::TradingCurrency))); + security.setTradingMarket(node.attribute(attributeName(Attribute::Security::TradingMarket))); + } + + return security; +} + +MyMoneyInstitution MyMoneyXmlContentHandler::readInstitution(const QDomElement &node) +{ + if (nodeName(Node::Institution) != node.tagName()) + throw MYMONEYEXCEPTION_CSTRING("Node was not INSTITUTION"); + + MyMoneyInstitution institution(node.attribute(attributeName(Attribute::Account::ID))); + + addToKeyValueContainer(institution, node.elementsByTagName(nodeName(Node::KeyValuePairs)).item(0).toElement()); + + institution.setSortcode(node.attribute(attributeName(Attribute::Institution::SortCode))); + institution.setName(node.attribute(attributeName(Attribute::Institution::Name))); + institution.setManager(node.attribute(attributeName(Attribute::Institution::Manager))); + + QDomNodeList nodeList = node.elementsByTagName(elementName(Element::Institution::Address)); + if (nodeList.isEmpty()) + throw MYMONEYEXCEPTION(QString::fromLatin1("No ADDRESS in institution %1").arg(institution.name())); + + QDomElement addrNode = nodeList.item(0).toElement(); + institution.setStreet(addrNode.attribute(attributeName(Attribute::Institution::Street))); + institution.setTown(addrNode.attribute(attributeName(Attribute::Institution::City))); + institution.setPostcode(addrNode.attribute(attributeName(Attribute::Institution::Zip))); + institution.setTelephone(addrNode.attribute(attributeName(Attribute::Institution::Telephone))); + + nodeList = node.elementsByTagName(elementName(Element::Institution::AccountIDS)); + if (!nodeList.isEmpty()) { + nodeList = nodeList.item(0).toElement().elementsByTagName(elementName(Element::Institution::AccountID)); + for (int i = 0; i < nodeList.count(); ++i) + institution.addAccountId(nodeList.item(i).toElement().attribute(attributeName(Attribute::Institution::ID))); + } + + return institution; +} + +MyMoneyReport MyMoneyXmlContentHandler::readReport(const QDomElement &node) +{ + if (nodeName(Node::Report) != node.tagName()) + throw MYMONEYEXCEPTION_CSTRING("Node was not REPORT"); + + MyMoneyReport report(node.attribute(attributeName(Attribute::Report::ID))); + + // The goal of this reading method is 100% backward AND 100% forward + // compatibility. Any report ever created with any version of KMyMoney + // should be able to be loaded by this method (as long as it's one of the + // report types supported in this version, of course) + + + // read report's internals + QString type = node.attribute(attributeName(Attribute::Report::Type)); + if (type.startsWith(QLatin1String("pivottable"))) + report.setReportType(eMyMoney::Report::ReportType::PivotTable); + else if (type.startsWith(QLatin1String("querytable"))) + report.setReportType(eMyMoney::Report::ReportType::QueryTable); + else if (type.startsWith(QLatin1String("infotable"))) + report.setReportType(eMyMoney::Report::ReportType::InfoTable); + else + throw MYMONEYEXCEPTION_CSTRING("Unknown report type"); + + report.setGroup(node.attribute(attributeName(Attribute::Report::Group))); + + report.clearTransactionFilter(); + + // read date tab + QString datelockstr = node.attribute(attributeName(Attribute::Report::DateLock), "userdefined"); + // Handle the pivot 1.2/query 1.1 case where the values were saved as + // numbers + bool ok = false; + int i = datelockstr.toUInt(&ok); + if (!ok) { + i = stringToDateLockAttribute(datelockstr); + if (i == -1) + i = (int)eMyMoney::TransactionFilter::Date::UserDefined; + } + report.setDateFilter(static_cast(i)); + + // read general tab + report.setName(node.attribute(attributeName(Attribute::Report::Name))); + report.setComment(node.attribute(attributeName(Attribute::Report::Comment), "Extremely old report")); + report.setConvertCurrency(node.attribute(attributeName(Attribute::Report::ConvertCurrency), "1").toUInt()); + report.setFavorite(node.attribute(attributeName(Attribute::Report::Favorite), "0").toUInt()); + report.setSkipZero(node.attribute(attributeName(Attribute::Report::SkipZero), "0").toUInt()); + + if (report.reportType() == eMyMoney::Report::ReportType::PivotTable) { + // read report's internals + report.setIncludingBudgetActuals(node.attribute(attributeName(Attribute::Report::IncludesActuals), "0").toUInt()); + report.setIncludingForecast(node.attribute(attributeName(Attribute::Report::IncludesForecast), "0").toUInt()); + report.setIncludingPrice(node.attribute(attributeName(Attribute::Report::IncludesPrice), "0").toUInt()); + report.setIncludingAveragePrice(node.attribute(attributeName(Attribute::Report::IncludesAveragePrice), "0").toUInt()); + report.setMixedTime(node.attribute(attributeName(Attribute::Report::MixedTime), "0").toUInt()); + report.setInvestmentsOnly(node.attribute(attributeName(Attribute::Report::Investments), "0").toUInt()); + + // read rows/columns tab + if (node.hasAttribute(attributeName(Attribute::Report::Budget))) + report.setBudget(node.attribute(attributeName(Attribute::Report::Budget))); + + const auto rowTypeFromXML = stringToRowType(node.attribute(attributeName(Attribute::Report::RowType))); + if (rowTypeFromXML != eMyMoney::Report::RowType::Invalid) + report.setRowType(rowTypeFromXML); + else + report.setRowType(eMyMoney::Report::RowType::ExpenseIncome); + + if (node.hasAttribute(attributeName(Attribute::Report::ShowRowTotals))) + report.setShowingRowTotals(node.attribute(attributeName(Attribute::Report::ShowRowTotals)).toUInt()); + else if (report.rowType() == eMyMoney::Report::RowType::ExpenseIncome) // for backward compatibility + report.setShowingRowTotals(true); + report.setShowingColumnTotals(node.attribute(attributeName(Attribute::Report::ShowColumnTotals), "1").toUInt()); + + //check for reports with older settings which didn't have the detail attribute + const auto detailLevelFromXML = stringToDetailLevel(node.attribute(attributeName(Attribute::Report::Detail))); + if (detailLevelFromXML != eMyMoney::Report::DetailLevel::End) + report.setDetailLevel(detailLevelFromXML); + else + report.setDetailLevel(eMyMoney::Report::DetailLevel::All); + + report.setIncludingMovingAverage(node.attribute(attributeName(Attribute::Report::IncludesMovingAverage), "0").toUInt()); + if (report.isIncludingMovingAverage()) + report.setMovingAverageDays(node.attribute(attributeName(Attribute::Report::MovingAverageDays), "1").toUInt()); + report.setIncludingSchedules(node.attribute(attributeName(Attribute::Report::IncludesSchedules), "0").toUInt()); + report.setIncludingTransfers(node.attribute(attributeName(Attribute::Report::IncludesTransfers), "0").toUInt()); + report.setIncludingUnusedAccounts(node.attribute(attributeName(Attribute::Report::IncludesUnused), "0").toUInt()); + report.setColumnsAreDays(node.attribute(attributeName(Attribute::Report::ColumnsAreDays), "0").toUInt()); + + // read chart tab + const auto chartTypeFromXML = stringToChartType(node.attribute(attributeName(Attribute::Report::ChartType))); + if (chartTypeFromXML != eMyMoney::Report::ChartType::End) + report.setChartType(chartTypeFromXML); + else + report.setChartType(eMyMoney::Report::ChartType::None); + + report.setChartCHGridLines(node.attribute(attributeName(Attribute::Report::ChartCHGridLines), "1").toUInt()); + report.setChartSVGridLines(node.attribute(attributeName(Attribute::Report::ChartSVGridLines), "1").toUInt()); + report.setChartDataLabels(node.attribute(attributeName(Attribute::Report::ChartDataLabels), "1").toUInt()); + report.setChartByDefault(node.attribute(attributeName(Attribute::Report::ChartByDefault), "0").toUInt()); + report.setLogYAxis(node.attribute(attributeName(Attribute::Report::LogYAxis), "0").toUInt()); + report.setChartLineWidth(node.attribute(attributeName(Attribute::Report::ChartLineWidth), QString(MyMoneyReport::m_lineWidth)).toUInt()); + + // read range tab + const auto columnTypeFromXML = stringToColumnType(node.attribute(attributeName(Attribute::Report::ColumnType))); + if (columnTypeFromXML != eMyMoney::Report::ColumnType::Invalid) + report.setColumnType(columnTypeFromXML); + else + report.setColumnType(eMyMoney::Report::ColumnType::Months); + + const auto dataLockFromXML = stringToDataLockAttribute(node.attribute(attributeName(Attribute::Report::DataLock))); + if (dataLockFromXML != eMyMoney::Report::DataLock::DataOptionCount) + report.setDataFilter(dataLockFromXML); + else + report.setDataFilter(eMyMoney::Report::DataLock::Automatic); + + report.setDataRangeStart(node.attribute(attributeName(Attribute::Report::DataRangeStart), "0")); + report.setDataRangeEnd(node.attribute(attributeName(Attribute::Report::DataRangeEnd), "0")); + report.setDataMajorTick(node.attribute(attributeName(Attribute::Report::DataMajorTick), "0")); + report.setDataMinorTick(node.attribute(attributeName(Attribute::Report::DataMinorTick), "0")); + report.setYLabelsPrecision(node.attribute(attributeName(Attribute::Report::YLabelsPrecision), "2").toUInt()); + } else if (report.reportType() == eMyMoney::Report::ReportType::QueryTable) { + // read rows/columns tab + const auto rowTypeFromXML = stringToRowType(node.attribute(attributeName(Attribute::Report::RowType))); + if (rowTypeFromXML != eMyMoney::Report::RowType::Invalid) + report.setRowType(rowTypeFromXML); + else + report.setRowType(eMyMoney::Report::RowType::Account); + + unsigned qc = 0; + QStringList columns = node.attribute(attributeName(Attribute::Report::QueryColumns), "none").split(','); + foreach (const auto column, columns) { + const int queryColumnFromXML = stringToQueryColumn(column); + i = stringToQueryColumn(column); + if (queryColumnFromXML != eMyMoney::Report::QueryColumn::End) + qc |= queryColumnFromXML; + } + report.setQueryColumns(static_cast(qc)); + + report.setTax(node.attribute(attributeName(Attribute::Report::Tax), "0").toUInt()); + report.setInvestmentsOnly(node.attribute(attributeName(Attribute::Report::Investments), "0").toUInt()); + report.setLoansOnly(node.attribute(attributeName(Attribute::Report::Loans), "0").toUInt()); + report.setHideTransactions(node.attribute(attributeName(Attribute::Report::HideTransactions), "0").toUInt()); + report.setShowingColumnTotals(node.attribute(attributeName(Attribute::Report::ShowColumnTotals), "1").toUInt()); + const auto detailLevelFromXML = stringToDetailLevel(node.attribute(attributeName(Attribute::Report::Detail), "none")); + if (detailLevelFromXML == eMyMoney::Report::DetailLevel::All) + report.setDetailLevel(detailLevelFromXML); + else + report.setDetailLevel(eMyMoney::Report::DetailLevel::None); + + // read performance or capital gains tab + if (report.queryColumns() & eMyMoney::Report::QueryColumn::Performance) + report.setInvestmentSum(static_cast(node.attribute(attributeName(Attribute::Report::InvestmentSum), QString::number(static_cast(eMyMoney::Report::InvestmentSum::Period))).toInt())); + + // read capital gains tab + if (report.queryColumns() & eMyMoney::Report::QueryColumn::CapitalGain) { + report.setInvestmentSum(static_cast(node.attribute(attributeName(Attribute::Report::InvestmentSum), QString::number(static_cast(eMyMoney::Report::InvestmentSum::Sold))).toInt())); + if (report.investmentSum() == eMyMoney::Report::InvestmentSum::Sold) { + report.setShowSTLTCapitalGains(node.attribute(attributeName(Attribute::Report::ShowSTLTCapitalGains), "0").toUInt()); + report.setSettlementPeriod(node.attribute(attributeName(Attribute::Report::SettlementPeriod), "3").toUInt()); + report.setTermSeparator(QDate::fromString(node.attribute(attributeName(Attribute::Report::TermsSeparator), QDate::currentDate().addYears(-1).toString(Qt::ISODate)),Qt::ISODate)); + } + } + } else if (report.reportType() == eMyMoney::Report::ReportType::InfoTable) { + if (node.hasAttribute(attributeName(Attribute::Report::ShowRowTotals))) + report.setShowingRowTotals(node.attribute(attributeName(Attribute::Report::ShowRowTotals)).toUInt()); + else + report.setShowingRowTotals(true); + } + + QDomNode child = node.firstChild(); + while (!child.isNull() && child.isElement()) { + QDomElement c = child.toElement(); + if (elementName(Element::Report::Text) == c.tagName() && c.hasAttribute(attributeName(Attribute::Report::Pattern))) { + report.setTextFilter(QRegExp(c.attribute(attributeName(Attribute::Report::Pattern)), + c.attribute(attributeName(Attribute::Report::CaseSensitive), "1").toUInt() + ? Qt::CaseSensitive : Qt::CaseInsensitive, + c.attribute(attributeName(Attribute::Report::RegEx), "1").toUInt() + ? QRegExp::Wildcard : QRegExp::RegExp), + c.attribute(attributeName(Attribute::Report::InvertText), "0").toUInt()); + } + if (elementName(Element::Report::Type) == c.tagName() && c.hasAttribute(attributeName(Attribute::Report::Type))) { + i = stringToTypeAttribute(c.attribute(attributeName(Attribute::Report::Type))); + if (i != -1) + report.addType(i); + } + if (elementName(Element::Report::State) == c.tagName() && c.hasAttribute(attributeName(Attribute::Report::State))) { + i = stringToStateAttribute(c.attribute(attributeName(Attribute::Report::State))); + if (i != -1) + report.addState(i); + } + if (elementName(Element::Report::Number) == c.tagName()) + report.setNumberFilter(c.attribute(attributeName(Attribute::Report::From)), c.attribute(attributeName(Attribute::Report::To))); + if (elementName(Element::Report::Amount) == c.tagName()) + report.setAmountFilter(MyMoneyMoney(c.attribute(attributeName(Attribute::Report::From), "0/100")), MyMoneyMoney(c.attribute(attributeName(Attribute::Report::To), "0/100"))); + if (elementName(Element::Report::Dates) == c.tagName()) { + QDate from, to; + if (c.hasAttribute(attributeName(Attribute::Report::From))) + from = QDate::fromString(c.attribute(attributeName(Attribute::Report::From)), Qt::ISODate); + if (c.hasAttribute(attributeName(Attribute::Report::To))) + to = QDate::fromString(c.attribute(attributeName(Attribute::Report::To)), Qt::ISODate); + report.setDateFilter(from, to); + } + if (elementName(Element::Report::Payee) == c.tagName()) + report.addPayee(c.attribute(attributeName(Attribute::Report::ID))); + if (elementName(Element::Report::Tag) == c.tagName()) + report.addTag(c.attribute(attributeName(Attribute::Report::ID))); + if (elementName(Element::Report::Category) == c.tagName() && c.hasAttribute(attributeName(Attribute::Report::ID))) + report.addCategory(c.attribute(attributeName(Attribute::Report::ID))); + if (elementName(Element::Report::Account) == c.tagName() && c.hasAttribute(attributeName(Attribute::Report::ID))) + report.addAccount(c.attribute(attributeName(Attribute::Report::ID))); + if (elementName(Element::Report::AccountGroup) == c.tagName() && c.hasAttribute(attributeName(Attribute::Report::Group))) { + i = stringToAccountTypeAttribute(c.attribute(attributeName(Attribute::Report::Group))); + if (i != -1) + report.addAccountGroup(static_cast(i)); + } + child = child.nextSibling(); + } + + + return report; +} + +MyMoneyBudget MyMoneyXmlContentHandler::readBudget(const QDomElement &node) +{ + if (nodeName(Node::Budget) != node.tagName()) + throw MYMONEYEXCEPTION_CSTRING("Node was not BUDGET"); + + MyMoneyBudget budget(node.attribute(attributeName(Attribute::Account::ID))); + // The goal of this reading method is 100% backward AND 100% forward + // compatibility. Any Budget ever created with any version of KMyMoney + // should be able to be loaded by this method (as long as it's one of the + // Budget types supported in this version, of course) + + budget.setName(node.attribute(attributeName(Attribute::Budget::Name))); + budget.setBudgetStart(QDate::fromString(node.attribute(attributeName(Attribute::Budget::Start)), Qt::ISODate)); + + QDomNode child = node.firstChild(); + while (!child.isNull() && child.isElement()) { + QDomElement c = child.toElement(); + + MyMoneyBudget::AccountGroup account; + + if (elementName(Element::Budget::Account) == c.tagName()) { + if (c.hasAttribute(attributeName(Attribute::Budget::ID))) + account.setId(c.attribute(attributeName(Attribute::Budget::ID))); + + if (c.hasAttribute(attributeName(Attribute::Budget::BudgetLevel))) + account.setBudgetLevel(stringToBudgetLevel(c.attribute(attributeName(Attribute::Budget::BudgetLevel)))); + + if (c.hasAttribute(attributeName(Attribute::Budget::BudgetSubAccounts))) + account.setBudgetSubaccounts(c.attribute(attributeName(Attribute::Budget::BudgetSubAccounts)).toUInt()); + } + + QDomNode period = c.firstChild(); + while (!period.isNull() && period.isElement()) { + QDomElement per = period.toElement(); + MyMoneyBudget::PeriodGroup pGroup; + + if (elementName(Element::Budget::Period) == per.tagName() && per.hasAttribute(attributeName(Attribute::Budget::Amount)) && per.hasAttribute(attributeName(Attribute::Budget::Start))) { + pGroup.setAmount(MyMoneyMoney(per.attribute(attributeName(Attribute::Budget::Amount)))); + pGroup.setStartDate(QDate::fromString(per.attribute(attributeName(Attribute::Budget::Start)), Qt::ISODate)); + account.addPeriod(pGroup.startDate(), pGroup); + } + + period = period.nextSibling(); + } + budget.setAccount(account, account.id()); + + child = child.nextSibling(); + } + + + return budget; +} + +MyMoneySchedule MyMoneyXmlContentHandler::readSchedule(const QDomElement &node) +{ + if (nodeName(Node::ScheduleTX) != node.tagName()) + throw MYMONEYEXCEPTION_CSTRING("Node was not SCHEDULED_TX"); + + MyMoneySchedule schedule(node.attribute(attributeName(Attribute::Account::ID))); + + schedule.setName(node.attribute(attributeName(Attribute::Schedule::Name))); + schedule.setStartDate(MyMoneyUtils::stringToDate(node.attribute(attributeName(Attribute::Schedule::StartDate)))); + schedule.setEndDate(MyMoneyUtils::stringToDate(node.attribute(attributeName(Attribute::Schedule::EndDate)))); + schedule.setLastPayment(MyMoneyUtils::stringToDate(node.attribute(attributeName(Attribute::Schedule::LastPayment)))); + + schedule.setType(static_cast(node.attribute(attributeName(Attribute::Schedule::Type)).toInt())); + schedule.setPaymentType(static_cast(node.attribute(attributeName(Attribute::Schedule::PaymentType)).toInt())); + schedule.setOccurrence(static_cast(node.attribute(attributeName(Attribute::Schedule::Occurrence)).toInt())); + schedule.setOccurrenceMultiplier(node.attribute(attributeName(Attribute::Schedule::OccurrenceMultiplier), "1").toInt()); + schedule.setLastDayInMonth(static_cast(node.attribute("lastDayInMonth").toInt())); + schedule.setAutoEnter(static_cast(node.attribute(attributeName(Attribute::Schedule::AutoEnter)).toInt())); + schedule.setFixed(static_cast(node.attribute(attributeName(Attribute::Schedule::Fixed)).toInt())); + schedule.setWeekendOption(static_cast(node.attribute(attributeName(Attribute::Schedule::WeekendOption)).toInt())); + + // read in the associated transaction + QDomNodeList nodeList = node.elementsByTagName(nodeName(Node::Transaction)); + if (nodeList.count() == 0) + throw MYMONEYEXCEPTION_CSTRING("SCHEDULED_TX has no TRANSACTION node"); + + auto transaction = readTransaction(nodeList.item(0).toElement()); + + // some old versions did not remove the entry date and post date fields + // in the schedule. So if this is the case, we deal with a very old transaction + // and can't use the post date field as next due date. Hence, we wipe it out here + if (transaction.entryDate().isValid()) { + transaction.setPostDate(QDate()); + transaction.setEntryDate(QDate()); + } + schedule.setTransaction(transaction, true); + + // readin the recorded payments + nodeList = node.elementsByTagName(elementName(Element::Schedule::Payments)); + if (!nodeList.isEmpty()) { + nodeList = nodeList.item(0).toElement().elementsByTagName(elementName(Element::Schedule::Payment)); + for (int i = 0; i < nodeList.count(); ++i) { + schedule.recordPayment(MyMoneyUtils::stringToDate(nodeList.item(i).toElement().attribute(attributeName(Attribute::Schedule::Date)))); + } + } + + // if the next due date is not set (comes from old version) + // then set it up the old way + if (!schedule.nextDueDate().isValid() && !schedule.lastPayment().isValid()) { + auto t = schedule.transaction(); + t.setPostDate(schedule.startDate()); + schedule.setTransaction(t, true); + // clear it, because the schedule has never been used + schedule.setStartDate(QDate()); + } + + // There are reports that lastPayment and nextDueDate are identical or + // that nextDueDate is older than lastPayment. This could + // be caused by older versions of the application. In this case, we just + // clear out the nextDueDate and let it calculate from the lastPayment. + if (schedule.nextDueDate().isValid() && schedule.nextDueDate() <= schedule.lastPayment()) { + auto t = schedule.transaction(); + t.setPostDate(QDate()); + schedule.setTransaction(t, true); + } + + if (!schedule.nextDueDate().isValid()) { + auto t = schedule.transaction(); + t.setPostDate(schedule.startDate()); + schedule.setTransaction(t, true); + t = schedule.transaction(); + t.setPostDate(schedule.nextPayment(schedule.lastPayment().addDays(1))); + schedule.setTransaction(t, true); + } + + return schedule; +} + +onlineJob MyMoneyXmlContentHandler::readOnlineJob(const QDomElement &node) +{ + onlineJob oJob(node.attribute(attributeName(Attribute::Account::ID))); + + oJob.clearJobMessageList(); + oJob.setLock(false); + oJob.setJobSend(QDateTime::fromString(node.attribute(attributeName(Attribute::OnlineJob::Send)), Qt::ISODate)); + const auto state = node.attribute(attributeName(Attribute::OnlineJob::BankAnswerState)); + const auto date = QDateTime::fromString(node.attribute(attributeName(Attribute::OnlineJob::BankAnswerDate)), Qt::ISODate); + if (state == attributeName(Attribute::OnlineJob::AbortedByUser)) + oJob.setBankAnswer(eMyMoney::OnlineJob::sendingState::abortedByUser, date); + else if (state == attributeName(Attribute::OnlineJob::AcceptedByBank)) + oJob.setBankAnswer(eMyMoney::OnlineJob::sendingState::acceptedByBank, date); + else if (state == attributeName(Attribute::OnlineJob::RejectedByBank)) + oJob.setBankAnswer(eMyMoney::OnlineJob::sendingState::rejectedByBank, date); + else if (state == attributeName(Attribute::OnlineJob::SendingError)) + oJob.setBankAnswer(eMyMoney::OnlineJob::sendingState::sendingError, date); + else + oJob.setBankAnswer(eMyMoney::OnlineJob::sendingState::noBankAnswer); + + auto taskElem = node.firstChildElement(elementName(Element::OnlineJob::OnlineTask)); + oJob.setTask(onlineJobAdministration::instance()->createOnlineTaskByXml(taskElem.attribute(attributeName(Attribute::OnlineJob::IID)), taskElem)); + + return oJob; +} + +MyMoneyCostCenter MyMoneyXmlContentHandler::readCostCenter(const QDomElement &node) +{ + if (nodeName(Node::CostCenter) != node.tagName()) + throw MYMONEYEXCEPTION_CSTRING("Node was not COSTCENTER"); + + MyMoneyCostCenter costCenter(node.attribute(attributeName(Attribute::Account::ID))); + costCenter.setName(node.attribute(attributeName(Attribute::CostCenter::Name))); + return costCenter; +} @@ -522,74 +1205,74 @@ m_storage = storage; // qDebug("XMLWRITER: Starting file write"); - m_doc = new QDomDocument(tagNames[tnKMMFile]); + m_doc = new QDomDocument(tagName(Tag::KMMFile)); Q_CHECK_PTR(m_doc); QDomProcessingInstruction instruct = m_doc->createProcessingInstruction("xml", "version=\"1.0\" encoding=\"utf-8\""); m_doc->appendChild(instruct); - QDomElement mainElement = m_doc->createElement(tagNames[tnKMMFile]); + QDomElement mainElement = m_doc->createElement(tagName(Tag::KMMFile)); m_doc->appendChild(mainElement); - QDomElement fileInfo = m_doc->createElement(tagNames[tnFileInfo]); + QDomElement fileInfo = m_doc->createElement(tagName(Tag::FileInfo)); writeFileInformation(fileInfo); mainElement.appendChild(fileInfo); - QDomElement userInfo = m_doc->createElement(tagNames[tnUser]); + QDomElement userInfo = m_doc->createElement(tagName(Tag::User)); writeUserInformation(userInfo); mainElement.appendChild(userInfo); - QDomElement institutions = m_doc->createElement(tagNames[tnInstitutions]); + QDomElement institutions = m_doc->createElement(tagName(Tag::Institutions)); writeInstitutions(institutions); mainElement.appendChild(institutions); - QDomElement payees = m_doc->createElement(tagNames[tnPayees]); + QDomElement payees = m_doc->createElement(tagName(Tag::Payees)); writePayees(payees); mainElement.appendChild(payees); - QDomElement costCenters = m_doc->createElement(tagNames[tnCostCenters]); + QDomElement costCenters = m_doc->createElement(tagName(Tag::CostCenters)); writeCostCenters(costCenters); mainElement.appendChild(costCenters); - QDomElement tags = m_doc->createElement(tagNames[tnTags]); + QDomElement tags = m_doc->createElement(tagName(Tag::Tags)); writeTags(tags); mainElement.appendChild(tags); - QDomElement accounts = m_doc->createElement(tagNames[tnAccounts]); + QDomElement accounts = m_doc->createElement(tagName(Tag::Accounts)); writeAccounts(accounts); mainElement.appendChild(accounts); - QDomElement transactions = m_doc->createElement(tagNames[tnTransactions]); + QDomElement transactions = m_doc->createElement(tagName(Tag::Transactions)); writeTransactions(transactions); mainElement.appendChild(transactions); QDomElement keyvalpairs = writeKeyValuePairs(m_storage->pairs()); mainElement.appendChild(keyvalpairs); - QDomElement schedules = m_doc->createElement(tagNames[tnSchedules]); + QDomElement schedules = m_doc->createElement(tagName(Tag::Schedules)); writeSchedules(schedules); mainElement.appendChild(schedules); - QDomElement equities = m_doc->createElement(tagNames[tnSecurities]); + QDomElement equities = m_doc->createElement(tagName(Tag::Securities)); writeSecurities(equities); mainElement.appendChild(equities); - QDomElement currencies = m_doc->createElement(tagNames[tnCurrencies]); + QDomElement currencies = m_doc->createElement(tagName(Tag::Currencies)); writeCurrencies(currencies); mainElement.appendChild(currencies); - QDomElement prices = m_doc->createElement(tagNames[tnPrices]); + QDomElement prices = m_doc->createElement(tagName(Tag::Prices)); writePrices(prices); mainElement.appendChild(prices); - QDomElement reports = m_doc->createElement(tagNames[tnReports]); + QDomElement reports = m_doc->createElement(tagName(Tag::Reports)); writeReports(reports); mainElement.appendChild(reports); - QDomElement budgets = m_doc->createElement(tagNames[tnBudgets]); + QDomElement budgets = m_doc->createElement(tagName(Tag::Budgets)); writeBudgets(budgets); mainElement.appendChild(budgets); - QDomElement onlineJobs = m_doc->createElement(tagNames[tnOnlineJobs]); + QDomElement onlineJobs = m_doc->createElement(tagName(Tag::OnlineJobs)); writeOnlineJobs(onlineJobs); mainElement.appendChild(onlineJobs); @@ -614,32 +1297,32 @@ { signalProgress(0, 3, i18n("Loading file information...")); bool rc = true; - QDomElement temp = findChildElement(getElName(enCreationDate), fileInfo); + QDomElement temp = findChildElement(elementName(Element::General::CreationDate), fileInfo); if (temp == QDomElement()) { rc = false; } - QString strDate = MyMoneyUtils::QStringEmpty(temp.attribute(attrNames[anDate])); + QString strDate = MyMoneyUtils::QStringEmpty(temp.attribute(attributeName(Attribute::General::Date))); m_storage->setCreationDate(MyMoneyUtils::stringToDate(strDate)); signalProgress(1, 0); - temp = findChildElement(getElName(enLastModifiedDate), fileInfo); + temp = findChildElement(elementName(Element::General::LastModifiedDate), fileInfo); if (temp == QDomElement()) { rc = false; } - strDate = MyMoneyUtils::QStringEmpty(temp.attribute(attrNames[anDate])); + strDate = MyMoneyUtils::QStringEmpty(temp.attribute(attributeName(Attribute::General::Date))); m_storage->setLastModificationDate(MyMoneyUtils::stringToDate(strDate)); signalProgress(2, 0); - temp = findChildElement(getElName(enVersion), fileInfo); + temp = findChildElement(elementName(Element::General::Version), fileInfo); if (temp == QDomElement()) { rc = false; } - QString strVersion = MyMoneyUtils::QStringEmpty(temp.attribute(attrNames[anID])); + QString strVersion = MyMoneyUtils::QStringEmpty(temp.attribute(attributeName(Attribute::General::ID))); fileVersionRead = strVersion.toUInt(0, 16); - temp = findChildElement(getElName(enFixVersion), fileInfo); + temp = findChildElement(elementName(Element::General::FixVersion), fileInfo); if (temp != QDomElement()) { - QString strFixVersion = MyMoneyUtils::QStringEmpty(temp.attribute(attrNames[anID])); + QString strFixVersion = MyMoneyUtils::QStringEmpty(temp.attribute(attributeName(Attribute::General::ID))); m_storage->setFileFixVersion(strFixVersion.toUInt()); // skip KMyMoneyView::fixFile_2() if (m_storage->fileFixVersion() == 2) { @@ -657,36 +1340,36 @@ void MyMoneyStorageXML::writeFileInformation(QDomElement& fileInfo) { - QDomElement creationDate = m_doc->createElement(getElName(enCreationDate)); - creationDate.setAttribute(attrNames[anDate], MyMoneyUtils::dateToString(m_storage->creationDate())); + QDomElement creationDate = m_doc->createElement(elementName(Element::General::CreationDate)); + creationDate.setAttribute(attributeName(Attribute::General::Date), MyMoneyUtils::dateToString(m_storage->creationDate())); fileInfo.appendChild(creationDate); - QDomElement lastModifiedDate = m_doc->createElement(getElName(enLastModifiedDate)); - lastModifiedDate.setAttribute(attrNames[anDate], MyMoneyUtils::dateToString(m_storage->lastModificationDate())); + QDomElement lastModifiedDate = m_doc->createElement(elementName(Element::General::LastModifiedDate)); + lastModifiedDate.setAttribute(attributeName(Attribute::General::Date), MyMoneyUtils::dateToString(m_storage->lastModificationDate())); fileInfo.appendChild(lastModifiedDate); - QDomElement version = m_doc->createElement(getElName(enVersion)); + QDomElement version = m_doc->createElement(elementName(Element::General::Version)); - version.setAttribute(attrNames[anID], "1"); + version.setAttribute(attributeName(Attribute::General::ID), "1"); fileInfo.appendChild(version); - QDomElement fixVersion = m_doc->createElement(getElName(enFixVersion)); - fixVersion.setAttribute(attrNames[anID], m_storage->fileFixVersion()); + QDomElement fixVersion = m_doc->createElement(elementName(Element::General::FixVersion)); + fixVersion.setAttribute(attributeName(Attribute::General::ID), m_storage->fileFixVersion()); fileInfo.appendChild(fixVersion); } void MyMoneyStorageXML::writeUserInformation(QDomElement& userInfo) { MyMoneyPayee user = m_storage->user(); - userInfo.setAttribute(attrNames[anName], user.name()); - userInfo.setAttribute(attrNames[anEmail], user.email()); + userInfo.setAttribute(attributeName(Attribute::General::Name), user.name()); + userInfo.setAttribute(attributeName(Attribute::General::Email), user.email()); - QDomElement address = m_doc->createElement(getElName(enAddress)); - address.setAttribute(attrNames[anStreet], user.address()); - address.setAttribute(attrNames[anCity], user.city()); - address.setAttribute(attrNames[anCountry], user.state()); - address.setAttribute(attrNames[anZipCode], user.postcode()); - address.setAttribute(attrNames[anTelephone], user.telephone()); + QDomElement address = m_doc->createElement(elementName(Element::General::Address)); + address.setAttribute(attributeName(Attribute::General::Street), user.address()); + address.setAttribute(attributeName(Attribute::General::City), user.city()); + address.setAttribute(attributeName(Attribute::General::Country), user.state()); + address.setAttribute(attributeName(Attribute::General::ZipCode), user.postcode()); + address.setAttribute(attributeName(Attribute::General::Telephone), user.telephone()); userInfo.appendChild(address); } @@ -697,16 +1380,16 @@ signalProgress(0, 1, i18n("Loading user information...")); MyMoneyPayee user; - user.setName(MyMoneyUtils::QStringEmpty(userElement.attribute(attrNames[anName]))); - user.setEmail(MyMoneyUtils::QStringEmpty(userElement.attribute(attrNames[anEmail]))); + user.setName(MyMoneyUtils::QStringEmpty(userElement.attribute(attributeName(Attribute::General::Name)))); + user.setEmail(MyMoneyUtils::QStringEmpty(userElement.attribute(attributeName(Attribute::General::Email)))); - QDomElement addressNode = findChildElement(getElName(enAddress), userElement); + QDomElement addressNode = findChildElement(elementName(Element::General::Address), userElement); if (!addressNode.isNull()) { - user.setAddress(MyMoneyUtils::QStringEmpty(addressNode.attribute(attrNames[anStreet]))); - user.setCity(MyMoneyUtils::QStringEmpty(addressNode.attribute(attrNames[anCity]))); - user.setState(MyMoneyUtils::QStringEmpty(addressNode.attribute(attrNames[anCountry]))); - user.setPostcode(MyMoneyUtils::QStringEmpty(addressNode.attribute(attrNames[anZipCode]))); - user.setTelephone(MyMoneyUtils::QStringEmpty(addressNode.attribute(attrNames[anTelephone]))); + user.setAddress(MyMoneyUtils::QStringEmpty(addressNode.attribute(attributeName(Attribute::General::Street)))); + user.setCity(MyMoneyUtils::QStringEmpty(addressNode.attribute(attributeName(Attribute::General::City)))); + user.setState(MyMoneyUtils::QStringEmpty(addressNode.attribute(attributeName(Attribute::General::Country)))); + user.setPostcode(MyMoneyUtils::QStringEmpty(addressNode.attribute(attributeName(Attribute::General::ZipCode)))); + user.setTelephone(MyMoneyUtils::QStringEmpty(addressNode.attribute(attributeName(Attribute::General::Telephone)))); } m_storage->setUser(user); @@ -719,7 +1402,7 @@ { const QList list = m_storage->institutionList(); QList::ConstIterator it; - institutions.setAttribute(attrNames[anCount], list.count()); + institutions.setAttribute(attributeName(Attribute::General::Count), list.count()); for (it = list.begin(); it != list.end(); ++it) writeInstitution(institutions, *it); @@ -734,7 +1417,7 @@ { const QList list = m_storage->payeeList(); QList::ConstIterator it; - payees.setAttribute(attrNames[anCount], list.count()); + payees.setAttribute(attributeName(Attribute::General::Count), list.count()); for (it = list.begin(); it != list.end(); ++it) writePayee(payees, *it); @@ -749,7 +1432,7 @@ { const QList list = m_storage->tagList(); QList::ConstIterator it; - tags.setAttribute(attrNames[anCount], list.count()); + tags.setAttribute(attributeName(Attribute::General::Count), list.count()); for (it = list.begin(); it != list.end(); ++it) writeTag(tags, *it); @@ -765,7 +1448,7 @@ QList list; m_storage->accountList(list); QList::ConstIterator it; - accounts.setAttribute(attrNames[anCount], list.count() + 5); + accounts.setAttribute(attributeName(Attribute::General::Count), list.count() + 5); writeAccount(accounts, m_storage->asset()); writeAccount(accounts, m_storage->liability()); @@ -791,7 +1474,7 @@ MyMoneyTransactionFilter filter; filter.setReportAllSplits(false); const auto list = m_storage->transactionList(filter); - transactions.setAttribute(attrNames[anCount], list.count()); + transactions.setAttribute(attributeName(Attribute::General::Count), list.count()); QList::ConstIterator it; @@ -814,7 +1497,7 @@ const QList list = m_storage->scheduleList(QString(), eMyMoney::Schedule::Type::Any, eMyMoney::Schedule::Occurrence::Any, eMyMoney::Schedule::PaymentType::Any, QDate(), QDate(), false); QList::ConstIterator it; - scheduled.setAttribute(attrNames[anCount], list.count()); + scheduled.setAttribute(attributeName(Attribute::General::Count), list.count()); for (it = list.constBegin(); it != list.constEnd(); ++it) { this->writeSchedule(scheduled, *it); @@ -829,7 +1512,7 @@ void MyMoneyStorageXML::writeSecurities(QDomElement& equities) { const QList securityList = m_storage->securityList(); - equities.setAttribute(attrNames[anCount], securityList.count()); + equities.setAttribute(attributeName(Attribute::General::Count), securityList.count()); if (securityList.size()) { for (QList::ConstIterator it = securityList.constBegin(); it != securityList.constEnd(); ++it) { writeSecurity(equities, (*it)); @@ -845,7 +1528,7 @@ void MyMoneyStorageXML::writeCurrencies(QDomElement& currencies) { const QList currencyList = m_storage->currencyList(); - currencies.setAttribute(attrNames[anCount], currencyList.count()); + currencies.setAttribute(attributeName(Attribute::General::Count), currencyList.count()); if (currencyList.size()) { for (QList::ConstIterator it = currencyList.constBegin(); it != currencyList.constEnd(); ++it) { writeSecurity(currencies, (*it)); @@ -857,7 +1540,7 @@ { const QList list = m_storage->reportList(); QList::ConstIterator it; - parent.setAttribute(attrNames[anCount], list.count()); + parent.setAttribute(attributeName(Attribute::General::Count), list.count()); signalProgress(0, list.count(), i18n("Saving reports...")); unsigned i = 0; @@ -876,7 +1559,7 @@ { const QList list = m_storage->budgetList(); QList::ConstIterator it; - parent.setAttribute(attrNames[anCount], list.count()); + parent.setAttribute(attributeName(Attribute::General::Count), list.count()); signalProgress(0, list.count(), i18n("Saving budgets...")); unsigned i = 0; @@ -894,7 +1577,7 @@ void MyMoneyStorageXML::writeOnlineJobs(QDomElement& parent) { const QList list = m_storage->onlineJobList(); - parent.setAttribute(attrNames[anCount], list.count()); + parent.setAttribute(attributeName(Attribute::General::Count), list.count()); signalProgress(0, list.count(), i18n("Saving online banking orders...")); unsigned i = 0; QList::ConstIterator end = list.constEnd(); @@ -912,7 +1595,7 @@ void MyMoneyStorageXML::writeCostCenters(QDomElement& parent) { const QList list = m_storage->costCenterList(); - parent.setAttribute(attrNames[anCount], list.count()); + parent.setAttribute(attributeName(Attribute::General::Count), list.count()); signalProgress(0, list.count(), i18n("Saving costcenters...")); unsigned i = 0; Q_FOREACH(MyMoneyCostCenter costCenter, list) { @@ -945,13 +1628,13 @@ QDomElement MyMoneyStorageXML::writeKeyValuePairs(const QMap pairs) { if (m_doc) { - QDomElement keyValPairs = m_doc->createElement(nodeNames[nnKeyValuePairs]); + QDomElement keyValPairs = m_doc->createElement(nodeName(Node::KeyValuePairs)); QMap::const_iterator it; for (it = pairs.constBegin(); it != pairs.constEnd(); ++it) { - QDomElement pair = m_doc->createElement(getElName(enPair)); - pair.setAttribute(attrNames[anKey], it.key()); - pair.setAttribute(attrNames[anValue], it.value()); + QDomElement pair = m_doc->createElement(elementName(Element::General::Pair)); + pair.setAttribute(attributeName(Attribute::General::Key), it.key()); + pair.setAttribute(attributeName(Attribute::General::Value), it.value()); keyValPairs.appendChild(pair); } return keyValPairs; @@ -963,12 +1646,12 @@ { const MyMoneyPriceList list = m_storage->priceList(); MyMoneyPriceList::ConstIterator it; - prices.setAttribute(attrNames[anCount], list.count()); + prices.setAttribute(attributeName(Attribute::General::Count), list.count()); for (it = list.constBegin(); it != list.constEnd(); ++it) { - QDomElement price = m_doc->createElement(nodeNames[nnPricePair]); - price.setAttribute(attrNames[anFrom], it.key().first); - price.setAttribute(attrNames[anTo], it.key().second); + QDomElement price = m_doc->createElement(nodeName(Node::PricePair)); + price.setAttribute(attributeName(Attribute::General::From), it.key().first); + price.setAttribute(attributeName(Attribute::General::To), it.key().second); writePricePair(price, *it); prices.appendChild(price); } @@ -978,17 +1661,17 @@ { MyMoneyPriceEntries::ConstIterator it; for (it = p.constBegin(); it != p.constEnd(); ++it) { - QDomElement entry = m_doc->createElement(nodeNames[nnPrice]); + QDomElement entry = m_doc->createElement(nodeName(Node::Price)); writePrice(entry, *it); price.appendChild(entry); } } void MyMoneyStorageXML::writePrice(QDomElement& price, const MyMoneyPrice& p) { - price.setAttribute(attrNames[anDate], p.date().toString(Qt::ISODate)); - price.setAttribute(attrNames[anPrice], p.rate(QString()).toString()); - price.setAttribute(attrNames[anSource], p.source()); + price.setAttribute(attributeName(Attribute::General::Date), p.date().toString(Qt::ISODate)); + price.setAttribute(attributeName(Attribute::General::Price), p.rate(QString()).toString()); + price.setAttribute(attributeName(Attribute::General::Source), p.source()); } void MyMoneyStorageXML::setProgressCallback(void(*callback)(int, int, const QString&)) @@ -1053,16 +1736,3 @@ } } #endif - -const QString MyMoneyStorageXML::getElName(const elNameE _el) -{ - static const QHash elNames = { - {enAddress, QStringLiteral("ADDRESS")}, - {enCreationDate, QStringLiteral("CREATION_DATE")}, - {enLastModifiedDate, QStringLiteral("LAST_MODIFIED_DATE")}, - {enVersion, QStringLiteral("VERSION")}, - {enFixVersion, QStringLiteral("FIXVERSION")}, - {enPair, QStringLiteral("PAIR")} - }; - return elNames[_el]; -} diff --git a/kmymoney/plugins/xml/tests/CMakeLists.txt b/kmymoney/plugins/xml/tests/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/kmymoney/plugins/xml/tests/CMakeLists.txt @@ -0,0 +1,21 @@ +include(ECMAddTests) + +set(mymoneystoragexml_SOURCES + ../mymoneystoragexml.cpp + ../mymoneystoragenames.cpp + ) + +add_library(mymoneystoragexml STATIC ${mymoneystoragexml_SOURCES}) +target_link_libraries(mymoneystoragexml + PUBLIC + Qt5::Xml + KF5::I18n + kmm_mymoney +) + +file(GLOB tests_sources "*-test.cpp") +ecm_add_tests(${tests_sources} + LINK_LIBRARIES + Qt5::Test + mymoneystoragexml +) diff --git a/kmymoney/plugins/xml/tests/mymoneystoragenames-test.h b/kmymoney/plugins/xml/tests/mymoneystoragenames-test.h new file mode 100644 --- /dev/null +++ b/kmymoney/plugins/xml/tests/mymoneystoragenames-test.h @@ -0,0 +1,51 @@ +/* + * Copyright 2018 Łukasz Wojniłowicz + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef MYMONEYSTORAGENAMESTEST_H +#define MYMONEYSTORAGENAMESTEST_H + +#include + +class MyMoneyStorageNamesTest : public QObject +{ + Q_OBJECT + +private Q_SLOTS: + void keyValuePairElementNames(); + void keyValuePairAttributeNames(); + void transactionElementNames(); + void transactionAttributeNames(); + void accountElementNames(); + void accountAttributeNames(); + void payeeElementNames(); + void payeeAttributeNames(); + void tagAttributeNames(); + void securityAttributeNames(); + void institutionElementNames(); + void institutionAttributeNames(); + void reportElementNames(); + void reportAttributeNames(); + void budgetElementNames(); + void budgetAttributeNames(); + void scheduleElementNames(); + void scheduleAttributeNames(); + void onlineJobElementNames(); + void onlineJobAttributeNames(); + +}; + +#endif diff --git a/kmymoney/plugins/xml/tests/mymoneystoragenames-test.cpp b/kmymoney/plugins/xml/tests/mymoneystoragenames-test.cpp new file mode 100644 --- /dev/null +++ b/kmymoney/plugins/xml/tests/mymoneystoragenames-test.cpp @@ -0,0 +1,224 @@ +/* + * Copyright 2018 Łukasz Wojniłowicz + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "mymoneystoragenames-test.h" + +#include +#include "../mymoneystoragenames.cpp" + +QTEST_GUILESS_MAIN(MyMoneyStorageNamesTest) + +void MyMoneyStorageNamesTest::keyValuePairElementNames() +{ + for (auto i = (int)Element::KVP::Pair; i <= (int)Element::KVP::Pair; ++i) { + auto isEmpty = elementName(static_cast(i)).isEmpty(); + if (isEmpty) + qWarning() << "Empty element's name " << i; + QVERIFY(!isEmpty); + } +} + +void MyMoneyStorageNamesTest::keyValuePairAttributeNames() +{ + for (auto i = (int)Attribute::KVP::Key; i < (int)Attribute::KVP::LastAttribute; ++i) { + auto isEmpty = attributeName(static_cast(i)).isEmpty(); + if (isEmpty) + qWarning() << "Empty attribute's name " << i; + QVERIFY(!isEmpty); + } +} + +void MyMoneyStorageNamesTest::transactionElementNames() +{ + for (auto i = (int)Element::Transaction::Split; i <= (int)Element::Transaction::Splits; ++i) { + auto isEmpty = elementName(static_cast(i)).isEmpty(); + if (isEmpty) + qWarning() << "Empty element's name " << i; + QVERIFY(!isEmpty); + } +} + +void MyMoneyStorageNamesTest::transactionAttributeNames() +{ + for (auto i = (int)Attribute::Transaction::Name; i < (int)Attribute::Transaction::LastAttribute; ++i) { + auto isEmpty = attributeName(static_cast(i)).isEmpty(); + if (isEmpty) + qWarning() << "Empty attribute's name " << i; + QVERIFY(!isEmpty); + } +} + +void MyMoneyStorageNamesTest::accountElementNames() +{ + for (auto i = (int)Element::Account::SubAccount; i <= (int)Element::Account::OnlineBanking; ++i) { + auto isEmpty = elementName(static_cast(i)).isEmpty(); + if (isEmpty) + qWarning() << "Empty element's name " << i; + QVERIFY(!isEmpty); + } +} + +void MyMoneyStorageNamesTest::accountAttributeNames() +{ + for (auto i = (int)Attribute::Account::ID; i < (int)Attribute::Account::LastAttribute; ++i) { + auto isEmpty = attributeName(static_cast(i)).isEmpty(); + if (isEmpty) + qWarning() << "Empty attribute's name " << i; + QVERIFY(!isEmpty); + } +} + +void MyMoneyStorageNamesTest::payeeElementNames() +{ + for (auto i = (int)Element::Payee::Address; i <= (int)Element::Payee::Address; ++i) { + auto isEmpty = elementName(static_cast(i)).isEmpty(); + if (isEmpty) + qWarning() << "Empty element's name " << i; + QVERIFY(!isEmpty); + } +} + +void MyMoneyStorageNamesTest::payeeAttributeNames() +{ + for (auto i = (int)Attribute::Payee::Name; i < (int)Attribute::Payee::LastAttribute; ++i) { + auto isEmpty = attributeName(static_cast(i)).isEmpty(); + if (isEmpty) + qWarning() << "Empty attribute's name " << i; + QVERIFY(!isEmpty); + } +} + +void MyMoneyStorageNamesTest::tagAttributeNames() +{ + for (auto i = (int)Attribute::Tag::Name; i < (int)Attribute::Tag::LastAttribute; ++i) { + auto isEmpty = attributeName(static_cast(i)).isEmpty(); + if (isEmpty) + qWarning() << "Empty attribute's name " << i; + QVERIFY(!isEmpty); + } +} + +void MyMoneyStorageNamesTest::securityAttributeNames() +{ + for (auto i = (int)Attribute::Security::Name; i < (int)Attribute::Security::LastAttribute; ++i) { + auto isEmpty = attributeName(static_cast(i)).isEmpty(); + if (isEmpty) + qWarning() << "Empty attribute's name " << i; + QVERIFY(!isEmpty); + } +} + +void MyMoneyStorageNamesTest::institutionElementNames() +{ + for (auto i = (int)Element::Institution::AccountID; i <= (int)Element::Institution::Address; ++i) { + auto isEmpty = elementName(static_cast(i)).isEmpty(); + if (isEmpty) + qWarning() << "Empty element's name " << i; + QVERIFY(!isEmpty); + } + +} + +void MyMoneyStorageNamesTest::institutionAttributeNames() +{ + for (auto i = (int)Attribute::Institution::ID; i < (int)Attribute::Institution::LastAttribute; ++i) { + auto isEmpty = attributeName(static_cast(i)).isEmpty(); + if (isEmpty) + qWarning() << "Empty attribute's name " << i; + QVERIFY(!isEmpty); + } +} + +void MyMoneyStorageNamesTest::reportElementNames() +{ + for (auto i = (int)Element::Report::Payee; i <= (int)Element::Report::AccountGroup; ++i) { + auto isEmpty = elementName(static_cast(i)).isEmpty(); + if (isEmpty) + qWarning() << "Empty element's name " << i; + QVERIFY(!isEmpty); + } +} + +void MyMoneyStorageNamesTest::reportAttributeNames() +{ + for (auto i = (int)Attribute::Report::ID; i < (int)Attribute::Report::LastAttribute; ++i) { + auto isEmpty = attributeName(static_cast(i)).isEmpty(); + if (isEmpty) + qWarning() << "Empty attribute's name " << i; + QVERIFY(!isEmpty); + } +} + +void MyMoneyStorageNamesTest::budgetElementNames() +{ + for (auto i = (int)Element::Budget::Budget; i <= (int)Element::Budget::Period; ++i) { + auto isEmpty = elementName(static_cast(i)).isEmpty(); + if (isEmpty) + qWarning() << "Empty element's name " << i; + QVERIFY(!isEmpty); + } +} + +void MyMoneyStorageNamesTest::budgetAttributeNames() +{ + for (auto i = (int)Attribute::Budget::ID; i < (int)Attribute::Budget::LastAttribute; ++i) { + auto isEmpty = attributeName(static_cast(i)).isEmpty(); + if (isEmpty) + qWarning() << "Empty attribute's name " << i; + QVERIFY(!isEmpty); + } +} + +void MyMoneyStorageNamesTest::scheduleElementNames() +{ + for (auto i = (int)Element::Schedule::Payment; i <= (int)Element::Schedule::Payments; ++i) { + auto isEmpty = elementName(static_cast(i)).isEmpty(); + if (isEmpty) + qWarning() << "Empty element's name " << i; + QVERIFY(!isEmpty); + } +} + +void MyMoneyStorageNamesTest::scheduleAttributeNames() +{ + for (auto i = (int)Attribute::Schedule::Name; i < (int)Attribute::Schedule::LastAttribute; ++i) { + auto isEmpty = attributeName(static_cast(i)).isEmpty(); + if (isEmpty) + qWarning() << "Empty attribute's name " << i; + QVERIFY(!isEmpty); + } +} + +void MyMoneyStorageNamesTest::onlineJobElementNames() +{ + for (auto i = (int)Element::OnlineJob::OnlineTask; i <= (int)Element::OnlineJob::OnlineTask; ++i) { + auto isEmpty = elementName(static_cast(i)).isEmpty(); + if (isEmpty) + qWarning() << "Empty element's name " << i; + QVERIFY(!isEmpty); + } +} + +void MyMoneyStorageNamesTest::onlineJobAttributeNames() +{ + for (auto i = (int)Attribute::OnlineJob::Send; i < (int)Attribute::OnlineJob::LastAttribute; ++i) { + auto isEmpty = attributeName(static_cast(i)).isEmpty(); + if (isEmpty) + qWarning() << "Empty attribute's name " << i; + QVERIFY(!isEmpty); + } +} diff --git a/kmymoney/mymoney/tests/mymoneyschedule-test.h b/kmymoney/plugins/xml/tests/mymoneyxmlcontenthandler-test.h copy from kmymoney/mymoney/tests/mymoneyschedule-test.h copy to kmymoney/plugins/xml/tests/mymoneyxmlcontenthandler-test.h --- a/kmymoney/mymoney/tests/mymoneyschedule-test.h +++ b/kmymoney/plugins/xml/tests/mymoneyxmlcontenthandler-test.h @@ -1,6 +1,12 @@ /* + * Copyright 2002-2017 Thomas Baumgart * Copyright 2003 Michael Edwardes - * Copyright 2006 Ace Jones + * Copyright 2004-2006 Ace Jones + * Copyright 2004 Kevin Tambascio + * Copyright 2009-2014 Cristian Oneț + * Copyright 2012 Alessandro Russo + * Copyright 2016 Christian Dávid + * Copyright 2018 Łukasz Wojniłowicz * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -16,45 +22,37 @@ * along with this program. If not, see . */ -#ifndef MYMONEYSCHEDULETEST_H -#define MYMONEYSCHEDULETEST_H +#ifndef MYMONEYXMLCONTENTHANDLERTEST_H +#define MYMONEYXMLCONTENTHANDLERTEST_H #include -class MyMoneyScheduleTest : public QObject +class MyMoneyXmlContentHandlerTest : public QObject { Q_OBJECT private Q_SLOTS: - void testEmptyConstructor(); - void testConstructor(); - void testSetFunctions(); - void testCopyConstructor(); - void testAssignmentConstructor(); + void readKeyValueContainer(); + void writeKeyValueContainer(); + void readTransaction(); + void readTransactionEx(); + void writeTransaction(); + void readAccount(); + void writeAccount(); + void readWritePayee(); + void readWriteTag(); + void readInstitution(); + void writeInstitution(); + void readSchedule(); + void writeSchedule(); void testOverdue(); void testNextPayment(); - void testAddHalfMonths(); + void testNextPaymentOnLastDayOfMonth(); void testPaymentDates(); - void testWriteXML(); - void testReadXML(); void testHasReferenceTo(); - void testAdjustedNextDueDate(); - void testModifyNextDueDate(); - void testDaysBetweenEvents(); - void testEventsPerYear(); - void testOccurrenceToString(); - void testOccurrencePeriodToString(); - void testOccurrencePeriod(); - void testSimpleToFromCompoundOccurrence(); - void testProcessingDates(); void testPaidEarlyOneTime(); - void testAdjustedNextPayment(); void testReplaceId(); - void testAdjustedWhenItWillEnd(); - void testProcessLastDayInMonth(); - void testNextPaymentOnLastDayOfMonth(); - void testElementNames(); - void testAttributeNames(); + }; #endif diff --git a/kmymoney/plugins/xml/tests/mymoneyxmlcontenthandler-test.cpp b/kmymoney/plugins/xml/tests/mymoneyxmlcontenthandler-test.cpp new file mode 100644 --- /dev/null +++ b/kmymoney/plugins/xml/tests/mymoneyxmlcontenthandler-test.cpp @@ -0,0 +1,1500 @@ +/* + * Copyright 2002-2017 Thomas Baumgart + * Copyright 2003 Michael Edwardes + * Copyright 2004-2006 Ace Jones + * Copyright 2004 Kevin Tambascio + * Copyright 2009-2014 Cristian Oneț + * Copyright 2012 Alessandro Russo + * Copyright 2016 Christian Dávid + * Copyright 2018 Łukasz Wojniłowicz + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "mymoneyxmlcontenthandler-test.h" + +#include +#include "../mymoneystoragexml.cpp" + +QTEST_GUILESS_MAIN(MyMoneyXmlContentHandlerTest) + +void MyMoneyXmlContentHandlerTest::readKeyValueContainer() +{ + MyMoneyKeyValueContainer kvp; + kvp.setValue("Key", "Value"); + kvp.setValue("key", "value"); + + QString ref_ok( + "\n" + "\n" + " \n" + " \n" + " \n" + " \n" + "\n"); + + QString ref_false( + "\n" + "\n" + " \n" + " \n" + " \n" + " \n" + "\n"); + + + QDomDocument doc; + QDomElement node; + doc.setContent(ref_false); + node = doc.documentElement().firstChild().toElement(); + + // make sure, an empty node does not trigger an exception + try { + QDomElement e; + MyMoneyKeyValueContainer k; + MyMoneyXmlContentHandler::addToKeyValueContainer(k, e); + } catch (const MyMoneyException &) { + QFAIL("Unexpected exception"); + } + + try { + MyMoneyKeyValueContainer k; + MyMoneyXmlContentHandler::addToKeyValueContainer(k, node); + QFAIL("Missing expected exception"); + } catch (const MyMoneyException &) { + } + + doc.setContent(ref_ok); + node = doc.documentElement().firstChild().toElement(); + try { + MyMoneyKeyValueContainer k; + MyMoneyXmlContentHandler::addToKeyValueContainer(k, node); +// QVERIFY(k.d_func()->m_kvp.count() == 2); to be enabled soon + QVERIFY(k.value("key") == "Value"); + QVERIFY(k.value("Key") == "value"); + } catch (const MyMoneyException &) { + QFAIL("Unexpected exception"); + } +} + +void MyMoneyXmlContentHandlerTest::writeKeyValueContainer() +{ + MyMoneyKeyValueContainer kvp; + kvp.setValue("Key", "Value"); + kvp.setValue("key", "value"); + + QDomDocument doc("TEST"); + QDomElement el = doc.createElement("KVP-CONTAINER"); + doc.appendChild(el); + kvp.writeXML(doc, el); + + QCOMPARE(doc.doctype().name(), QLatin1String("TEST")); + QDomElement kvpContainer = doc.documentElement(); + QCOMPARE(kvpContainer.tagName(), QLatin1String("KVP-CONTAINER")); + QCOMPARE(kvpContainer.childNodes().size(), 1); + + QVERIFY(kvpContainer.childNodes().at(0).isElement()); + QDomElement keyValuePairs = kvpContainer.childNodes().at(0).toElement(); + QCOMPARE(keyValuePairs.tagName(), QLatin1String("KEYVALUEPAIRS")); + QCOMPARE(keyValuePairs.childNodes().size(), 2); + + QVERIFY(keyValuePairs.childNodes().at(0).isElement()); + QDomElement keyValuePair1 = keyValuePairs.childNodes().at(0).toElement(); + QCOMPARE(keyValuePair1.tagName(), QLatin1String("PAIR")); + QCOMPARE(keyValuePair1.attribute("key"), QLatin1String("Key")); + QCOMPARE(keyValuePair1.attribute("value"), QLatin1String("Value")); + QCOMPARE(keyValuePair1.childNodes().size(), 0); + + QVERIFY(keyValuePairs.childNodes().at(1).isElement()); + QDomElement keyValuePair2 = keyValuePairs.childNodes().at(1).toElement(); + QCOMPARE(keyValuePair2.tagName(), QLatin1String("PAIR")); + QCOMPARE(keyValuePair2.attribute("key"), QLatin1String("key")); + QCOMPARE(keyValuePair2.attribute("value"), QLatin1String("value")); + QCOMPARE(keyValuePair2.childNodes().size(), 0); +} + +void MyMoneyXmlContentHandlerTest::readTransaction() +{ + MyMoneyTransaction t; + + QString ref_ok = QString( + "\n" + "\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "\n" + ); + + QString ref_false = QString( + "\n" + "\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "\n" + ); + + QDomDocument doc; + QDomElement node; + doc.setContent(ref_false); + node = doc.documentElement().firstChild().toElement(); + + try { + t = MyMoneyXmlContentHandler::readTransaction(node); + QFAIL("Missing expected exception"); + } catch (const MyMoneyException &) { + } + + doc.setContent(ref_ok); + node = doc.documentElement().firstChild().toElement(); + + t.setValue("key", "VALUE"); + try { + t = MyMoneyXmlContentHandler::readTransaction(node); + QVERIFY(t.postDate() == QDate(2001, 12, 28)); + QVERIFY(t.entryDate() == QDate(2003, 9, 29)); + QVERIFY(t.id() == "T000000000000000001"); + QVERIFY(t.memo() == "Wohnung:Miete"); + QVERIFY(t.commodity() == "EUR"); + QVERIFY(t.pairs().count() == 1); + QVERIFY(t.value("key") == "value"); + QVERIFY(t.splits().count() == 1); + } catch (const MyMoneyException &) { + QFAIL("Unexpected exception"); + } +} + +void MyMoneyXmlContentHandlerTest::readTransactionEx() +{ + MyMoneyTransaction t; + + QString ref_ok = QString( + "\n" + "\n" + "\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " &lt;CONTAINER>\n" + " &lt;TRANSACTION postdate="2010-03-05" memo="UMBUCHUNG" id="" commodity="EUR" entrydate="2010-03-08" >\n" + " &lt;SPLITS>\n" + " &lt;SPLIT payee="P000010" reconciledate="" shares="125000/100" action="Transfer" bankid="" number="" reconcileflag="0" memo="UMBUCHUNG" value="125000/100" id="S0001" account="A000087" />\n" + " &lt;SPLIT payee="P000010" reconciledate="" shares="-125000/100" action="" bankid="A000076-2010-03-05-b6850c0-1" number="" reconcileflag="0" memo="UMBUCHUNG" value="-125000/100" id="S0002" account="A000076" />\n" + " &lt;/SPLITS>\n" + " &lt;KEYVALUEPAIRS>\n" + " &lt;PAIR key="Imported" value="true" />\n" + " &lt;/KEYVALUEPAIRS>\n" + " &lt;/TRANSACTION>\n" + " &lt;/CONTAINER>\n" + "\" />\n" + " \n" + " \n" + " \n" + " \n" + " \n" + "\n" + "\n" + ); + QDomDocument doc; + QDomElement node; + doc.setContent(ref_ok); + node = doc.documentElement().firstChild().toElement(); + + try { + t = MyMoneyXmlContentHandler::readTransaction(node); + QVERIFY(t.pairs().count() == 0); + QVERIFY(t.splits().size() == 2); + QVERIFY(t.splits()[0].pairs().count() == 3); + QVERIFY(t.splits()[1].pairs().count() == 0); + QVERIFY(t.splits()[0].isMatched()); + + MyMoneyTransaction ti = t.splits()[0].matchedTransaction(); + QVERIFY(ti.pairs().count() == 1); + QVERIFY(ti.isImported()); + QVERIFY(ti.splits().count() == 2); + } catch (const MyMoneyException &) { + QFAIL("Unexpected exception"); + } +} + +void MyMoneyXmlContentHandlerTest::writeTransaction() +{ + MyMoneyTransaction t("T000000000000000001"); + t.setPostDate(QDate(2001, 12, 28)); + t.setEntryDate(QDate(2003, 9, 29)); + t.setMemo("Wohnung:Miete"); + t.setCommodity("EUR"); + t.setValue("key", "value"); + + MyMoneySplit s; + s.setPayeeId("P000001"); + QList tagIdList; + tagIdList << "G000001"; + s.setTagIdList(tagIdList); + s.setShares(MyMoneyMoney(96379, 100)); + s.setValue(MyMoneyMoney(96379, 100)); + s.setAction(MyMoneySplit::actionName(eMyMoney::Split::Action::Withdrawal)); + s.setAccountId("A000076"); + s.setReconcileFlag(eMyMoney::Split::State::Reconciled); + s.setBankID("SPID"); + t.addSplit(s); + + QDomDocument doc("TEST"); + QDomElement el = doc.createElement("TRANSACTION-CONTAINER"); + doc.appendChild(el); + t.writeXML(doc, el); + + QCOMPARE(doc.doctype().name(), QLatin1String("TEST")); + QDomElement transactionContainer = doc.documentElement(); + QVERIFY(transactionContainer.isElement()); + QCOMPARE(transactionContainer.tagName(), QLatin1String("TRANSACTION-CONTAINER")); + QVERIFY(transactionContainer.childNodes().size() == 1); + QVERIFY(transactionContainer.childNodes().at(0).isElement()); + + QDomElement transaction = transactionContainer.childNodes().at(0).toElement(); + QCOMPARE(transaction.tagName(), QLatin1String("TRANSACTION")); + QCOMPARE(transaction.attribute("id"), QLatin1String("T000000000000000001")); + QCOMPARE(transaction.attribute("postdate"), QLatin1String("2001-12-28")); + QCOMPARE(transaction.attribute("commodity"), QLatin1String("EUR")); + QCOMPARE(transaction.attribute("memo"), QLatin1String("Wohnung:Miete")); + QCOMPARE(transaction.attribute("entrydate"), QLatin1String("2003-09-29")); + QCOMPARE(transaction.childNodes().size(), 2); + + QVERIFY(transaction.childNodes().at(0).isElement()); + QDomElement splits = transaction.childNodes().at(0).toElement(); + QCOMPARE(splits.tagName(), QLatin1String("SPLITS")); + QCOMPARE(splits.childNodes().size(), 1); + QVERIFY(splits.childNodes().at(0).isElement()); + QDomElement split = splits.childNodes().at(0).toElement(); + QCOMPARE(split.tagName(), QLatin1String("SPLIT")); + QCOMPARE(split.attribute("id"), QLatin1String("S0001")); + QCOMPARE(split.attribute("payee"), QLatin1String("P000001")); + QCOMPARE(split.attribute("reconcileflag"), QLatin1String("2")); + QCOMPARE(split.attribute("shares"), QLatin1String("96379/100")); + QCOMPARE(split.attribute("reconciledate"), QString()); + QCOMPARE(split.attribute("action"), QLatin1String("Withdrawal")); + QCOMPARE(split.attribute("bankid"), QLatin1String("SPID")); + QCOMPARE(split.attribute("account"), QLatin1String("A000076")); + QCOMPARE(split.attribute("number"), QString()); + QCOMPARE(split.attribute("value"), QLatin1String("96379/100")); + QCOMPARE(split.attribute("memo"), QString()); + QCOMPARE(split.childNodes().size(), 1); + + QVERIFY(split.childNodes().at(0).isElement()); + QDomElement tag = split.childNodes().at(0).toElement(); + QCOMPARE(tag.tagName(), QLatin1String("TAG")); + QCOMPARE(tag.attribute("id"), QLatin1String("G000001")); + QCOMPARE(tag.childNodes().size(), 0); + + QDomElement keyValuePairs = transaction.childNodes().at(1).toElement(); + QCOMPARE(keyValuePairs.tagName(), QLatin1String("KEYVALUEPAIRS")); + QCOMPARE(keyValuePairs.childNodes().size(), 1); + + QVERIFY(keyValuePairs.childNodes().at(0).isElement()); + QDomElement keyValuePair1 = keyValuePairs.childNodes().at(0).toElement(); + QCOMPARE(keyValuePair1.tagName(), QLatin1String("PAIR")); + QCOMPARE(keyValuePair1.attribute("key"), QLatin1String("key")); + QCOMPARE(keyValuePair1.attribute("value"), QLatin1String("value")); + QCOMPARE(keyValuePair1.childNodes().size(), 0); +} + +void MyMoneyXmlContentHandlerTest::readAccount() +{ + MyMoneyAccount a; + QString ref_ok = QString( + "\n" + "\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "\n"). + arg(QDate::currentDate().toString(Qt::ISODate)).arg(QDate::currentDate().toString(Qt::ISODate)); + + QString ref_false = QString( + "\n" + "\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "\n"). + arg(QDate::currentDate().toString(Qt::ISODate)).arg(QDate::currentDate().toString(Qt::ISODate)); + + QDomDocument doc; + QDomElement node; + doc.setContent(ref_false); + node = doc.documentElement().firstChild().toElement(); + + try { + a = MyMoneyXmlContentHandler::readAccount(node); + QFAIL("Missing expected exception"); + } catch (const MyMoneyException &) { + } + + doc.setContent(ref_ok); + node = doc.documentElement().firstChild().toElement(); + + a.addAccountId("TEST"); + a.setValue("KEY", "VALUE"); + + try { + a = MyMoneyXmlContentHandler::readAccount(node); + QVERIFY(a.id() == "A000001"); + QVERIFY(a.name() == "AccountName"); + QVERIFY(a.parentAccountId() == "Parent"); + QVERIFY(a.lastModified() == QDate::currentDate()); + QVERIFY(a.lastReconciliationDate() == QDate()); + QVERIFY(a.institutionId() == "B000001"); + QVERIFY(a.number() == "465500"); + QVERIFY(a.openingDate() == QDate::currentDate()); + QVERIFY(a.accountType() == eMyMoney::Account::Type::Asset); + QVERIFY(a.description() == "Desc"); + QVERIFY(a.accountList().count() == 2); + QVERIFY(a.accountList()[0] == "A000002"); + QVERIFY(a.accountList()[1] == "A000003"); + QVERIFY(a.pairs().count() == 4); + QVERIFY(a.value("key") == "value"); + QVERIFY(a.value("Key") == "Value"); + QVERIFY(a.value("lastStatementDate").isEmpty()); + QVERIFY(a.reconciliationHistory().count() == 2); + QVERIFY(a.reconciliationHistory()[QDate(2011, 1, 1)] == MyMoneyMoney(123, 100)); + QVERIFY(a.reconciliationHistory()[QDate(2011, 2, 1)] == MyMoneyMoney(456, 100)); + } catch (const MyMoneyException &) { + QFAIL("Unexpected exception"); + } +} + +void MyMoneyXmlContentHandlerTest::writeAccount() +{ + QString id = "A000001"; + QString institutionid = "B000001"; + QString parent = "Parent"; + + MyMoneyAccount r; + r.setAccountType(eMyMoney::Account::Type::Asset); + r.setOpeningDate(QDate::currentDate()); + r.setLastModified(QDate::currentDate()); + r.setDescription("Desc"); + r.setName("AccountName"); + r.setNumber("465500"); + r.setParentAccountId(parent); + r.setInstitutionId(institutionid); + r.setValue(QString("key"), "value"); + r.addAccountId("A000002"); + r.addReconciliation(QDate(2011, 1, 1), MyMoneyMoney(123, 100)); + r.addReconciliation(QDate(2011, 2, 1), MyMoneyMoney(456, 100)); + + QCOMPARE(r.pairs().count(), 2); + QCOMPARE(r.value("key"), QLatin1String("value")); + QCOMPARE(r.value("reconciliationHistory"), QLatin1String("2011-01-01:123/100;2011-02-01:114/25")); + + MyMoneyAccount a(id, r); + + QDomDocument doc("TEST"); + QDomElement el = doc.createElement("ACCOUNT-CONTAINER"); + doc.appendChild(el); + a.writeXML(doc, el); + + QCOMPARE(doc.doctype().name(), QLatin1String("TEST")); + QDomElement accountContainer = doc.documentElement(); + QVERIFY(accountContainer.isElement()); + QCOMPARE(accountContainer.tagName(), QLatin1String("ACCOUNT-CONTAINER")); + QVERIFY(accountContainer.childNodes().size() == 1); + QVERIFY(accountContainer.childNodes().at(0).isElement()); + + QDomElement account = accountContainer.childNodes().at(0).toElement(); + QCOMPARE(account.tagName(), QLatin1String("ACCOUNT")); + QCOMPARE(account.attribute("id"), QLatin1String("A000001")); + QCOMPARE(account.attribute("lastreconciled"), QString()); + QCOMPARE(account.attribute("institution"), QLatin1String("B000001")); + QCOMPARE(account.attribute("name"), QLatin1String("AccountName")); + QCOMPARE(account.attribute("number"), QLatin1String("465500")); + QCOMPARE(account.attribute("description"), QLatin1String("Desc")); + QCOMPARE(account.attribute("parentaccount"), QLatin1String("Parent")); + QCOMPARE(account.attribute("opened"), QDate::currentDate().toString(Qt::ISODate)); + QCOMPARE(account.attribute("type"), QLatin1String("9")); + QCOMPARE(account.attribute("lastmodified"), QDate::currentDate().toString(Qt::ISODate)); + QCOMPARE(account.attribute("id"), QLatin1String("A000001")); + QCOMPARE(account.childNodes().size(), 2); + + QVERIFY(account.childNodes().at(0).isElement()); + QDomElement subAccounts = account.childNodes().at(0).toElement(); + QCOMPARE(subAccounts.tagName(), QLatin1String("SUBACCOUNTS")); + QCOMPARE(subAccounts.childNodes().size(), 1); + QVERIFY(subAccounts.childNodes().at(0).isElement()); + QDomElement subAccount = subAccounts.childNodes().at(0).toElement(); + QCOMPARE(subAccount.tagName(), QLatin1String("SUBACCOUNT")); + QCOMPARE(subAccount.attribute("id"), QLatin1String("A000002")); + QCOMPARE(subAccount.childNodes().size(), 0); + + QDomElement keyValuePairs = account.childNodes().at(1).toElement(); + QCOMPARE(keyValuePairs.tagName(), QLatin1String("KEYVALUEPAIRS")); + QCOMPARE(keyValuePairs.childNodes().size(), 2); + + QVERIFY(keyValuePairs.childNodes().at(0).isElement()); + QDomElement keyValuePair1 = keyValuePairs.childNodes().at(0).toElement(); + QCOMPARE(keyValuePair1.tagName(), QLatin1String("PAIR")); + QCOMPARE(keyValuePair1.attribute("key"), QLatin1String("key")); + QCOMPARE(keyValuePair1.attribute("value"), QLatin1String("value")); + QCOMPARE(keyValuePair1.childNodes().size(), 0); + + QVERIFY(keyValuePairs.childNodes().at(1).isElement()); + QDomElement keyValuePair2 = keyValuePairs.childNodes().at(1).toElement(); + QCOMPARE(keyValuePair2.tagName(), QLatin1String("PAIR")); + QCOMPARE(keyValuePair2.attribute("key"), QLatin1String("reconciliationHistory")); + QCOMPARE(keyValuePair2.attribute("value"), QLatin1String("2011-01-01:123/100;2011-02-01:114/25")); + QCOMPARE(keyValuePair2.childNodes().size(), 0); +} + +void MyMoneyXmlContentHandlerTest::readWritePayee() +{ + QDomDocument doc; + QDomElement parent = doc.createElement("Test"); + doc.appendChild(parent); + MyMoneyPayee payee1("some random id"); //if the ID isn't set, w ethrow an exception + payee1.writeXML(doc, parent); + QString temp1 = "Account1"; + payee1.setDefaultAccountId(temp1); + payee1.writeXML(doc, parent); + QString temp2 = "Account2"; + payee1.setDefaultAccountId(temp2); + payee1.writeXML(doc, parent); + payee1.setDefaultAccountId(); + payee1.writeXML(doc, parent); + QDomElement el = parent.firstChild().toElement(); + QVERIFY(!el.isNull()); + auto payee2 = MyMoneyXmlContentHandler::readPayee(el); + QVERIFY(!payee2.defaultAccountEnabled()); + QVERIFY(payee2.defaultAccountId().isEmpty()); + el = el.nextSibling().toElement(); + QVERIFY(!el.isNull()); + auto payee3 = MyMoneyXmlContentHandler::readPayee(el); + QVERIFY(payee3.defaultAccountEnabled()); + QVERIFY(payee3.defaultAccountId() == temp1); + el = el.nextSibling().toElement(); + QVERIFY(!el.isNull()); + auto payee4 = MyMoneyXmlContentHandler::readPayee(el); + QVERIFY(payee4.defaultAccountEnabled()); + QVERIFY(payee4.defaultAccountId() == temp2); + el = el.nextSibling().toElement(); + QVERIFY(!el.isNull()); + auto payee5 = MyMoneyXmlContentHandler::readPayee(el); + QVERIFY(!payee5.defaultAccountEnabled()); + QVERIFY(payee5.defaultAccountId().isEmpty()); +} + +void MyMoneyXmlContentHandlerTest::readWriteTag() +{ + QDomDocument doc; + QDomElement parent = doc.createElement("Test"); + doc.appendChild(parent); + MyMoneyTag tag1("some random id"); //if the ID isn't set, w ethrow an exception + tag1.writeXML(doc, parent); + QDomElement el = parent.firstChild().toElement(); + QVERIFY(!el.isNull()); + auto tag2 = MyMoneyXmlContentHandler::readTag(el); +} + +void MyMoneyXmlContentHandlerTest::readInstitution() +{ + MyMoneyInstitution i; + QString ref_ok = QString( + "\n" + "\n" + " \n" + "
\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "\n"); + + QString ref_false = QString( + "\n" + "\n" + " \n" + "
\n" + " \n" + " \n" + " \n" + " \n" + " \n" + "\n"); + + QDomDocument doc; + QDomElement node; + + doc.setContent(ref_false); + node = doc.documentElement().firstChild().toElement(); + try { + i = MyMoneyXmlContentHandler::readInstitution(node); + QFAIL("Missing expected exception"); + } catch (const MyMoneyException &) { + } + + i.addAccountId("TEST"); + + doc.setContent(ref_ok); + node = doc.documentElement().firstChild().toElement(); + try { + QStringList alist; + alist << "A000001" << "A000003"; + i = MyMoneyXmlContentHandler::readInstitution(node); + + QVERIFY(i.sortcode() == "sortcode"); + QVERIFY(i.id() == "I00001"); + QVERIFY(i.manager() == "manager"); + QVERIFY(i.name() == "name"); + QVERIFY(i.street() == "street"); + QVERIFY(i.postcode() == "postcode"); + QVERIFY(i.city() == "town"); + QVERIFY(i.telephone() == "telephone"); + QVERIFY(i.accountList() == alist); + QVERIFY(i.value(QString("key")) == "value"); + + } catch (const MyMoneyException &) { + QFAIL("Unexpected exception"); + } +} + +void MyMoneyXmlContentHandlerTest::writeInstitution() +{ + MyMoneyInstitution n("name", "town", "street", "postcode", + "telephone", "manager", "sortcode");; + + n.addAccountId("A000001"); + n.addAccountId("A000003"); + n.setValue(QString("key"), "value"); + + QDomDocument doc("TEST"); + QDomElement el = doc.createElement("INSTITUTION-CONTAINER"); + doc.appendChild(el); + + MyMoneyInstitution i("I00001", n); + + i.writeXML(doc, el); + + QCOMPARE(doc.doctype().name(), QLatin1String("TEST")); + QDomElement institutionContainer = doc.documentElement(); + QVERIFY(institutionContainer.isElement()); + QCOMPARE(institutionContainer.tagName(), QLatin1String("INSTITUTION-CONTAINER")); + QVERIFY(institutionContainer.childNodes().size() == 1); + QVERIFY(institutionContainer.elementsByTagName("INSTITUTION").at(0).isElement()); + + QDomElement institution = institutionContainer.elementsByTagName("INSTITUTION").at(0).toElement(); + QCOMPARE(institution.tagName(), QLatin1String("INSTITUTION")); + QCOMPARE(institution.attribute("id"), QLatin1String("I00001")); + QCOMPARE(institution.attribute("manager"), QLatin1String("manager")); + QCOMPARE(institution.attribute("name"), QLatin1String("name")); + QCOMPARE(institution.attribute("sortcode"), QLatin1String("sortcode")); + QCOMPARE(institution.childNodes().size(), 3); + + QVERIFY(institution.childNodes().at(0).isElement()); + QDomElement address = institution.childNodes().at(0).toElement(); + QCOMPARE(address.tagName(), QLatin1String("ADDRESS")); + QCOMPARE(address.attribute("street"), QLatin1String("street")); + QCOMPARE(address.attribute("telephone"), QLatin1String("telephone")); + QCOMPARE(address.attribute("zip"), QLatin1String("postcode")); + QCOMPARE(address.attribute("city"), QLatin1String("town")); + QCOMPARE(address.childNodes().size(), 0); + + QVERIFY(institution.childNodes().at(1).isElement()); + QDomElement accountIds = institution.childNodes().at(1).toElement(); + QCOMPARE(accountIds.tagName(), QLatin1String("ACCOUNTIDS")); + QCOMPARE(accountIds.childNodes().size(), 2); + + QVERIFY(accountIds.childNodes().at(0).isElement()); + QDomElement account1 = accountIds.childNodes().at(0).toElement(); + QCOMPARE(account1.tagName(), QLatin1String("ACCOUNTID")); + QCOMPARE(account1.attribute("id"), QLatin1String("A000001")); + QCOMPARE(account1.childNodes().size(), 0); + + QVERIFY(accountIds.childNodes().at(1).isElement()); + QDomElement account2 = accountIds.childNodes().at(1).toElement(); + QCOMPARE(account2.tagName(), QLatin1String("ACCOUNTID")); + QCOMPARE(account2.attribute("id"), QLatin1String("A000003")); + QCOMPARE(account2.childNodes().size(), 0); + + QVERIFY(institution.childNodes().at(2).isElement()); + QDomElement keyValuePairs = institution.childNodes().at(2).toElement(); + QCOMPARE(keyValuePairs.tagName(), QLatin1String("KEYVALUEPAIRS")); + QCOMPARE(keyValuePairs.childNodes().size(), 1); + + QVERIFY(keyValuePairs.childNodes().at(0).isElement()); + QDomElement keyValuePair1 = keyValuePairs.childNodes().at(0).toElement(); + QCOMPARE(keyValuePair1.tagName(), QLatin1String("PAIR")); + QCOMPARE(keyValuePair1.attribute("key"), QLatin1String("key")); + QCOMPARE(keyValuePair1.attribute("value"), QLatin1String("value")); + QCOMPARE(keyValuePair1.childNodes().size(), 0); +} + +void MyMoneyXmlContentHandlerTest::readSchedule() +{ + MyMoneySchedule sch; + + QString ref_ok1 = QString( + "\n" + "\n" + " \n" // krazy:exclude=spelling + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "\n" + ).arg(QDate::currentDate().toString(Qt::ISODate)) + .arg(QDate::currentDate().toString(Qt::ISODate)) + .arg(QDate::currentDate().toString(Qt::ISODate)); + + // diff to ref_ok1 is that we now have an empty entrydate + // in the transaction parameters + QString ref_ok2 = QString( + "\n" + "\n" + " \n" // krazy:exclude=spelling + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "\n" + ).arg(QDate::currentDate().toString(Qt::ISODate)) + .arg(QDate::currentDate().toString(Qt::ISODate)) + .arg(QDate::currentDate().toString(Qt::ISODate)); + + QString ref_false = QString( + "\n" + "\n" + " \n" // krazy:exclude=spelling + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "\n" + ).arg(QDate::currentDate().toString(Qt::ISODate)) + .arg(QDate::currentDate().toString(Qt::ISODate)) + .arg(QDate::currentDate().toString(Qt::ISODate)); + + QDomDocument doc; + QDomElement node; + doc.setContent(ref_false); + node = doc.documentElement().firstChild().toElement(); + + try { + sch = MyMoneyXmlContentHandler::readSchedule(node); + QFAIL("Missing expected exception"); + } catch (const MyMoneyException &) { + } + + doc.setContent(ref_ok1); + node = doc.documentElement().firstChild().toElement(); + + + try { + sch = MyMoneyXmlContentHandler::readSchedule(node); + QCOMPARE(sch.id(), QLatin1String("SCH0002")); + QCOMPARE(sch.nextDueDate(), QDate::currentDate().addDays(7)); + QCOMPARE(sch.startDate(), QDate::currentDate()); + QCOMPARE(sch.endDate(), QDate()); + QCOMPARE(sch.autoEnter(), true); + QCOMPARE(sch.isFixed(), true); + QCOMPARE(sch.weekendOption(), Schedule::WeekendOption::MoveNothing); + QCOMPARE(sch.lastPayment(), QDate::currentDate()); + QCOMPARE(sch.paymentType(), Schedule::PaymentType::DirectDebit); + QCOMPARE(sch.type(), Schedule::Type::Bill); + QCOMPARE(sch.name(), QLatin1String("A Name")); + QCOMPARE(sch.occurrence(), Schedule::Occurrence::Weekly); + QCOMPARE(sch.occurrenceMultiplier(), 1); + QCOMPARE(sch.nextDueDate(), sch.lastPayment().addDays(7)); + QCOMPARE(sch.recordedPayments().count(), 1); + QCOMPARE(sch.recordedPayments()[0], QDate::currentDate()); + } catch (const MyMoneyException &) { + QFAIL("Unexpected exception"); + } + + doc.setContent(ref_ok2); + node = doc.documentElement().firstChild().toElement(); + + + try { + sch = MyMoneyXmlContentHandler::readSchedule(node); + QCOMPARE(sch.id(), QLatin1String("SCH0002")); + QCOMPARE(sch.nextDueDate(), QDate::currentDate().addDays(7)); + QCOMPARE(sch.startDate(), QDate::currentDate()); + QCOMPARE(sch.endDate(), QDate()); + QCOMPARE(sch.autoEnter(), true); + QCOMPARE(sch.isFixed(), true); + QCOMPARE(sch.weekendOption(), Schedule::WeekendOption::MoveNothing); + QCOMPARE(sch.lastPayment(), QDate::currentDate()); + QCOMPARE(sch.paymentType(), Schedule::PaymentType::DirectDebit); + QCOMPARE(sch.type(), Schedule::Type::Bill); + QCOMPARE(sch.name(), QLatin1String("A Name")); + QCOMPARE(sch.occurrence(), Schedule::Occurrence::Weekly); + QCOMPARE(sch.occurrenceMultiplier(), 1); + QCOMPARE(sch.nextDueDate(), sch.lastPayment().addDays(7)); + QCOMPARE(sch.recordedPayments().count(), 1); + QCOMPARE(sch.recordedPayments()[0], QDate::currentDate()); + } catch (const MyMoneyException &) { + QFAIL("Unexpected exception"); + } +} + +void MyMoneyXmlContentHandlerTest::writeSchedule() +{ + MyMoneySchedule tempSch("A Name", + Schedule::Type::Bill, + Schedule::Occurrence::Weekly, 123, + Schedule::PaymentType::DirectDebit, + QDate::currentDate(), + QDate(), + true, + true); + + MyMoneySchedule sch("SCH0001", tempSch); + sch.setLastPayment(QDate::currentDate()); + sch.recordPayment(QDate::currentDate()); + + MyMoneyTransaction t("T000000000000000001"); + t.setPostDate(QDate(2001, 12, 28)); + t.setEntryDate(QDate(2003, 9, 29)); + t.setMemo("Wohnung:Miete"); + t.setCommodity("EUR"); + t.setValue("key", "value"); + + MyMoneySplit s; + s.setPayeeId("P000001"); + s.setShares(MyMoneyMoney(96379, 100)); + s.setValue(MyMoneyMoney(96379, 100)); + s.setAccountId("A000076"); + s.setBankID("SPID1"); + s.setReconcileFlag(eMyMoney::Split::State::Reconciled); + t.addSplit(s); + + s.setPayeeId("P000001"); + s.setShares(MyMoneyMoney(-96379, 100)); + s.setValue(MyMoneyMoney(-96379, 100)); + s.setAccountId("A000276"); + s.setBankID("SPID2"); + s.setReconcileFlag(eMyMoney::Split::State::Cleared); + s.clearId(); + t.addSplit(s); + + sch.setTransaction(t); + + QDomDocument doc("TEST"); + QDomElement el = doc.createElement("SCHEDULE-CONTAINER"); + doc.appendChild(el); + sch.writeXML(doc, el); + + QCOMPARE(doc.doctype().name(), QLatin1String("TEST")); + QDomElement scheduleContainer = doc.documentElement(); + QVERIFY(scheduleContainer.isElement()); + QCOMPARE(scheduleContainer.tagName(), QLatin1String("SCHEDULE-CONTAINER")); + QCOMPARE(scheduleContainer.childNodes().size(), 1); + QVERIFY(scheduleContainer.childNodes().at(0).isElement()); + + QDomElement schedule = scheduleContainer.childNodes().at(0).toElement(); + QCOMPARE(schedule.tagName(), QLatin1String("SCHEDULED_TX")); + QCOMPARE(schedule.attribute("id"), QLatin1String("SCH0001")); + QCOMPARE(schedule.attribute("paymentType"), QLatin1String("1")); + QCOMPARE(schedule.attribute("autoEnter"), QLatin1String("1")); + QCOMPARE(schedule.attribute("occurenceMultiplier"), QLatin1String("123")); // krazy:exclude=spelling + QCOMPARE(schedule.attribute("startDate"), QDate::currentDate().toString(Qt::ISODate)); + QCOMPARE(schedule.attribute("lastPayment"), QDate::currentDate().toString(Qt::ISODate)); + QCOMPARE(schedule.attribute("occurenceMultiplier"), QLatin1String("123")); // krazy:exclude=spelling + QCOMPARE(schedule.attribute("occurence"), QLatin1String("4")); // krazy:exclude=spelling + QCOMPARE(schedule.attribute("type"), QLatin1String("1")); + QCOMPARE(schedule.attribute("name"), QLatin1String("A Name")); + QCOMPARE(schedule.attribute("fixed"), QLatin1String("1")); + QCOMPARE(schedule.attribute("endDate"), QString()); + QCOMPARE(schedule.childNodes().size(), 2); + + QVERIFY(schedule.childNodes().at(0).isElement()); + QDomElement payments = schedule.childNodes().at(0).toElement(); + + QVERIFY(schedule.childNodes().at(1).isElement()); + QDomElement transaction = schedule.childNodes().at(1).toElement(); + QCOMPARE(transaction.tagName(), QLatin1String("TRANSACTION")); + QCOMPARE(transaction.attribute("id"), QString()); + QCOMPARE(transaction.attribute("postdate"), QLatin1String("2001-12-28")); + QCOMPARE(transaction.attribute("commodity"), QLatin1String("EUR")); + QCOMPARE(transaction.attribute("memo"), QLatin1String("Wohnung:Miete")); + QCOMPARE(transaction.attribute("entrydate"), QLatin1String("2003-09-29")); + QCOMPARE(transaction.childNodes().size(), 2); + + QVERIFY(transaction.childNodes().at(0).isElement()); + QDomElement splits = transaction.childNodes().at(0).toElement(); + QCOMPARE(splits.tagName(), QLatin1String("SPLITS")); + QCOMPARE(splits.childNodes().size(), 2); + QVERIFY(splits.childNodes().at(0).isElement()); + QDomElement split1 = splits.childNodes().at(0).toElement(); + QCOMPARE(split1.tagName(), QLatin1String("SPLIT")); + QCOMPARE(split1.attribute("id"), QLatin1String("S0001")); + QCOMPARE(split1.attribute("payee"), QLatin1String("P000001")); + QCOMPARE(split1.attribute("reconcileflag"), QLatin1String("2")); + QCOMPARE(split1.attribute("shares"), QLatin1String("96379/100")); + QCOMPARE(split1.attribute("reconciledate"), QString()); + QCOMPARE(split1.attribute("action"), QString()); + QCOMPARE(split1.attribute("bankid"), QString()); + QCOMPARE(split1.attribute("account"), QLatin1String("A000076")); + QCOMPARE(split1.attribute("number"), QString()); + QCOMPARE(split1.attribute("value"), QLatin1String("96379/100")); + QCOMPARE(split1.attribute("memo"), QString()); + QCOMPARE(split1.childNodes().size(), 0); + + QVERIFY(splits.childNodes().at(1).isElement()); + QDomElement split2 = splits.childNodes().at(1).toElement(); + QCOMPARE(split2.tagName(), QLatin1String("SPLIT")); + QCOMPARE(split2.attribute("id"), QLatin1String("S0002")); + QCOMPARE(split2.attribute("payee"), QLatin1String("P000001")); + QCOMPARE(split2.attribute("reconcileflag"), QLatin1String("1")); + QCOMPARE(split2.attribute("shares"), QLatin1String("-96379/100")); + QCOMPARE(split2.attribute("reconciledate"), QString()); + QCOMPARE(split2.attribute("action"), QString()); + QCOMPARE(split2.attribute("bankid"), QString()); + QCOMPARE(split2.attribute("account"), QLatin1String("A000276")); + QCOMPARE(split2.attribute("number"), QString()); + QCOMPARE(split2.attribute("value"), QLatin1String("-96379/100")); + QCOMPARE(split2.attribute("memo"), QString()); + QCOMPARE(split2.childNodes().size(), 0); + + QDomElement keyValuePairs = transaction.childNodes().at(1).toElement(); + QCOMPARE(keyValuePairs.tagName(), QLatin1String("KEYVALUEPAIRS")); + QCOMPARE(keyValuePairs.childNodes().size(), 1); + + QVERIFY(keyValuePairs.childNodes().at(0).isElement()); + QDomElement keyValuePair1 = keyValuePairs.childNodes().at(0).toElement(); + QCOMPARE(keyValuePair1.tagName(), QLatin1String("PAIR")); + QCOMPARE(keyValuePair1.attribute("key"), QLatin1String("key")); + QCOMPARE(keyValuePair1.attribute("value"), QLatin1String("value")); + QCOMPARE(keyValuePair1.childNodes().size(), 0); +} + +void MyMoneyXmlContentHandlerTest::testOverdue() +{ + MyMoneySchedule sch_overdue; + MyMoneySchedule sch_intime; + + // the following checks only work correctly, if currentDate() is + // between the 1st and 27th. If it is between 28th and 31st + // we don't perform them. Note: this should be fixed. + if (QDate::currentDate().day() > 27 || QDate::currentDate().day() == 1) { + qDebug() << "testOverdue() skipped because current day is between 28th and 2nd"; + return; + } + + QDate startDate = QDate::currentDate().addDays(-1).addMonths(-23); + QDate lastPaymentDate = QDate::currentDate().addDays(-1).addMonths(-1); + + QString ref = QString( + "\n" + "\n" + " \n" // krazy:exclude=spelling + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "\n"); + QString ref_overdue = ref.arg(startDate.toString(Qt::ISODate)) + .arg(lastPaymentDate.toString(Qt::ISODate)) + .arg(lastPaymentDate.toString(Qt::ISODate)); + + QString ref_intime = ref.arg(startDate.addDays(1).toString(Qt::ISODate)) + .arg(lastPaymentDate.addDays(1).toString(Qt::ISODate)) + .arg(lastPaymentDate.addDays(1).toString(Qt::ISODate)); + + QDomDocument doc; + QDomElement node; + + // std::cout << ref_intime << std::endl; + try { + doc.setContent(ref_overdue); + node = doc.documentElement().firstChild().toElement(); + sch_overdue = MyMoneyXmlContentHandler::readSchedule(node); + doc.setContent(ref_intime); + node = doc.documentElement().firstChild().toElement(); + sch_intime = MyMoneyXmlContentHandler::readSchedule(node); + + QCOMPARE(sch_overdue.isOverdue(), true); + QCOMPARE(sch_intime.isOverdue(), false); + + } catch (const MyMoneyException &) { + QFAIL("Unexpected exception"); + } +} + +void MyMoneyXmlContentHandlerTest::testNextPayment() +/* + * Test for a schedule where a payment hasn't yet been made. + * First payment is in the future. +*/ +{ + MyMoneySchedule sch; + QString future_sched = QString( + "\n" + "\n" + "\n" // krazy:exclude=spelling + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "\n" + "\n" + ); + + QDomDocument doc; + QDomElement node; + doc.setContent(future_sched); + node = doc.documentElement().firstChild().toElement(); + + try { + sch = MyMoneyXmlContentHandler::readSchedule(node); + QCOMPARE(sch.nextPayment(QDate(2007, 2, 14)), QDate(2007, 2, 17)); + QCOMPARE(sch.nextPayment(QDate(2007, 2, 17)), QDate(2008, 2, 17)); + QCOMPARE(sch.nextPayment(QDate(2007, 2, 18)), QDate(2008, 2, 17)); + + } catch (const MyMoneyException &) { + QFAIL("Unexpected exception"); + } +} + +void MyMoneyXmlContentHandlerTest::testNextPaymentOnLastDayOfMonth() +{ + MyMoneySchedule sch; + QString future_sched = QString( + "\n" + "\n" + "\n" // krazy:exclude=spelling + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "\n" + "\n" + ); + + QDomDocument doc; + QDomElement node; + doc.setContent(future_sched); + node = doc.documentElement().firstChild().toElement(); + + try { + sch = MyMoneyXmlContentHandler::readSchedule(node); + QDate nextPayment; + + // check for the first payment to happen + nextPayment = sch.nextPayment(QDate(2014, 10, 1)); + QCOMPARE(nextPayment, QDate(2014, 10, 31)); + sch.setLastPayment(nextPayment); + + QCOMPARE(sch.nextPayment(QDate(2014, 11, 1)), QDate(2014, 11, 30)); + QCOMPARE(sch.nextPayment(QDate(2014, 12, 1)), QDate(2014, 12, 31)); + QCOMPARE(sch.nextPayment(QDate(2015, 1, 1)), QDate(2015, 1, 31)); + QCOMPARE(sch.nextPayment(QDate(2015, 2, 1)), QDate(2015, 2, 28)); + QCOMPARE(sch.nextPayment(QDate(2015, 3, 1)), QDate(2015, 3, 31)); + + // now check that we also cover leap years + QCOMPARE(sch.nextPayment(QDate(2016, 2, 1)), QDate(2016, 2, 29)); + QCOMPARE(sch.nextPayment(QDate(2016, 3, 1)), QDate(2016, 3, 31)); + + } catch (const MyMoneyException &) { + QFAIL("Unexpected exception"); + } +} + +void MyMoneyXmlContentHandlerTest::testPaymentDates() +{ + MyMoneySchedule sch; + QString ref_ok = QString( + "\n" + "\n" + + "\n" // krazy:exclude=spelling + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "\n" + + "\n" + ); + + QDomDocument doc; + QDomElement node; + doc.setContent(ref_ok); + node = doc.documentElement().firstChild().toElement(); + + QDate startDate(2006, 1, 28); + QDate endDate(2006, 5, 30); + + try { + sch = MyMoneyXmlContentHandler::readSchedule(node); + QDate nextPayment = sch.nextPayment(startDate); + QList list = sch.paymentDates(nextPayment, endDate); + QCOMPARE(list.count(), 3); + QCOMPARE(list[0], QDate(2006, 2, 28)); + QCOMPARE(list[1], QDate(2006, 3, 31)); + // Would fall on a Sunday so gets moved back to 28th. + QCOMPARE(list[2], QDate(2006, 4, 28)); + + // Add tests for each possible occurrence. + // Check how paymentDates is meant to work + // Build a list of expected dates and compare + // Schedule::Occurrence::Once + sch.setOccurrence(Schedule::Occurrence::Once); + startDate.setDate(2009, 1, 1); + endDate.setDate(2009, 12, 31); + sch.setStartDate(startDate); + sch.setNextDueDate(startDate); + list = sch.paymentDates(startDate, endDate); + QCOMPARE(list.count(), 1); + QCOMPARE(list[0], QDate(2009, 1, 1)); + // Schedule::Occurrence::Daily + sch.setOccurrence(Schedule::Occurrence::Daily); + startDate.setDate(2009, 1, 1); + endDate.setDate(2009, 1, 5); + sch.setStartDate(startDate); + sch.setNextDueDate(startDate); + list = sch.paymentDates(startDate, endDate); + QCOMPARE(list.count(), 5); + QCOMPARE(list[0], QDate(2009, 1, 1)); + QCOMPARE(list[1], QDate(2009, 1, 2)); + // Would fall on Saturday so gets moved to 2nd. + QCOMPARE(list[2], QDate(2009, 1, 2)); + // Would fall on Sunday so gets moved to 2nd. + QCOMPARE(list[3], QDate(2009, 1, 2)); + QCOMPARE(list[4], QDate(2009, 1, 5)); + // Schedule::Occurrence::Daily with multiplier 2 + sch.setOccurrenceMultiplier(2); + list = sch.paymentDates(startDate.addDays(1), endDate); + QCOMPARE(list.count(), 2); + // Would fall on Sunday so gets moved to 2nd. + QCOMPARE(list[0], QDate(2009, 1, 2)); + QCOMPARE(list[1], QDate(2009, 1, 5)); + sch.setOccurrenceMultiplier(1); + // Schedule::Occurrence::Weekly + sch.setOccurrence(Schedule::Occurrence::Weekly); + startDate.setDate(2009, 1, 6); + endDate.setDate(2009, 2, 4); + sch.setStartDate(startDate); + sch.setNextDueDate(startDate); + list = sch.paymentDates(startDate, endDate); + QCOMPARE(list.count(), 5); + QCOMPARE(list[0], QDate(2009, 1, 6)); + QCOMPARE(list[1], QDate(2009, 1, 13)); + QCOMPARE(list[2], QDate(2009, 1, 20)); + QCOMPARE(list[3], QDate(2009, 1, 27)); + QCOMPARE(list[4], QDate(2009, 2, 3)); + // Schedule::Occurrence::EveryOtherWeek + sch.setOccurrence(Schedule::Occurrence::EveryOtherWeek); + startDate.setDate(2009, 2, 5); + endDate.setDate(2009, 4, 3); + sch.setStartDate(startDate); + sch.setNextDueDate(startDate); + list = sch.paymentDates(startDate, endDate); + QCOMPARE(list.count(), 5); + QCOMPARE(list[0], QDate(2009, 2, 5)); + QCOMPARE(list[1], QDate(2009, 2, 19)); + QCOMPARE(list[2], QDate(2009, 3, 5)); + QCOMPARE(list[3], QDate(2009, 3, 19)); + QCOMPARE(list[4], QDate(2009, 4, 2)); + // Schedule::Occurrence::Fortnightly + sch.setOccurrence(Schedule::Occurrence::Fortnightly); + startDate.setDate(2009, 4, 4); + endDate.setDate(2009, 5, 31); + sch.setStartDate(startDate); + sch.setNextDueDate(startDate); + list = sch.paymentDates(startDate, endDate); + QCOMPARE(list.count(), 4); + // First one would fall on a Saturday and would get moved + // to 3rd which is before start date so is not in list. + // Would fall on a Saturday so gets moved to 17th. + QCOMPARE(list[0], QDate(2009, 4, 17)); + // Would fall on a Saturday so gets moved to 1st. + QCOMPARE(list[1], QDate(2009, 5, 1)); + // Would fall on a Saturday so gets moved to 15th. + QCOMPARE(list[2], QDate(2009, 5, 15)); + // Would fall on a Saturday so gets moved to 29th. + QCOMPARE(list[3], QDate(2009, 5, 29)); + // Schedule::Occurrence::EveryHalfMonth + sch.setOccurrence(Schedule::Occurrence::EveryHalfMonth); + startDate.setDate(2009, 6, 1); + endDate.setDate(2009, 8, 11); + sch.setStartDate(startDate); + sch.setNextDueDate(startDate); + list = sch.paymentDates(startDate, endDate); + QCOMPARE(list.count(), 5); + QCOMPARE(list[0], QDate(2009, 6, 1)); + QCOMPARE(list[1], QDate(2009, 6, 16)); + QCOMPARE(list[2], QDate(2009, 7, 1)); + QCOMPARE(list[3], QDate(2009, 7, 16)); + // Would fall on a Saturday so gets moved to 31st. + QCOMPARE(list[4], QDate(2009, 7, 31)); + // Schedule::Occurrence::EveryThreeWeeks + sch.setOccurrence(Schedule::Occurrence::EveryThreeWeeks); + startDate.setDate(2009, 8, 12); + endDate.setDate(2009, 11, 12); + sch.setStartDate(startDate); + sch.setNextDueDate(startDate); + list = sch.paymentDates(startDate, endDate); + QCOMPARE(list.count(), 5); + QCOMPARE(list[0], QDate(2009, 8, 12)); + QCOMPARE(list[1], QDate(2009, 9, 2)); + QCOMPARE(list[2], QDate(2009, 9, 23)); + QCOMPARE(list[3], QDate(2009, 10, 14)); + QCOMPARE(list[4], QDate(2009, 11, 4)); + // Schedule::Occurrence::EveryFourWeeks + sch.setOccurrence(Schedule::Occurrence::EveryFourWeeks); + startDate.setDate(2009, 11, 13); + endDate.setDate(2010, 3, 13); + sch.setStartDate(startDate); + sch.setNextDueDate(startDate); + list = sch.paymentDates(startDate, endDate); + QCOMPARE(list.count(), 5); + QCOMPARE(list[0], QDate(2009, 11, 13)); + QCOMPARE(list[1], QDate(2009, 12, 11)); + QCOMPARE(list[2], QDate(2010, 1, 8)); + QCOMPARE(list[3], QDate(2010, 2, 5)); + QCOMPARE(list[4], QDate(2010, 3, 5)); + // Schedule::Occurrence::EveryThirtyDays + sch.setOccurrence(Schedule::Occurrence::EveryThirtyDays); + startDate.setDate(2010, 3, 19); + endDate.setDate(2010, 7, 19); + sch.setStartDate(startDate); + sch.setNextDueDate(startDate); + list = sch.paymentDates(startDate, endDate); + QCOMPARE(list.count(), 5); + QCOMPARE(list[0], QDate(2010, 3, 19)); + // Would fall on a Sunday so gets moved to 16th. + QCOMPARE(list[1], QDate(2010, 4, 16)); + QCOMPARE(list[2], QDate(2010, 5, 18)); + QCOMPARE(list[3], QDate(2010, 6, 17)); + // Would fall on a Saturday so gets moved to 16th. + QCOMPARE(list[4], QDate(2010, 7, 16)); + // Schedule::Occurrence::EveryEightWeeks + sch.setOccurrence(Schedule::Occurrence::EveryEightWeeks); + startDate.setDate(2010, 7, 26); + endDate.setDate(2011, 3, 26); + sch.setStartDate(startDate); + sch.setNextDueDate(startDate); + list = sch.paymentDates(startDate, endDate); + QCOMPARE(list.count(), 5); + QCOMPARE(list[0], QDate(2010, 7, 26)); + QCOMPARE(list[1], QDate(2010, 9, 20)); + QCOMPARE(list[2], QDate(2010, 11, 15)); + QCOMPARE(list[3], QDate(2011, 1, 10)); + QCOMPARE(list[4], QDate(2011, 3, 7)); + // Schedule::Occurrence::EveryOtherMonth + sch.setOccurrence(Schedule::Occurrence::EveryOtherMonth); + startDate.setDate(2011, 3, 14); + endDate.setDate(2011, 11, 20); + sch.setStartDate(startDate); + sch.setNextDueDate(startDate); + list = sch.paymentDates(startDate, endDate); + QCOMPARE(list.count(), 5); + QCOMPARE(list[0], QDate(2011, 3, 14)); + // Would fall on a Saturday so gets moved to 13th. + QCOMPARE(list[1], QDate(2011, 5, 13)); + QCOMPARE(list[2], QDate(2011, 7, 14)); + QCOMPARE(list[3], QDate(2011, 9, 14)); + QCOMPARE(list[4], QDate(2011, 11, 14)); + // Schedule::Occurrence::EveryThreeMonths + sch.setOccurrence(Schedule::Occurrence::EveryThreeMonths); + startDate.setDate(2011, 11, 15); + endDate.setDate(2012, 11, 19); + sch.setStartDate(startDate); + sch.setNextDueDate(startDate); + list = sch.paymentDates(startDate, endDate); + QCOMPARE(list.count(), 5); + QCOMPARE(list[0], QDate(2011, 11, 15)); + QCOMPARE(list[1], QDate(2012, 2, 15)); + QCOMPARE(list[2], QDate(2012, 5, 15)); + QCOMPARE(list[3], QDate(2012, 8, 15)); + QCOMPARE(list[4], QDate(2012, 11, 15)); + // Schedule::Occurrence::Quarterly + sch.setOccurrence(Schedule::Occurrence::Quarterly); + startDate.setDate(2012, 11, 20); + endDate.setDate(2013, 11, 23); + sch.setStartDate(startDate); + sch.setNextDueDate(startDate); + list = sch.paymentDates(startDate, endDate); + QCOMPARE(list.count(), 5); + QCOMPARE(list[0], QDate(2012, 11, 20)); + QCOMPARE(list[1], QDate(2013, 2, 20)); + QCOMPARE(list[2], QDate(2013, 5, 20)); + QCOMPARE(list[3], QDate(2013, 8, 20)); + QCOMPARE(list[4], QDate(2013, 11, 20)); + // Schedule::Occurrence::EveryFourMonths + sch.setOccurrence(Schedule::Occurrence::EveryFourMonths); + startDate.setDate(2013, 11, 21); + endDate.setDate(2015, 3, 23); + sch.setStartDate(startDate); + sch.setNextDueDate(startDate); + list = sch.paymentDates(startDate, endDate); + QCOMPARE(list.count(), 5); + QCOMPARE(list[0], QDate(2013, 11, 21)); + QCOMPARE(list[1], QDate(2014, 3, 21)); + QCOMPARE(list[2], QDate(2014, 7, 21)); + QCOMPARE(list[3], QDate(2014, 11, 21)); + // Would fall on a Saturday so gets moved to 20th. + QCOMPARE(list[4], QDate(2015, 3, 20)); + // Schedule::Occurrence::TwiceYearly + sch.setOccurrence(Schedule::Occurrence::TwiceYearly); + startDate.setDate(2015, 3, 22); + endDate.setDate(2017, 3, 29); + sch.setStartDate(startDate); + sch.setNextDueDate(startDate); + list = sch.paymentDates(startDate, endDate); + QCOMPARE(list.count(), 4); + // First date would fall on a Sunday which would get moved + // to 20th which is before start date so not in list. + QCOMPARE(list[0], QDate(2015, 9, 22)); + QCOMPARE(list[1], QDate(2016, 3, 22)); + QCOMPARE(list[2], QDate(2016, 9, 22)); + QCOMPARE(list[3], QDate(2017, 3, 22)); + // Schedule::Occurrence::Yearly + sch.setOccurrence(Schedule::Occurrence::Yearly); + startDate.setDate(2017, 3, 23); + endDate.setDate(2021, 3, 29); + sch.setStartDate(startDate); + sch.setNextDueDate(startDate); + list = sch.paymentDates(startDate, endDate); + QCOMPARE(list.count(), 5); + QCOMPARE(list[0], QDate(2017, 3, 23)); + QCOMPARE(list[1], QDate(2018, 3, 23)); + // Would fall on a Saturday so gets moved to 22nd. + QCOMPARE(list[2], QDate(2019, 3, 22)); + QCOMPARE(list[3], QDate(2020, 3, 23)); + QCOMPARE(list[4], QDate(2021, 3, 23)); + // Schedule::Occurrence::EveryOtherYear + sch.setOccurrence(Schedule::Occurrence::EveryOtherYear); + startDate.setDate(2021, 3, 24); + endDate.setDate(2029, 3, 30); + sch.setStartDate(startDate); + sch.setNextDueDate(startDate); + list = sch.paymentDates(startDate, endDate); + QCOMPARE(list.count(), 5); + QCOMPARE(list[0], QDate(2021, 3, 24)); + QCOMPARE(list[1], QDate(2023, 3, 24)); + QCOMPARE(list[2], QDate(2025, 3, 24)); + QCOMPARE(list[3], QDate(2027, 3, 24)); + // Would fall on a Saturday so gets moved to 23rd. + QCOMPARE(list[4], QDate(2029, 3, 23)); + } catch (const MyMoneyException &) { + QFAIL("Unexpected exception"); + } +} + +void MyMoneyXmlContentHandlerTest::testHasReferenceTo() +{ + MyMoneySchedule sch; + QString ref_ok = QString( + "\n" + "\n" + " \n" // krazy:exclude=spelling + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "\n" + ).arg(QDate::currentDate().toString(Qt::ISODate)) + .arg(QDate::currentDate().toString(Qt::ISODate)) + .arg(QDate::currentDate().toString(Qt::ISODate)); + + QDomDocument doc; + QDomElement node; + doc.setContent(ref_ok); + node = doc.documentElement().firstChild().toElement(); + + try { + sch = MyMoneyXmlContentHandler::readSchedule(node); + + } catch (const MyMoneyException &) { + QFAIL("Unexpected exception"); + } + + QCOMPARE(sch.hasReferenceTo(QLatin1String("P000001")), true); + QCOMPARE(sch.hasReferenceTo(QLatin1String("A000276")), true); + QCOMPARE(sch.hasReferenceTo(QLatin1String("A000076")), true); + QCOMPARE(sch.hasReferenceTo(QLatin1String("EUR")), true); +} + +void MyMoneyXmlContentHandlerTest::testPaidEarlyOneTime() +{ +// this tries to figure out what's wrong with +// https://bugs.kde.org/show_bug.cgi?id=231029 + + MyMoneySchedule sch; + QDate paymentInFuture = QDate::currentDate().addDays(7); + + QString ref_ok = QString( + "\n" + "\n" + " \n" // krazy:exclude=spelling + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "\n" + ).arg(paymentInFuture.toString(Qt::ISODate)) + .arg(paymentInFuture.toString(Qt::ISODate)) + .arg(paymentInFuture.toString(Qt::ISODate)); + + QDomDocument doc; + QDomElement node; + doc.setContent(ref_ok); + node = doc.documentElement().firstChild().toElement(); + + try { + sch = MyMoneyXmlContentHandler::readSchedule(node); + QCOMPARE(sch.isFinished(), true); + QCOMPARE(sch.occurrencePeriod(), Schedule::Occurrence::Monthly); + QCOMPARE(sch.paymentDates(QDate::currentDate(), QDate::currentDate().addDays(21)).count(), 0); + } catch (const MyMoneyException &) { + QFAIL("Unexpected exception"); + } +} + +void MyMoneyXmlContentHandlerTest::testReplaceId() +{ + MyMoneySchedule sch; + QDate paymentInFuture = QDate::currentDate().addDays(7); + + QString ref_ok = QString( + "\n" + "\n" + " \n" // krazy:exclude=spelling + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "\n" + ).arg(paymentInFuture.toString(Qt::ISODate)) + .arg(paymentInFuture.toString(Qt::ISODate)) + .arg(paymentInFuture.toString(Qt::ISODate)); + + QDomDocument doc; + QDomElement node; + doc.setContent(ref_ok); + node = doc.documentElement().firstChild().toElement(); + + try { + sch = MyMoneyXmlContentHandler::readSchedule(node); + QCOMPARE(sch.transaction().postDate().isValid(), false); + QCOMPARE(sch.transaction().splits()[0].accountId(), QLatin1String("A000076")); + QCOMPARE(sch.transaction().splits()[1].accountId(), QLatin1String("A000276")); + QCOMPARE(sch.replaceId(QLatin1String("A000079"), QLatin1String("A000076")), true); + QCOMPARE(sch.transaction().splits()[0].accountId(), QLatin1String("A000079")); + QCOMPARE(sch.transaction().splits()[1].accountId(), QLatin1String("A000276")); + + } catch (const MyMoneyException &) { + QFAIL("Unexpected exception"); + } + +}