File indexing completed on 2024-06-09 05:03:28
0001 /* 0002 SPDX-FileCopyrightText: 2007 Thomas Baumgart <ipwizard@users.sourceforge.net> 0003 SPDX-FileCopyrightText: 2017 Łukasz Wojniłowicz <lukasz.wojnilowicz@gmail.com> 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "kaccounttypepage.h" 0008 #include "kaccounttypepage_p.h" 0009 0010 // ---------------------------------------------------------------------------- 0011 // QT Includes 0012 0013 #include <QDate> 0014 #include <QDialog> 0015 #include <QLabel> 0016 #include <QPointer> 0017 #include <QPushButton> 0018 0019 // ---------------------------------------------------------------------------- 0020 // KDE Includes 0021 0022 #include <KLineEdit> 0023 #include <KLocalizedString> 0024 #include <KMessageBox> 0025 0026 // ---------------------------------------------------------------------------- 0027 // Project Includes 0028 0029 #include "accountsmodel.h" 0030 #include "kbrokeragepage.h" 0031 #include "kcreditcardschedulepage.h" 0032 #include "kequitypriceupdatedlg.h" 0033 #include "kgeneralloaninfopage.h" 0034 #include "kguiutils.h" 0035 #include "khierarchypage.h" 0036 #include "kmymoneycurrencyselector.h" 0037 #include "kmymoneygeneralcombo.h" 0038 #include "kmymoneysettings.h" 0039 #include "kmymoneywizardpage.h" 0040 #include "knewaccountwizard.h" 0041 #include "knewaccountwizard_p.h" 0042 #include "mymoneyaccount.h" 0043 #include "mymoneyenums.h" 0044 #include "mymoneyfile.h" 0045 #include "mymoneymoney.h" 0046 #include "mymoneyprice.h" 0047 #include "mymoneysecurity.h" 0048 #include "wizardpage.h" 0049 0050 using namespace eMyMoney; 0051 0052 namespace NewAccountWizard 0053 { 0054 AccountTypePage::AccountTypePage(Wizard* wizard) : 0055 QWidget(wizard), 0056 WizardPage<Wizard>(*new AccountTypePagePrivate(wizard), StepAccount, this, wizard) 0057 { 0058 Q_D(AccountTypePage); 0059 d->ui->setupUi(this); 0060 d->m_showPriceWarning = true; 0061 d->ui->m_typeSelection->insertItem(i18n("Checking"), (int)Account::Type::Checkings, 0); 0062 d->ui->m_typeSelection->setItemIcon(0, Icons::get(Icon::Checking)); 0063 d->ui->m_typeSelection->insertItem(i18n("Savings"), (int)Account::Type::Savings, 1); 0064 d->ui->m_typeSelection->setItemIcon(1, Icons::get(Icon::Savings)); 0065 d->ui->m_typeSelection->insertItem(i18n("Credit Card"), (int)Account::Type::CreditCard, 2); 0066 d->ui->m_typeSelection->setItemIcon(2, Icons::get(Icon::CreditCard)); 0067 d->ui->m_typeSelection->insertItem(i18n("Cash"), (int)Account::Type::Cash, 3); 0068 d->ui->m_typeSelection->setItemIcon(3, Icons::get(Icon::Cash)); 0069 d->ui->m_typeSelection->insertItem(i18n("Loan"), (int)Account::Type::Loan, 4); 0070 d->ui->m_typeSelection->setItemIcon(4, Icons::get(Icon::Loan)); 0071 d->ui->m_typeSelection->insertItem(i18n("Investment"), (int)Account::Type::Investment, 5); 0072 d->ui->m_typeSelection->setItemIcon(5, Icons::get(Icon::Investment)); 0073 d->ui->m_typeSelection->insertItem(i18n("Asset"), (int)Account::Type::Asset, 6); 0074 d->ui->m_typeSelection->setItemIcon(6, Icons::get(Icon::Asset)); 0075 d->ui->m_typeSelection->insertItem(i18n("Liability"), (int)Account::Type::Liability, 7); 0076 d->ui->m_typeSelection->setItemIcon(7, Icons::get(Icon::Liability)); 0077 if (KMyMoneySettings::expertMode()) { 0078 d->ui->m_typeSelection->insertItem(i18n("Equity"), (int)Account::Type::Equity, 8); 0079 d->ui->m_typeSelection->setItemIcon(8, Icons::get(Icon::Equity)); 0080 } 0081 0082 d->ui->m_typeSelection->setCurrentItem((int)Account::Type::Checkings); 0083 0084 d->ui->m_currencyComboBox->setSecurity(MyMoneyFile::instance()->baseCurrency()); 0085 0086 d->m_mandatoryGroup->add(d->ui->m_accountName); 0087 d->m_mandatoryGroup->add(d->ui->m_conversionRate); 0088 0089 d->ui->m_conversionRate->setValue(MyMoneyMoney::ONE); 0090 slotUpdateCurrency(); 0091 0092 connect(d->ui->m_typeSelection, &KMyMoneyGeneralCombo::itemSelected, this, &AccountTypePage::slotUpdateType); 0093 connect(d->ui->m_currencyComboBox, static_cast<void (QComboBox::*)(int)>(&QComboBox::activated), this, &AccountTypePage::slotUpdateCurrency); 0094 /// @todo fix this logic with new amount edit logic (at least check) 0095 connect(d->ui->m_conversionRate, &AmountEdit::textChanged, this, &AccountTypePage::slotUpdateConversionRate); 0096 connect(d->ui->m_conversionRate, &AmountEdit::amountChanged, this, &AccountTypePage::slotPriceWarning); 0097 connect(d->ui->m_onlineQuote, &QAbstractButton::clicked, this, &AccountTypePage::slotGetOnlineQuote); 0098 } 0099 0100 AccountTypePage::~AccountTypePage() 0101 { 0102 } 0103 0104 void AccountTypePage::slotUpdateType(int i) 0105 { 0106 Q_D(AccountTypePage); 0107 hideShowPages(static_cast<Account::Type>(i)); 0108 const bool enabled = accountTypeSupportsOpeningBalance(static_cast<Account::Type>(i)); 0109 d->ui->m_openingBalance->setEnabled(enabled); 0110 d->ui->m_openingBalanceLabel->setEnabled(enabled); 0111 } 0112 0113 void AccountTypePage::hideShowPages(Account::Type accountType) const 0114 { 0115 Q_D(const AccountTypePage); 0116 bool hideSchedulePage = (accountType != Account::Type::CreditCard) 0117 && (accountType != Account::Type::Loan); 0118 bool hideLoanPage = (accountType != Account::Type::Loan); 0119 d->m_wizard->d_func()->setStepHidden(StepDetails, hideLoanPage); 0120 d->m_wizard->d_func()->setStepHidden(StepPayments, hideLoanPage); 0121 d->m_wizard->d_func()->setStepHidden(StepFees, hideLoanPage); 0122 d->m_wizard->d_func()->setStepHidden(StepSchedule, hideSchedulePage); 0123 d->m_wizard->d_func()->setStepHidden(StepPayout, (accountType != Account::Type::Loan)); 0124 d->m_wizard->d_func()->setStepHidden(StepBroker, accountType != Account::Type::Investment); 0125 d->m_wizard->d_func()->setStepHidden(StepParentAccount, accountType == Account::Type::Loan); 0126 // Force an update of the steps in case the list has changed 0127 d->m_wizard->reselectStep(); 0128 } 0129 0130 KMyMoneyWizardPage* AccountTypePage::nextPage() const 0131 { 0132 Q_D(const AccountTypePage); 0133 if (accountType() == Account::Type::Loan) 0134 return d->m_wizard->d_func()->m_generalLoanInfoPage; 0135 if (accountType() == Account::Type::CreditCard) 0136 return d->m_wizard->d_func()->m_schedulePage; 0137 if (accountType() == Account::Type::Investment) 0138 return d->m_wizard->d_func()->m_brokeragepage; 0139 return d->m_wizard->d_func()->m_hierarchyPage; 0140 } 0141 0142 QWidget* AccountTypePage::initialFocusWidget() const 0143 { 0144 Q_D(const AccountTypePage); 0145 return d->ui->m_accountName; 0146 } 0147 0148 void AccountTypePage::slotUpdateCurrency() 0149 { 0150 Q_D(AccountTypePage); 0151 MyMoneyAccount acc; 0152 acc.setAccountType(accountType()); 0153 0154 d->ui->m_openingBalance->setPrecision(MyMoneyMoney::denomToPrec(acc.fraction(currency()))); 0155 0156 bool show = d->ui->m_currencyComboBox->security().id() != MyMoneyFile::instance()->baseCurrency().id(); 0157 d->ui->m_conversionLabel->setVisible(show); 0158 d->ui->m_conversionRate->setVisible(show); 0159 d->ui->m_conversionExample->setVisible(show); 0160 d->ui->m_onlineQuote->setVisible(show); 0161 d->ui->m_conversionRate->setEnabled(show); // make sure to include/exclude in mandatoryGroup 0162 d->ui->m_conversionRate->setPrecision(d->ui->m_currencyComboBox->security().pricePrecision()); 0163 d->m_mandatoryGroup->changed(); 0164 slotUpdateConversionRate(d->ui->m_conversionRate->text()); 0165 } 0166 0167 void AccountTypePage::slotGetOnlineQuote() 0168 { 0169 Q_D(AccountTypePage); 0170 QString id = MyMoneyFile::instance()->baseCurrency().id() + ' ' + d->ui->m_currencyComboBox->security().id(); 0171 QPointer<KEquityPriceUpdateDlg> dlg = new KEquityPriceUpdateDlg(this, id); 0172 if (dlg->exec() == QDialog::Accepted) { 0173 const MyMoneyPrice &price = dlg->price(id); 0174 if (price.isValid()) { 0175 d->ui->m_conversionRate->setValue(price.rate(d->ui->m_currencyComboBox->security().id())); 0176 if (price.date() != d->ui->m_openingDate->date()) { 0177 priceWarning(true); 0178 } 0179 } 0180 } 0181 delete dlg; 0182 } 0183 0184 void AccountTypePage::slotPriceWarning() 0185 { 0186 priceWarning(false); 0187 } 0188 0189 void AccountTypePage::priceWarning(bool always) 0190 { 0191 Q_D(AccountTypePage); 0192 if (d->m_showPriceWarning || always) { 0193 KMessageBox::information(this, i18n("Please make sure to enter the correct conversion for the selected opening date. If you requested an online quote it might be provided for a different date."), i18n("Check date")); 0194 } 0195 d->m_showPriceWarning = false; 0196 } 0197 0198 void AccountTypePage::slotUpdateConversionRate(const QString& txt) 0199 { 0200 Q_D(AccountTypePage); 0201 d->ui->m_conversionExample->setText(i18n("1 %1 equals %2", MyMoneyFile::instance()->baseCurrency().tradingSymbol(), MyMoneyMoney(txt).formatMoney(d->ui->m_currencyComboBox->security().tradingSymbol(), d->ui->m_currencyComboBox->security().pricePrecision()))); 0202 } 0203 0204 bool AccountTypePage::isComplete() const 0205 { 0206 Q_D(const AccountTypePage); 0207 // check that the conversion rate is positive if enabled 0208 bool rc = !d->ui->m_conversionRate->isVisible() || (!d->ui->m_conversionRate->value().isZero() && !d->ui->m_conversionRate->value().isNegative()); 0209 if (!rc) { 0210 d->m_wizard->d_func()->m_nextButton->setToolTip(i18n("Conversion rate is not positive")); 0211 0212 } else { 0213 rc = KMyMoneyWizardPage::isComplete(); 0214 0215 if (!rc) { 0216 d->m_wizard->d_func()->m_nextButton->setToolTip(i18n("No account name supplied")); 0217 } 0218 } 0219 hideShowPages(accountType()); 0220 return rc; 0221 } 0222 0223 bool AccountTypePage::accountTypeSupportsOpeningBalance(Account::Type type) const 0224 { 0225 switch(type) { 0226 case Account::Type::Equity: 0227 case Account::Type::Investment: 0228 return false; 0229 default: 0230 break; 0231 } 0232 return true; 0233 } 0234 0235 Account::Type AccountTypePage::accountType() const 0236 { 0237 Q_D(const AccountTypePage); 0238 return static_cast<Account::Type>(d->ui->m_typeSelection->currentItem()); 0239 } 0240 0241 const MyMoneySecurity& AccountTypePage::currency() const 0242 { 0243 Q_D(const AccountTypePage); 0244 return d->ui->m_currencyComboBox->security(); 0245 } 0246 0247 void AccountTypePage::setAccount(const MyMoneyAccount& acc) 0248 { 0249 Q_D(AccountTypePage); 0250 if (acc.accountType() != Account::Type::Unknown) { 0251 if (acc.accountType() == Account::Type::AssetLoan) { 0252 d->ui->m_typeSelection->setCurrentItem((int)Account::Type::Loan); 0253 } else { 0254 d->ui->m_typeSelection->setCurrentItem((int)acc.accountType()); 0255 } 0256 } 0257 d->ui->m_openingDate->setDate(acc.openingDate()); 0258 d->ui->m_accountName->setText(acc.name()); 0259 d->m_parentAccountId = acc.parentAccountId(); 0260 } 0261 0262 MyMoneyAccount AccountTypePage::parentAccount() 0263 { 0264 Q_D(AccountTypePage); 0265 const auto file = MyMoneyFile::instance(); 0266 const auto acc = file->accountsModel()->itemById(d->m_parentAccountId); 0267 // in case we don't have a parent account or its group does 0268 // not match the selected account type, we use the corresponding 0269 // standard top level account 0270 if (acc.id().isEmpty() || (acc.accountGroup() != acc.accountGroup(accountType()))) { 0271 switch (accountType()) { 0272 case Account::Type::CreditCard: 0273 case Account::Type::Liability: 0274 case Account::Type::Loan: // Can be either but we return liability here 0275 return file->liability(); 0276 break; 0277 case Account::Type::Equity: 0278 return file->equity(); 0279 default: 0280 break; 0281 } 0282 return file->asset(); 0283 } 0284 return acc; 0285 } 0286 0287 bool AccountTypePage::allowsParentAccount() const 0288 { 0289 return accountType() != Account::Type::Loan; 0290 } 0291 }