/*************************************************************************** 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 <config.h> #endif // ---------------------------------------------------------------------------- // QT Includes #include <tqtextbrowser.h> #include <tqlineedit.h> #include <tqlabel.h> #include <tqlayout.h> #include <tqregexp.h> #include <tqcheckbox.h> #include <tqtabwidget.h> // ---------------------------------------------------------------------------- // KDE Includes #include <klocale.h> #include <kdebug.h> #include <kmessagebox.h> #include <kstandarddirs.h> #include <kprogress.h> #include <kapplication.h> #include <klistview.h> #include <klistviewsearchline.h> #include <kcombobox.h> #include <kurlrequester.h> // ---------------------------------------------------------------------------- // Project Includes #include "konlinebankingsetupwizard.h" #include <../ofxpartner.h> #include <mymoneyofxconnector.h> class KOnlineBankingSetupWizard::Private { public: TQFile m_fpTrace; TQTextStream m_trace; }; KOnlineBankingSetupWizard::KOnlineBankingSetupWizard(TQWidget *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", "")); TQStringList banks = OfxPartner::BankNames(); TQStringList::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 TQListViewItem* item = m_listFi->currentItem(); if ( item ) { TQString bank = item->text(0); m_textDetails->clear(); m_textDetails->append(TQString("<p>Details for %1:</p>").arg(bank)); TQStringList fipids = OfxPartner::FipidForBank(bank); TQStringList::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 TQString message = TQString("<p>Fipid: %1<br>").arg(*it_fipid); // If the bank supports retrieving statements if ( info.accountlist ) { m_bankInfo.push_back(info); message += TQString("URL: %1<br>Org: %2<br>Fid: %3<br>").arg(info.url,info.org,info.fid); if ( info.statements ) message += i18n("Supports online statements<br>"); if ( info.investments ) message += i18n("Supports investments<br>"); if ( info.billpay ) message += i18n("Supports bill payment (but not supported by KMyMoney yet)<br>"); } else { message += i18n("Does not support online banking</p>"); } 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(TQString("<p>Details for %1:</p>").arg(m_bankName->text())); memset(&info, 0, sizeof(OfxFiServiceInfo)); strncpy(info.fid, m_fid->text().ascii(), OFX_FID_LENGTH-1); strncpy(info.org, m_bankName->text().latin1(), OFX_ORG_LENGTH-1); strncpy(info.url, m_url->url().ascii(), OFX_URL_LENGTH-1); info.accountlist = 1; info.statements = 1; info.billpay = 1; info.investments = 1; m_bankInfo.push_back(info); TQString message; message += TQString("URL: %1<br>Org: %2<br>Fid: %3<br>").arg(info.url,info.org,info.fid); if ( info.statements ) message += i18n("Supports online statements<br>"); if ( info.investments ) message += i18n("Supports investments<br>"); if ( info.billpay ) message += i18n("Supports bill payment (but not supported by KMyMoney yet)<br>"); m_textDetails->append(message); result = true; } return result; } bool KOnlineBankingSetupWizard::finishLoginPage(void) { bool result = true; TQString username = m_editUsername->text(); TQString 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/ TQString appId = m_appId->appId(); TQRegExp 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); } TQString 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(TQString("%1response.ofx").arg(locateLocal("appdata", ""))); TQByteArray req; req.setRawData(request, strlen(request)); OfxHttpsRequest("POST", (*m_it_info).url, req, TQMap<TQString, TQString>(), filename, true); req.resetRawData(request, strlen(request)); LibofxContextPtr ctx = libofx_get_new_context(); TQ_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<KOnlineBankingSetupWizard*>(pv); // Put the account info in the view MyMoneyKeyValueContainer kvps; if ( data.account_type_valid ) { TQString 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",""); TQListViewItem* 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", TQString("%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<KOnlineBankingSetupWizard*>(pv); TQString message; if(data.code_valid==true) { message += TQString("#%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 ) { TQListViewItem* qitem = m_listAccount->currentItem(); ListViewItem* item = dynamic_cast<ListViewItem*>(qitem); if ( item ) { settings = *item; settings.deletePair("appId"); settings.deletePair("kmmofx-headerVersion"); TQString appId = m_appId->appId(); if(!appId.isEmpty()) settings.setValue("appId", appId); TQString hVer = m_headerVersion->headerVersion(); if(!hVer.isEmpty()) settings.setValue("kmmofx-headerVersion", hVer); result = true; } } return result; } KOnlineBankingSetupWizard::ListViewItem::ListViewItem( TQListView* parent, const MyMoneyKeyValueContainer& kvps ): MyMoneyKeyValueContainer( kvps ), TQListViewItem( 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: