/*************************************************************************** konlinebankingsetupwizard.cpp ------------------- begin : Sat Jan 7 2006 copyright : (C) 2006 by Ace Jones email : acejones@users.sourceforge.net ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifdef HAVE_CONFIG_H #include #endif // ---------------------------------------------------------------------------- // QT Includes #include #include #include #include #include #include #include // ---------------------------------------------------------------------------- // KDE Includes #include #include #include #include #include #include #include #include #include #include // ---------------------------------------------------------------------------- // Project Includes #include "konlinebankingsetupwizard.h" #include <../ofxpartner.h> #include class KOnlineBankingSetupWizard::Private { public: QFile m_fpTrace; QTextStream m_trace; }; KOnlineBankingSetupWizard::KOnlineBankingSetupWizard(QWidget *parent, const char *name): KOnlineBankingSetupDecl(parent,name), d(new Private), m_fDone(false), m_fInit(false), m_appId(0) { m_appId = new OfxAppVersion(m_applicationCombo, ""); m_headerVersion = new OfxHeaderVersion(m_headerVersionCombo, ""); // fill the list view with banks KProgressDialog* dlg = new KProgressDialog(this, 0, i18n("Loading banklist"), i18n("Getting list of banks from http://moneycentral.msn.com/\nThis may take some time depending on the available bandwidth."), true); dlg->setAllowCancel(false); // force to show immediately as the call to OfxPartner::BankNames() // does not call the processEvents() loop dlg->setMinimumDuration(0); kapp->processEvents(); tabLayout->insertWidget(0, new KListViewSearchLineWidget(m_listFi, tab, 0)); OfxPartner::setDirectory(locateLocal("appdata", "")); QStringList banks = OfxPartner::BankNames(); QStringList::const_iterator it_bank = banks.begin(); while (it_bank != banks.end()) { new KListViewItem( m_listFi, (*it_bank)); ++it_bank; } m_fInit = true; delete dlg; } KOnlineBankingSetupWizard::~KOnlineBankingSetupWizard() { delete m_appId; delete d; } void KOnlineBankingSetupWizard::next(void) { bool ok = true; switch (indexOf(currentPage())) { case 0: ok = finishFiPage(); break; case 1: ok = finishLoginPage(); break; case 2: m_fDone = ok = finishAccountPage(); break; } if (ok) KOnlineBankingSetupDecl::next(); setFinishEnabled(currentPage(), m_fDone ); } bool KOnlineBankingSetupWizard::finishFiPage(void) { bool result = false; m_bankInfo.clear(); OfxFiServiceInfo info; if(m_selectionTab->currentPageIndex() == 0) { // Get the fipids for the selected bank QListViewItem* item = m_listFi->currentItem(); if ( item ) { QString bank = item->text(0); m_textDetails->clear(); m_textDetails->append(QString("

Details for %1:

").arg(bank)); QStringList fipids = OfxPartner::FipidForBank(bank); QStringList::const_iterator it_fipid = fipids.begin(); while ( it_fipid != fipids.end() ) { // For each fipid, get the connection details info = OfxPartner::ServiceInfo(*it_fipid); // Print them to the text browser QString message = QString("

Fipid: %1
").arg(*it_fipid); // If the bank supports retrieving statements if ( info.accountlist ) { m_bankInfo.push_back(info); message += QString("URL: %1
Org: %2
Fid: %3
").arg(info.url,info.org,info.fid); if ( info.statements ) message += i18n("Supports online statements
"); if ( info.investments ) message += i18n("Supports investments
"); if ( info.billpay ) message += i18n("Supports bill payment (but not supported by KMyMoney yet)
"); } else { message += i18n("Does not support online banking

"); } m_textDetails->append(message); ++it_fipid; } result = true; } else // error! No current item KMessageBox::sorry(this,i18n("Please choose a bank.")); } else { // manual entry of values if(m_fid->text().isEmpty() || m_url->url().isEmpty() || m_bankName->text().isEmpty()) { KMessageBox::sorry(this,i18n("Please fill all fields with values.")); } m_textDetails->clear(); m_textDetails->append(QString("

Details for %1:

").arg(m_bankName->text())); memset(&info, 0, sizeof(OfxFiServiceInfo)); strncpy(info.fid, m_fid->text().data(), OFX_FID_LENGTH-1); strncpy(info.org, m_bankName->text().latin1(), OFX_ORG_LENGTH-1); strncpy(info.url, m_url->url().data(), OFX_URL_LENGTH-1); info.accountlist = 1; info.statements = 1; info.billpay = 1; info.investments = 1; m_bankInfo.push_back(info); QString message; message += QString("URL: %1
Org: %2
Fid: %3
").arg(info.url,info.org,info.fid); if ( info.statements ) message += i18n("Supports online statements
"); if ( info.investments ) message += i18n("Supports investments
"); if ( info.billpay ) message += i18n("Supports bill payment (but not supported by KMyMoney yet)
"); m_textDetails->append(message); result = true; } return result; } bool KOnlineBankingSetupWizard::finishLoginPage(void) { bool result = true; QString username = m_editUsername->text(); QString password = m_editPassword->text(); m_listAccount->clear(); // Process an account request for each fipid m_it_info = m_bankInfo.begin(); while ( m_it_info != m_bankInfo.end() ) { OfxFiLogin fi; memset(&fi,0,sizeof(OfxFiLogin)); strncpy(fi.fid,(*m_it_info).fid,OFX_FID_LENGTH-1); strncpy(fi.org,(*m_it_info).org,OFX_ORG_LENGTH-1); strncpy(fi.userid,username.latin1(),OFX_USERID_LENGTH-1); strncpy(fi.userpass,password.latin1(),OFX_USERPASS_LENGTH-1); #if LIBOFX_IS_VERSION(0,9,0) // pretend we're Quicken 2008 // http://ofxblog.wordpress.com/2007/06/06/ofx-appid-and-appver-for-intuit-products/ // http://ofxblog.wordpress.com/2007/06/06/ofx-appid-and-appver-for-microsoft-money/ QString appId = m_appId->appId(); QRegExp exp("(.*):(.*)"); if(exp.search(appId) != -1) { strncpy(fi.appid, exp.cap(1).latin1(), OFX_APPID_LENGTH-1); strncpy(fi.appver, exp.cap(2).latin1(), OFX_APPVER_LENGTH-1); } else { strncpy(fi.appid, "QWIN", OFX_APPID_LENGTH-1); strncpy(fi.appver, "1700", OFX_APPVER_LENGTH-1); } QString hver = m_headerVersion->headerVersion(); strncpy(fi.header_version, hver.latin1(), OFX_HEADERVERSION_LENGTH-1); #endif // who owns this memory?!?! char* request = libofx_request_accountinfo( &fi ); KURL filename(QString("%1response.ofx").arg(locateLocal("appdata", ""))); QByteArray req; req.setRawData(request, strlen(request)); OfxHttpsRequest("POST", (*m_it_info).url, req, QMap(), filename, true); req.resetRawData(request, strlen(request)); LibofxContextPtr ctx = libofx_get_new_context(); Q_CHECK_PTR(ctx); ofx_set_account_cb(ctx, ofxAccountCallback, this); ofx_set_status_cb(ctx, ofxStatusCallback, this); // Add resulting accounts to the account list libofx_proc_file(ctx, filename.path(), AUTODETECT); libofx_free_context(ctx); ++m_it_info; } if ( ! m_listAccount->childCount() ) { KMessageBox::sorry(this,i18n("No suitable accounts were found at this bank.")); result = false; } return result; } bool KOnlineBankingSetupWizard::finishAccountPage(void) { bool result = true; if ( ! m_listAccount->currentItem() ) { KMessageBox::sorry(this,i18n("Please choose an account")); result = false; } return result; } int KOnlineBankingSetupWizard::ofxAccountCallback(struct OfxAccountData data, void * pv) { KOnlineBankingSetupWizard* pthis = reinterpret_cast(pv); // Put the account info in the view MyMoneyKeyValueContainer kvps; if ( data.account_type_valid ) { QString type; switch ( data.account_type ) { case OfxAccountData::OFX_CHECKING: /**< A standard checking account */ type = "CHECKING"; break; case OfxAccountData::OFX_SAVINGS: /**< A standard savings account */ type = "SAVINGS"; break; case OfxAccountData::OFX_MONEYMRKT: /**< A money market account */ type = "MONEY MARKET"; break; case OfxAccountData::OFX_CREDITLINE: /**< A line of credit */ type = "CREDIT LINE"; break; case OfxAccountData::OFX_CMA: /**< Cash Management Account */ type = "CMA"; break; case OfxAccountData::OFX_CREDITCARD: /**< A credit card account */ type = "CREDIT CARD"; break; case OfxAccountData::OFX_INVESTMENT: /**< An investment account */ type = "INVESTMENT"; break; default: break; } kvps.setValue("type",type); } if ( data.bank_id_valid ) kvps.setValue("bankid",data.bank_id); if ( data.broker_id_valid ) kvps.setValue("bankid",data.broker_id); if ( data.branch_id_valid ) kvps.setValue("branchid",data.branch_id); if ( data.account_number_valid ) kvps.setValue("accountid",data.account_number); if ( data.account_id_valid ) kvps.setValue("uniqueId",data.account_id); kvps.setValue("username",pthis->m_editUsername->text()); kvps.setValue("password",pthis->m_editPassword->text()); kvps.setValue("url",(*(pthis->m_it_info)).url); kvps.setValue("fid",(*(pthis->m_it_info)).fid); kvps.setValue("org",(*(pthis->m_it_info)).org); kvps.setValue("fipid",""); QListViewItem* item = pthis->m_listFi->currentItem(); if ( item ) kvps.setValue("bankname",item->text(0)); // I removed the bankid here, because for some users it // was not possible to setup the automatic account matching // because the bankid was left empty here as well during // the statement download. In case we don't have it, we // simply use it blank. (ipwizard 2009-06-21) if(/* !kvps.value("bankid").isEmpty() && */ !kvps.value("uniqueId").isEmpty()) { kvps.setValue("kmmofx-acc-ref", QString("%1-%2").arg(kvps.value("bankid"), kvps.value("uniqueId"))); } else { qDebug("Cannot setup kmmofx-acc-ref for '%s'", kvps.value("bankname").data()); } kvps.setValue("protocol","OFX"); new ListViewItem( pthis->m_listAccount, kvps ); return 0; } int KOnlineBankingSetupWizard::ofxStatusCallback(struct OfxStatusData data, void * pv) { KOnlineBankingSetupWizard* pthis = reinterpret_cast(pv); QString message; if(data.code_valid==true) { message += QString("#%1 %2: \"%3\"\n").arg(data.code).arg(data.name,data.description); } if(data.server_message_valid==true){ message += i18n("Server message: %1\n").arg(data.server_message); } if(data.severity_valid==true){ switch(data.severity){ case OfxStatusData::INFO : break; case OfxStatusData::WARN : KMessageBox::detailedError( pthis, i18n("Your bank returned warnings when signing on"), i18n("WARNING %1").arg(message) ); break; case OfxStatusData::ERROR : KMessageBox::detailedError( pthis, i18n("Error signing onto your bank"), i18n("ERROR %1").arg(message) ); break; default: break; } } return 0; } bool KOnlineBankingSetupWizard::chosenSettings( MyMoneyKeyValueContainer& settings ) { bool result = false;; if ( m_fDone ) { QListViewItem* qitem = m_listAccount->currentItem(); ListViewItem* item = dynamic_cast(qitem); if ( item ) { settings = *item; settings.deletePair("appId"); settings.deletePair("kmmofx-headerVersion"); QString appId = m_appId->appId(); if(!appId.isEmpty()) settings.setValue("appId", appId); QString hVer = m_headerVersion->headerVersion(); if(!hVer.isEmpty()) settings.setValue("kmmofx-headerVersion", hVer); result = true; } } return result; } KOnlineBankingSetupWizard::ListViewItem::ListViewItem( QListView* parent, const MyMoneyKeyValueContainer& kvps ): MyMoneyKeyValueContainer( kvps ), QListViewItem( parent ) { setText( 0, value("accountid") ); setText( 1, value("type") ); setText( 2, value("bankid") ); setText( 3, value("branchid") ); } void KOnlineBankingSetupWizard::ListViewItem::x(void) {} #include "konlinebankingsetupwizard.moc" // vim:cin:si:ai:et:ts=2:sw=2: