File indexing completed on 2024-05-26 05:09:43
0001 /* 0002 SPDX-FileCopyrightText: 2014-2015 Romain Bignon <romain@symlink.me> 0003 SPDX-FileCopyrightText: 2014-2015 Florent Fourcot <weboob@flo.fourcot.fr> 0004 SPDX-FileCopyrightText: 2016 Christian David <christian-david@web.de> 0005 SPDX-FileCopyrightText: 2017 Łukasz Wojniłowicz <lukasz.wojnilowicz@gmail.com> 0006 SPDX-FileCopyrightText: 2019 Thomas Baumgart <tbaumgart@kde.org> 0007 SPDX-FileCopyrightText: 2021 Dawid Wróbel <me@dawidwrobel.com> 0008 SPDX-License-Identifier: GPL-2.0-or-later 0009 */ 0010 0011 #include "woob.h" 0012 #include <config-kmymoney.h> 0013 0014 #include <memory> 0015 0016 // ---------------------------------------------------------------------------- 0017 // QT Includes 0018 0019 #include <QFutureWatcher> 0020 #include <QProgressDialog> 0021 #include <QtConcurrentRun> 0022 0023 // ---------------------------------------------------------------------------- 0024 // KDE Includes 0025 0026 #include <KLocalizedString> 0027 #include <KMessageBox> 0028 #include <KPluginFactory> 0029 0030 // ---------------------------------------------------------------------------- 0031 // Project Includes 0032 0033 #include "accountsettings.h" 0034 #include "mapaccountwizard.h" 0035 #include "woobinterface.h" 0036 0037 #include "mymoneyaccount.h" 0038 #include "mymoneykeyvaluecontainer.h" 0039 #include "mymoneystatement.h" 0040 #include "statementinterface.h" 0041 0042 class WoobPrivate 0043 { 0044 public: 0045 WoobPrivate() 0046 : accountSettings(nullptr) 0047 { 0048 } 0049 0050 ~WoobPrivate() 0051 { 0052 } 0053 0054 bool checkInitialized() const 0055 { 0056 if (!woob.isPythonInitialized()) { 0057 KMessageBox::error( 0058 nullptr, 0059 i18n("Woob plugin failed to fully initialize, most likely due to a missing or a misconfigured Python environment. Please refer to the " 0060 "manual on how to fix it.")); 0061 return false; 0062 } else if (!woob.isWoobInitialized()) { 0063 KMessageBox::error( 0064 nullptr, 0065 i18n("Woob plugin failed to fully initialize, most likely due to a missing or a misconfigured Woob Python module. Please refer to the " 0066 "manual on how to fix it.")); 0067 return false; 0068 } 0069 0070 return true; 0071 } 0072 0073 WoobInterface woob; 0074 QFutureWatcher<WoobInterface::Account> watcher; 0075 std::unique_ptr<QProgressDialog> progress; 0076 AccountSettings* accountSettings; 0077 }; 0078 0079 Woob::Woob(QObject* parent, const KPluginMetaData& metaData, const QVariantList& args) 0080 : KMyMoneyPlugin::Plugin(parent, metaData, args) 0081 , d_ptr(new WoobPrivate) 0082 { 0083 Q_INIT_RESOURCE(woob); 0084 0085 const auto rcFileName = QLatin1String("woob.rc"); 0086 setXMLFile(rcFileName); 0087 0088 qDebug("Plugins: woob loaded"); 0089 } 0090 0091 Woob::~Woob() 0092 { 0093 Q_D(Woob); 0094 delete d; 0095 qDebug("Plugins: woob unloaded"); 0096 } 0097 0098 void Woob::plug(KXMLGUIFactory* guiFactory) 0099 { 0100 Q_UNUSED(guiFactory) 0101 Q_D(Woob); 0102 connect(&d->watcher, &QFutureWatcher<WoobInterface::Account>::finished, this, &Woob::gotAccount); 0103 } 0104 0105 void Woob::unplug() 0106 { 0107 Q_D(Woob); 0108 disconnect(&d->watcher, &QFutureWatcher<WoobInterface::Account>::finished, this, &Woob::gotAccount); 0109 } 0110 0111 void Woob::protocols(QStringList& protocolList) const 0112 { 0113 protocolList << "woob"; 0114 } 0115 0116 QWidget* Woob::accountConfigTab(const MyMoneyAccount& account, QString& tabName) 0117 { 0118 Q_D(Woob); 0119 const MyMoneyKeyValueContainer& kvp = account.onlineBankingSettings(); 0120 tabName = i18n("Woob configuration"); 0121 0122 d->accountSettings = new AccountSettings(account, 0); 0123 d->accountSettings->loadUi(kvp); 0124 0125 return d->accountSettings; 0126 } 0127 0128 MyMoneyKeyValueContainer Woob::onlineBankingSettings(const MyMoneyKeyValueContainer& current) 0129 { 0130 Q_D(Woob); 0131 MyMoneyKeyValueContainer kvp(current); 0132 kvp["provider"] = objectName().toLower(); 0133 if (d->accountSettings) { 0134 d->accountSettings->loadKvp(kvp); 0135 } 0136 return kvp; 0137 } 0138 0139 bool Woob::mapAccount(const MyMoneyAccount& acc, MyMoneyKeyValueContainer& onlineBankingSettings) 0140 { 0141 Q_D(Woob); 0142 Q_UNUSED(acc); 0143 0144 bool rc = false; 0145 0146 if (d->checkInitialized()) { 0147 QPointer<MapAccountWizard> w = new MapAccountWizard(nullptr, &d->woob); 0148 if (w->exec() == QDialog::Accepted && w != nullptr) { 0149 onlineBankingSettings.setValue("wb-backend", w->currentBackend()); 0150 onlineBankingSettings.setValue("wb-id", w->currentAccount()); 0151 onlineBankingSettings.setValue("wb-max", "0"); 0152 rc = true; 0153 } 0154 delete w; 0155 } 0156 0157 return rc; 0158 } 0159 0160 bool Woob::updateAccount(const MyMoneyAccount& kacc, bool moreAccounts) 0161 { 0162 Q_D(Woob); 0163 Q_UNUSED(moreAccounts); 0164 0165 if (d->checkInitialized()) { 0166 QString bname = kacc.onlineBankingSettings().value("wb-backend"); 0167 QString id = kacc.onlineBankingSettings().value("wb-id"); 0168 QString max = kacc.onlineBankingSettings().value("wb-max"); 0169 0170 d->progress = std::make_unique<QProgressDialog>(nullptr); 0171 d->progress->setWindowTitle(i18n("Connecting to bank...")); 0172 d->progress->setLabelText(i18n("Retrieving transactions...")); 0173 d->progress->setModal(true); 0174 d->progress->setCancelButton(nullptr); 0175 d->progress->setMinimum(0); 0176 d->progress->setMaximum(0); 0177 d->progress->setMinimumDuration(0); 0178 0179 QFuture<WoobInterface::Account> future = QtConcurrent::run(&d->woob, &WoobInterface::getAccount, bname, id, max); 0180 d->watcher.setFuture(future); 0181 0182 d->progress->exec(); 0183 d->progress.reset(); 0184 0185 return true; 0186 } else 0187 return false; 0188 } 0189 0190 void Woob::gotAccount() 0191 { 0192 Q_D(Woob); 0193 WoobInterface::Account acc = d->watcher.result(); 0194 0195 MyMoneyAccount kacc = statementInterface()->account("wb-id", acc.id); 0196 MyMoneyStatement ks; 0197 0198 ks.m_accountId = kacc.id(); 0199 ks.m_strAccountName = acc.name; 0200 ks.m_closingBalance = acc.balance; 0201 if (acc.transactions.length() > 0) 0202 ks.m_dateEnd = acc.transactions.front().date; 0203 0204 #if 0 0205 switch (acc.type) { 0206 case Woob::Account::TYPE_CHECKING: 0207 ks.m_eType = MyMoneyStatement::etCheckings; 0208 break; 0209 case Woob::Account::TYPE_SAVINGS: 0210 ks.m_eType = MyMoneyStatement::etSavings; 0211 break; 0212 case Woob::Account::TYPE_MARKET: 0213 ks.m_eType = MyMoneyStatement::etInvestment; 0214 break; 0215 case Woob::Account::TYPE_DEPOSIT: 0216 case Woob::Account::TYPE_LOAN: 0217 case Woob::Account::TYPE_JOINT: 0218 case Woob::Account::TYPE_UNKNOWN: 0219 break; 0220 } 0221 #endif 0222 0223 for (QListIterator<WoobInterface::Transaction> it(acc.transactions); it.hasNext();) { 0224 WoobInterface::Transaction tr = it.next(); 0225 MyMoneyStatement::Transaction kt; 0226 0227 kt.m_strBankID = QLatin1String("ID ") + tr.id; 0228 kt.m_datePosted = tr.rdate; 0229 kt.m_amount = tr.amount; 0230 kt.m_strMemo = tr.raw; 0231 kt.m_strPayee = tr.label; 0232 0233 ks.m_listTransactions += kt; 0234 } 0235 0236 statementInterface()->import(ks); 0237 0238 d->progress->hide(); 0239 } 0240 0241 K_PLUGIN_CLASS_WITH_JSON(Woob, "woob.json") 0242 0243 #include "woob.moc"