File indexing completed on 2024-06-09 05:03:30
0001 /* 0002 SPDX-FileCopyrightText: 2004 Thomas Baumgart <kmymoney-devel@kde.org> 0003 SPDX-FileCopyrightText: 2017 Łukasz Wojniłowicz <lukasz.wojnilowicz@gmail.com> 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "knewinvestmentwizard.h" 0008 0009 // ---------------------------------------------------------------------------- 0010 // QT Includes 0011 0012 #include <QList> 0013 #include <QPointer> 0014 0015 // ---------------------------------------------------------------------------- 0016 // KDE Includes 0017 0018 #include <KMessageBox> 0019 #include <KHelpClient> 0020 #include <KLocalizedString> 0021 0022 // ---------------------------------------------------------------------------- 0023 // Project Includes 0024 0025 #include "ui_knewinvestmentwizard.h" 0026 0027 #include "kmymoneyutils.h" 0028 #include "mymoneyaccount.h" 0029 #include "mymoneyenums.h" 0030 #include "mymoneyexception.h" 0031 #include "mymoneyfile.h" 0032 #include "mymoneymoney.h" 0033 #include "mymoneysecurity.h" 0034 /// @todo AlkOnlineQuote remove following include when ported to Alkimia 0035 #include "webpricequote.h" 0036 0037 #include "kmmyesno.h" 0038 0039 class KNewInvestmentWizardPrivate 0040 { 0041 Q_DISABLE_COPY(KNewInvestmentWizardPrivate) 0042 Q_DECLARE_PUBLIC(KNewInvestmentWizard) 0043 0044 public: 0045 explicit KNewInvestmentWizardPrivate(KNewInvestmentWizard *qq) : 0046 q_ptr(qq), 0047 ui(new Ui::KNewInvestmentWizard), 0048 m_createAccount(false) 0049 { 0050 } 0051 0052 ~KNewInvestmentWizardPrivate() 0053 { 0054 delete ui; 0055 } 0056 0057 void init1() 0058 { 0059 Q_Q(KNewInvestmentWizard); 0060 ui->m_onlineUpdatePage->slotSourceChanged(false); 0061 0062 // make sure, the back button does not clear fields 0063 q->setOption(QWizard::IndependentPages, true); 0064 0065 // enable the help button 0066 q->setOption(q->HaveHelpButton, true); 0067 q->connect(q, &KNewInvestmentWizard::helpRequested, q, &KNewInvestmentWizard::slotHelp); 0068 0069 m_createAccount = true; 0070 0071 // Update label in case of edit 0072 if (!m_account.id().isEmpty()) { 0073 ui->m_investmentTypePage->setIntroLabelText(i18n("This wizard allows you to modify the selected investment.")); 0074 } 0075 if (!m_security.id().isEmpty()) { 0076 ui->m_investmentTypePage->setIntroLabelText(i18n("This wizard allows you to modify the selected security.")); 0077 } 0078 0079 KMyMoneyUtils::updateWizardButtons(q); 0080 } 0081 0082 void init2() 0083 { 0084 ui->m_investmentTypePage->init2(m_security); 0085 ui->m_investmentDetailsPage->init2(m_security); 0086 ui->m_onlineUpdatePage->init2(m_security); 0087 ui->m_onlineUpdatePage->slotCheckPage(m_security.value("kmm-online-source")); 0088 } 0089 0090 KNewInvestmentWizard *q_ptr; 0091 Ui::KNewInvestmentWizard *ui; 0092 0093 MyMoneyAccount m_account; 0094 MyMoneySecurity m_security; 0095 bool m_createAccount; 0096 }; 0097 0098 KNewInvestmentWizard::KNewInvestmentWizard(QWidget *parent) : 0099 QWizard(parent), 0100 d_ptr(new KNewInvestmentWizardPrivate(this)) 0101 { 0102 Q_D(KNewInvestmentWizard); 0103 d->ui->setupUi(this); 0104 d->init1(); 0105 d->ui->m_onlineUpdatePage->slotCheckPage(QString()); 0106 0107 d->ui->m_investmentDetailsPage->setupInvestmentSymbol(); 0108 0109 connect(d->ui->m_investmentDetailsPage, &KInvestmentDetailsWizardPage::checkForExistingSymbol, this, &KNewInvestmentWizard::slotCheckForExistingSymbol); 0110 } 0111 0112 KNewInvestmentWizard::KNewInvestmentWizard(const MyMoneyAccount& acc, QWidget *parent) : 0113 QWizard(parent), 0114 d_ptr(new KNewInvestmentWizardPrivate(this)) 0115 { 0116 Q_D(KNewInvestmentWizard); 0117 d->ui->setupUi(this); 0118 d->m_account = acc; 0119 setWindowTitle(i18n("Investment detail wizard")); 0120 d->init1(); 0121 0122 // load the widgets with the data 0123 setName(d->m_account.name()); 0124 d->m_security = MyMoneyFile::instance()->security(d->m_account.currencyId()); 0125 0126 d->init2(); 0127 0128 int priceMode = 0; 0129 if (!d->m_account.value("priceMode").isEmpty()) 0130 priceMode = d->m_account.value("priceMode").toInt(); 0131 d->ui->m_investmentDetailsPage->setCurrentPriceMode(priceMode); 0132 0133 } 0134 0135 KNewInvestmentWizard::KNewInvestmentWizard(const MyMoneySecurity& security, QWidget *parent) : 0136 QWizard(parent), 0137 d_ptr(new KNewInvestmentWizardPrivate(this)) 0138 { 0139 Q_D(KNewInvestmentWizard); 0140 d->ui->setupUi(this); 0141 d->m_security = security; 0142 setWindowTitle(i18n("Security detail wizard")); 0143 d->init1(); 0144 d->m_createAccount = false; 0145 0146 // load the widgets with the data 0147 setName(security.name()); 0148 0149 d->init2(); 0150 0151 // no chance to change the price mode here 0152 d->ui->m_investmentDetailsPage->setCurrentPriceMode(0); 0153 d->ui->m_investmentDetailsPage->setPriceModeEnabled(false); 0154 } 0155 0156 KNewInvestmentWizard::~KNewInvestmentWizard() 0157 { 0158 } 0159 0160 void KNewInvestmentWizard::setName(const QString& name) 0161 { 0162 Q_D(KNewInvestmentWizard); 0163 d->ui->m_investmentDetailsPage->setName(name); 0164 } 0165 0166 void KNewInvestmentWizard::slotCheckForExistingSymbol(const QString& symbol) 0167 { 0168 Q_D(KNewInvestmentWizard); 0169 Q_UNUSED(symbol); 0170 0171 if (field("investmentName").toString().isEmpty()) { 0172 const QList<MyMoneySecurity> list = MyMoneyFile::instance()->securityList(); 0173 auto type = static_cast<eMyMoney::Security::Type>(field("securityType").toInt()); 0174 0175 for (const MyMoneySecurity& it_s : list) { 0176 if (it_s.securityType() == type 0177 && it_s.tradingSymbol() == field("investmentSymbol").toString()) { 0178 d->m_security = MyMoneySecurity(); 0179 if (KMessageBox::questionTwoActions(this, 0180 i18n("The selected symbol is already on file. Do you want to reuse the existing security?"), 0181 i18n("Security found"), 0182 KMMYesNo::yes(), 0183 KMMYesNo::no()) 0184 == KMessageBox::PrimaryAction) { 0185 d->m_security = it_s; 0186 d->init2(); 0187 d->ui->m_investmentDetailsPage->loadName(d->m_security.name()); 0188 } 0189 break; 0190 } 0191 } 0192 } 0193 } 0194 0195 void KNewInvestmentWizard::slotHelp() 0196 { 0197 KHelpClient::invokeHelp("details.investments.newinvestmentwizard"); 0198 } 0199 0200 void KNewInvestmentWizard::createObjects(const QString& parentId) 0201 { 0202 Q_D(KNewInvestmentWizard); 0203 auto file = MyMoneyFile::instance(); 0204 0205 auto type = static_cast<eMyMoney::Security::Type>(field("securityType").toInt()); 0206 auto roundingMethod = static_cast<AlkValue::RoundingMethod>(field("roundingMethod").toInt()); 0207 MyMoneyFileTransaction ft; 0208 try { 0209 // update all relevant attributes only, if we create a stock 0210 // account and the security is unknown or we modify the security 0211 MyMoneySecurity newSecurity(d->m_security); 0212 newSecurity.setName(field("investmentName").toString()); 0213 newSecurity.setTradingSymbol(field("investmentSymbol").toString()); 0214 newSecurity.setTradingMarket(field("tradingMarket").toString()); 0215 newSecurity.setSmallestAccountFraction(field("fraction").value<MyMoneyMoney>().formatMoney("", 0, false).toUInt()); 0216 newSecurity.setPricePrecision(MyMoneyMoney(field("pricePrecision").toUInt()).formatMoney("", 0, false).toUInt()); 0217 newSecurity.setTradingCurrency(field("tradingCurrencyEdit").value<MyMoneySecurity>().id()); 0218 newSecurity.setSecurityType(type); 0219 newSecurity.setRoundingMethod(roundingMethod); 0220 newSecurity.deletePair("kmm-online-source"); 0221 newSecurity.deletePair("kmm-online-quote-system"); 0222 newSecurity.deletePair("kmm-online-factor"); 0223 newSecurity.deletePair("kmm-security-id"); 0224 0225 if (!field("onlineSourceCombo").toString().isEmpty()) { 0226 if (field("useFinanceQuote").toBool()) { 0227 FinanceQuoteProcess p; 0228 newSecurity.setValue("kmm-online-quote-system", "Finance::Quote"); 0229 newSecurity.setValue("kmm-online-source", p.crypticName(field("onlineSourceCombo").toString())); 0230 } else { 0231 newSecurity.setValue("kmm-online-source", field("onlineSourceCombo").toString()); 0232 } 0233 } 0234 if (d->ui->m_onlineUpdatePage->isOnlineFactorEnabled() && (field("onlineFactor").value<MyMoneyMoney>() != MyMoneyMoney::ONE)) 0235 newSecurity.setValue("kmm-online-factor", field("onlineFactor").value<MyMoneyMoney>().toString()); 0236 if (!field("investmentIdentification").toString().isEmpty()) 0237 newSecurity.setValue("kmm-security-id", field("investmentIdentification").toString()); 0238 0239 if (d->m_security.id().isEmpty() || newSecurity != d->m_security) { 0240 d->m_security = newSecurity; 0241 0242 // add or update it 0243 if (d->m_security.id().isEmpty()) { 0244 file->addSecurity(d->m_security); 0245 } else { 0246 file->modifySecurity(d->m_security); 0247 } 0248 } 0249 0250 if (d->m_createAccount) { 0251 // now that the security exists, we can add the account to store it 0252 d->m_account.setName(field("investmentName").toString()); 0253 if (d->m_account.accountType() == eMyMoney::Account::Type::Unknown) 0254 d->m_account.setAccountType(eMyMoney::Account::Type::Stock); 0255 0256 d->m_account.setCurrencyId(d->m_security.id()); 0257 switch (d->ui->m_investmentDetailsPage->priceMode()) { 0258 case 0: 0259 d->m_account.deletePair("priceMode"); 0260 break; 0261 case 1: 0262 case 2: 0263 d->m_account.setValue("priceMode", QString("%1").arg(d->ui->m_investmentDetailsPage->priceMode())); 0264 break; 0265 } 0266 // update account's fraction in case its security fraction has changed 0267 // otherwise KMM restart is required because this won't happen automatically 0268 d->m_account.fraction(d->m_security); 0269 if (d->m_account.id().isEmpty()) { 0270 MyMoneyAccount parent = file->account(parentId); 0271 file->addAccount(d->m_account, parent); 0272 } else 0273 file->modifyAccount(d->m_account); 0274 } 0275 ft.commit(); 0276 } catch (const MyMoneyException &e) { 0277 KMessageBox::detailedError(this, i18n("Unexpected error occurred while adding new investment"), QString::fromLatin1(e.what())); 0278 } 0279 } 0280 0281 void KNewInvestmentWizard::newInvestment(const MyMoneyAccount& parent) 0282 { 0283 QPointer<KNewInvestmentWizard> dlg = new KNewInvestmentWizard; 0284 if (dlg->exec() == QDialog::Accepted) 0285 dlg->createObjects(parent.id()); 0286 delete dlg; 0287 } 0288 0289 void KNewInvestmentWizard::newInvestment(MyMoneyAccount& account, const MyMoneyAccount& parent) 0290 { 0291 QString dontShowAgain = "CreateNewInvestments"; 0292 if (KMessageBox::questionTwoActions(nullptr, 0293 i18n("<qt>The security <b>%1</b> currently does not exist as sub-account of <b>%2</b>. " 0294 "Do you want to create it?</qt>", 0295 account.name(), 0296 parent.name()), 0297 i18n("Create security"), 0298 KMMYesNo::yes(), 0299 KMMYesNo::no(), 0300 dontShowAgain) 0301 == KMessageBox::PrimaryAction) { 0302 QPointer<KNewInvestmentWizard> dlg = new KNewInvestmentWizard; 0303 dlg->setName(account.name()); 0304 if (dlg->exec() == QDialog::Accepted) { 0305 dlg->createObjects(parent.id()); 0306 account = dlg->account(); 0307 } 0308 delete dlg; 0309 } else { 0310 // in case the user said no but turned on the don't show again selection, we will enable 0311 // the message no matter what. Otherwise, the user is not able to use this feature 0312 // in the future anymore. 0313 KMessageBox::enableMessage(dontShowAgain); 0314 } 0315 } 0316 0317 void KNewInvestmentWizard::editInvestment(const MyMoneyAccount& parent) 0318 { 0319 QPointer<KNewInvestmentWizard> dlg = new KNewInvestmentWizard(parent); 0320 if (dlg->exec() == QDialog::Accepted) 0321 dlg->createObjects(parent.id()); 0322 delete dlg; 0323 } 0324 0325 MyMoneyAccount KNewInvestmentWizard::account() const 0326 { 0327 Q_D(const KNewInvestmentWizard); 0328 return d->m_account; 0329 }