diff --git a/kmymoney/wizards/newloanwizard/CMakeLists.txt b/kmymoney/wizards/newloanwizard/CMakeLists.txt --- a/kmymoney/wizards/newloanwizard/CMakeLists.txt +++ b/kmymoney/wizards/newloanwizard/CMakeLists.txt @@ -21,7 +21,7 @@ ) set (libnewloanwizard_a_UI - knewloanwizarddecl.ui + knewloanwizard.ui additionalfeeswizardpagedecl.ui loanamountwizardpagedecl.ui loanattributeswizardpagedecl.ui assetaccountwizardpagedecl.ui namewizardpagedecl.ui @@ -37,7 +37,7 @@ interesteditwizardpagedecl.ui schedulewizardpagedecl.ui interesttypewizardpagedecl.ui summaryeditwizardpagedecl.ui interestwizardpagedecl.ui summarywizardpagedecl.ui - knewloanwizarddecl.ui variableinterestdatewizardpagedecl.ui + knewloanwizard.ui variableinterestdatewizardpagedecl.ui lendborrowwizardpagedecl.ui ) diff --git a/kmymoney/wizards/newloanwizard/additionalfeeswizardpage.cpp b/kmymoney/wizards/newloanwizard/additionalfeeswizardpage.cpp --- a/kmymoney/wizards/newloanwizard/additionalfeeswizardpage.cpp +++ b/kmymoney/wizards/newloanwizard/additionalfeeswizardpage.cpp @@ -32,6 +32,7 @@ // Project Includes #include "knewloanwizard.h" +#include "knewloanwizard_p.h" #include "ksplittransactiondlg.h" #include "mymoneyfile.h" #include "mymoneyaccount.h" @@ -59,24 +60,24 @@ MyMoneyAccount account("Phony-ID", MyMoneyAccount()); QMap priceInfo; - QPointer dlg = new KSplitTransactionDlg(qobject_cast(wizard())->m_transaction, qobject_cast(wizard())->m_split, account, false, !field("borrowButton").toBool(), MyMoneyMoney(), priceInfo); + QPointer dlg = new KSplitTransactionDlg(qobject_cast(wizard())->d_func()->m_transaction, qobject_cast(wizard())->d_func()->m_split, account, false, !field("borrowButton").toBool(), MyMoneyMoney(), priceInfo); connect(dlg, SIGNAL(newCategory(MyMoneyAccount&)), this, SIGNAL(newCategory(MyMoneyAccount&))); if (dlg->exec() == QDialog::Accepted) { - qobject_cast(wizard())->m_transaction = dlg->transaction(); + qobject_cast(wizard())->d_func()->m_transaction = dlg->transaction(); // sum up the additional fees MyMoneyMoney fees; - foreach (const MyMoneySplit& it, qobject_cast(wizard())->m_transaction.splits()) { + foreach (const MyMoneySplit& it, qobject_cast(wizard())->d_func()->m_transaction.splits()) { if (it.accountId() != account.id()) { fees += it.value(); } } - setField("additionalCost", fees.formatMoney(qobject_cast(wizard())->m_account.fraction(MyMoneyFile::instance()->security(qobject_cast(wizard())->m_account.currencyId())))); + setField("additionalCost", fees.formatMoney(qobject_cast(wizard())->d_func()->m_account.fraction(MyMoneyFile::instance()->security(qobject_cast(wizard())->d_func()->m_account.currencyId())))); } delete dlg; - updatePeriodicPayment(qobject_cast(wizard())->m_account); + updatePeriodicPayment(qobject_cast(wizard())->d_func()->m_account); } void AdditionalFeesWizardPage::updatePeriodicPayment(const MyMoneyAccount& account) diff --git a/kmymoney/wizards/newloanwizard/effectivedatewizardpage.cpp b/kmymoney/wizards/newloanwizard/effectivedatewizardpage.cpp --- a/kmymoney/wizards/newloanwizard/effectivedatewizardpage.cpp +++ b/kmymoney/wizards/newloanwizard/effectivedatewizardpage.cpp @@ -30,6 +30,7 @@ // Project Includes #include "knewloanwizard.h" +#include "mymoneyaccountloan.h" EffectiveDateWizardPage::EffectiveDateWizardPage(QWidget *parent) : EffectiveDateWizardPageDecl(parent) diff --git a/kmymoney/wizards/newloanwizard/interestcategorywizardpage.cpp b/kmymoney/wizards/newloanwizard/interestcategorywizardpage.cpp --- a/kmymoney/wizards/newloanwizard/interestcategorywizardpage.cpp +++ b/kmymoney/wizards/newloanwizard/interestcategorywizardpage.cpp @@ -34,7 +34,9 @@ #include "knewaccountdlg.h" #include "mymoneyfile.h" +#include "mymoneyaccount.h" #include "icons/icons.h" +#include "mymoneyexception.h" using namespace Icons; @@ -79,7 +81,7 @@ } acc.setParentAccountId(base.id()); - QPointer dlg = new KNewAccountDlg(acc, true, true); + QPointer dlg = new KNewAccountDlg(acc, true, true, nullptr, QString()); if (dlg->exec() == QDialog::Accepted) { acc = dlg->account(); diff --git a/kmymoney/wizards/newloanwizard/keditloanwizard.h b/kmymoney/wizards/newloanwizard/keditloanwizard.h --- a/kmymoney/wizards/newloanwizard/keditloanwizard.h +++ b/kmymoney/wizards/newloanwizard/keditloanwizard.h @@ -9,6 +9,7 @@ John C Thomas Baumgart Kevin Tambascio + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ /*************************************************************************** @@ -34,17 +35,15 @@ #include "knewloanwizard.h" -class MyMoneyAccount; - /** * @author Thomas Baumgart */ - +class KEditLoanWizardPrivate; class KEditLoanWizard : public KNewLoanWizard { Q_OBJECT public: - explicit KEditLoanWizard(const MyMoneyAccount& account, QWidget *parent = 0); + explicit KEditLoanWizard(const MyMoneyAccount& account, QWidget *parent = nullptr); ~KEditLoanWizard(); /** @@ -75,10 +74,8 @@ void updateEditSummary(); private: - //MyMoneyAccountLoan m_account; - MyMoneySchedule m_schedule; - int m_lastSelection; - bool m_fullyRepayLoan; + Q_DISABLE_COPY(KEditLoanWizard) + Q_DECLARE_PRIVATE(KEditLoanWizard) }; #endif diff --git a/kmymoney/wizards/newloanwizard/keditloanwizard.cpp b/kmymoney/wizards/newloanwizard/keditloanwizard.cpp --- a/kmymoney/wizards/newloanwizard/keditloanwizard.cpp +++ b/kmymoney/wizards/newloanwizard/keditloanwizard.cpp @@ -9,6 +9,7 @@ John C Thomas Baumgart Kevin Tambascio + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ /*************************************************************************** @@ -29,6 +30,7 @@ #include #include #include +#include // ---------------------------------------------------------------------------- // KDE Includes @@ -40,53 +42,71 @@ // Project Includes #include "knewloanwizard.h" +#include "knewloanwizard_p.h" #include "kmymoneylineedit.h" #include "kmymoneyedit.h" #include "kmymoneyaccountselector.h" #include "mymoneyfile.h" #include "mymoneyinstitution.h" #include "mymoneyaccount.h" #include "mymoneyaccountloan.h" #include "mymoneypayee.h" +#include "mymoneyschedule.h" + +class KEditLoanWizardPrivate : public KNewLoanWizardPrivate +{ + Q_DISABLE_COPY(KEditLoanWizardPrivate) + +public: + KEditLoanWizardPrivate(KEditLoanWizard *qq) : + KNewLoanWizardPrivate(qq) + { + } + + MyMoneySchedule m_schedule; + int m_lastSelection; + bool m_fullyRepayLoan; +}; KEditLoanWizard::KEditLoanWizard(const MyMoneyAccount& account, QWidget *parent) : - KNewLoanWizard(parent) + KNewLoanWizard(*new KEditLoanWizardPrivate(this), parent) { - MyMoneyFile* file = MyMoneyFile::instance(); + Q_D(KEditLoanWizard); + auto file = MyMoneyFile::instance(); setWindowTitle(i18n("Edit loan wizard")); - m_account = account; + d->m_account = account; try { - QString id = m_account.value("schedule"); - m_schedule = file->schedule(id); + QString id = d->m_account.value("schedule"); + d->m_schedule = file->schedule(id); } catch (const MyMoneyException &) { } - m_lastSelection = -1; + d->m_lastSelection = -1; - loadWidgets(m_account); + loadWidgets(d->m_account); - if (m_account.openingDate() > QDate::currentDate()) { + if (d->m_account.openingDate() > QDate::currentDate()) { //FIXME: port - m_effectiveDatePage->m_effectiveDateNoteLabel->setText(QString("\n") + i18n( + d->ui->m_effectiveDatePage->m_effectiveDateNoteLabel->setText(QString("\n") + i18n( "Note: you will not be able to modify this account today, because the opening date \"%1\" is in the future. " - "Please revisit this dialog when the time has come.", QLocale().toString(m_account.openingDate()))); + "Please revisit this dialog when the time has come.", QLocale().toString(d->m_account.openingDate()))); } else { - m_effectiveDatePage->m_effectiveDateNoteLabel->hide(); + d->ui->m_effectiveDatePage->m_effectiveDateNoteLabel->hide(); } // turn off all pages that are contained here for derived classes - m_pages.clearBit(Page_Intro); - m_pages.clearBit(Page_NewGeneralInfo); - m_pages.clearBit(Page_LendBorrow); - m_pages.clearBit(Page_Name); - m_pages.clearBit(Page_NewCalculateLoan); - m_pages.clearBit(Page_NewPayments); + d->m_pages.clearBit(Page_Intro); + d->m_pages.clearBit(Page_NewGeneralInfo); + d->m_pages.clearBit(Page_LendBorrow); + d->m_pages.clearBit(Page_Name); + d->m_pages.clearBit(Page_NewCalculateLoan); + d->m_pages.clearBit(Page_NewPayments); removePage(Page_AssetAccount); - m_assetAccountPage = 0; + d->ui->m_assetAccountPage = 0; // turn on all pages that are contained here for derived classes - m_pages.setBit(Page_EditIntro); - m_pages.setBit(Page_EditSelection); + d->m_pages.setBit(Page_EditIntro); + d->m_pages.setBit(Page_EditSelection); // make sure, we show the correct start page setStartId(Page_EditIntro); @@ -98,50 +118,51 @@ void KEditLoanWizard::loadWidgets(const MyMoneyAccount& /* account */) { - MyMoneyFile* file = MyMoneyFile::instance(); + Q_D(KEditLoanWizard); + auto file = MyMoneyFile::instance(); QString paymentAccountId, interestAccountId; //FIXME: port - m_namePage->m_nameEdit->loadText(m_account.name()); - m_loanAmountPage->m_loanAmountEdit->loadText(m_account.loanAmount().formatMoney(m_account.fraction(MyMoneyFile::instance()->security(m_account.currencyId())))); - m_finalPaymentPage->m_finalPaymentEdit->loadText(m_account.finalPayment().formatMoney(m_account.fraction(MyMoneyFile::instance()->security(m_account.currencyId())))); - setField("firstDueDateEdit", m_account.openingDate()); + d->ui->m_namePage->m_nameEdit->loadText(d->m_account.name()); + d->ui->m_loanAmountPage->m_loanAmountEdit->loadText(d->m_account.loanAmount().formatMoney(d->m_account.fraction(MyMoneyFile::instance()->security(d->m_account.currencyId())))); + d->ui->m_finalPaymentPage->m_finalPaymentEdit->loadText(d->m_account.finalPayment().formatMoney(d->m_account.fraction(MyMoneyFile::instance()->security(d->m_account.currencyId())))); + setField("firstDueDateEdit", d->m_account.openingDate()); //FIXME: port - if (m_account.fixedInterestRate()) { - m_interestTypePage->m_fixedInterestButton->click(); + if (d->m_account.fixedInterestRate()) { + d->ui->m_interestTypePage->m_fixedInterestButton->click(); } else { - m_interestTypePage->m_variableInterestButton->click(); + d->ui->m_interestTypePage->m_variableInterestButton->click(); } - QString institutionName = file->institution(m_account.institutionId()).name(); - m_loanAttributesPage->setInstitution(institutionName); + QString institutionName = file->institution(d->m_account.institutionId()).name(); + d->ui->m_loanAttributesPage->setInstitution(institutionName); MyMoneyMoney ir; - if (m_schedule.startDate() > QDate::currentDate()) { - ir = m_account.interestRate(m_schedule.startDate()); + if (d->m_schedule.startDate() > QDate::currentDate()) { + ir = d->m_account.interestRate(d->m_schedule.startDate()); } else { - ir = m_account.interestRate(QDate::currentDate()); + ir = d->m_account.interestRate(QDate::currentDate()); } //FIXME: port - m_interestPage->m_interestRateEdit->loadText(ir.formatMoney("", 3)); - m_interestPage->m_interestRateEdit->setPrecision(3); - m_interestEditPage->m_newInterestRateEdit->loadText(ir.formatMoney("", 3)); - m_interestEditPage->m_newInterestRateEdit->setPrecision(3); - m_interestEditPage->m_interestRateLabel->setText(QString(" ") + ir.formatMoney("", 3) + QString("%")); + d->ui->m_interestPage->m_interestRateEdit->loadText(ir.formatMoney(QString(), 3)); + d->ui->m_interestPage->m_interestRateEdit->setPrecision(3); + d->ui->m_interestEditPage->m_newInterestRateEdit->loadText(ir.formatMoney(QString(), 3)); + d->ui->m_interestEditPage->m_newInterestRateEdit->setPrecision(3); + d->ui->m_interestEditPage->m_interestRateLabel->setText(QString(" ") + ir.formatMoney(QString(), 3) + QString("%")); - m_paymentFrequencyPage->m_paymentFrequencyUnitEdit->setCurrentIndex(m_paymentFrequencyPage->m_paymentFrequencyUnitEdit->findData(QVariant((int)m_schedule.occurrencePeriod()), Qt::UserRole, Qt::MatchExactly)); - m_durationPage->updateTermWidgets(m_account.term()); + d->ui->m_paymentFrequencyPage->m_paymentFrequencyUnitEdit->setCurrentIndex(d->ui->m_paymentFrequencyPage->m_paymentFrequencyUnitEdit->findData(QVariant((int)d->m_schedule.occurrencePeriod()), Qt::UserRole, Qt::MatchExactly)); + d->ui->m_durationPage->updateTermWidgets(d->m_account.term()); // the base payment (amortization and interest) is determined // by adding all splits that are not automatically calculated. // If the loan is a liability, we reverse the sign at the end MyMoneyMoney basePayment; MyMoneyMoney addPayment; - m_transaction = m_schedule.transaction(); + d->m_transaction = d->m_schedule.transaction(); - foreach (const MyMoneySplit& it_s, m_schedule.transaction().splits()) { + foreach (const MyMoneySplit& it_s, d->m_schedule.transaction().splits()) { MyMoneyAccount acc = file->account(it_s.accountId()); // if it's the split that references the source/dest // of the money, we check if we borrow or loan money @@ -171,9 +192,9 @@ // remove this split with one that will be replaced // later and has a phony id - m_transaction.removeSplit(it_s); - m_split.clearId(); - m_transaction.addSplit(m_split); + d->m_transaction.removeSplit(it_s); + d->m_split.clearId(); + d->m_transaction.addSplit(d->m_split); } if (it_s.action() == MyMoneySplit::ActionInterest) { @@ -185,7 +206,7 @@ } else { // remove the splits which should not show up // for additional fees - m_transaction.removeSplit(it_s); + d->m_transaction.removeSplit(it_s); } } @@ -198,42 +219,43 @@ // load account selection widgets now that we know if // we borrow or lend money - loadAccountList(); + d->loadAccountList(); - int fraction = m_account.fraction(MyMoneyFile::instance()->security(m_account.currencyId())); + int fraction = d->m_account.fraction(MyMoneyFile::instance()->security(d->m_account.currencyId())); //FIXME: port - m_paymentPage->m_paymentEdit->loadText(basePayment.formatMoney(fraction)); - m_paymentEditPage->m_newPaymentEdit->loadText(basePayment.formatMoney(fraction)); - m_paymentEditPage->m_paymentLabel->setText(QString(" ") + basePayment.formatMoney(fraction)); + d->ui->m_paymentPage->m_paymentEdit->loadText(basePayment.formatMoney(fraction)); + d->ui->m_paymentEditPage->m_newPaymentEdit->loadText(basePayment.formatMoney(fraction)); + d->ui->m_paymentEditPage->m_paymentLabel->setText(QString(" ") + basePayment.formatMoney(fraction)); setField("additionalCost", addPayment.formatMoney(fraction)); - m_interestCategoryPage->m_interestAccountEdit->setSelected(interestAccountId); - m_schedulePage->m_paymentAccountEdit->setSelected(paymentAccountId); - setField("nextDueDateEdit", m_schedule.nextPayment()); + d->ui->m_interestCategoryPage->m_interestAccountEdit->setSelected(interestAccountId); + d->ui->m_schedulePage->m_paymentAccountEdit->setSelected(paymentAccountId); + setField("nextDueDateEdit", d->m_schedule.nextPayment()); int changeFrequencyUnit; - int amt = m_account.interestChangeFrequency(&changeFrequencyUnit); + int amt = d->m_account.interestChangeFrequency(&changeFrequencyUnit); if (amt != -1) { setField("interestFrequencyAmountEdit", amt); setField("interestFrequencyUnitEdit", changeFrequencyUnit); } // keep track, if the loan should be fully repayed - m_fullyRepayLoan = m_account.finalPayment() < basePayment; + d->m_fullyRepayLoan = d->m_account.finalPayment() < basePayment; - updateLoanInfo(); + d->updateLoanInfo(); } bool KEditLoanWizard::validateCurrentPage() { - bool dontLeavePage = false; + Q_D(KEditLoanWizard); + auto dontLeavePage = false; //FIXME: port m_lastSelection - QAbstractButton* button = m_editSelectionPage->m_selectionButtonGroup->button(m_lastSelection); + QAbstractButton* button = d->ui->m_editSelectionPage->m_selectionButtonGroup->button(d->m_lastSelection); - if (currentPage() == m_editSelectionPage) { + if (currentPage() == d->ui->m_editSelectionPage) { if (button != 0 - && m_lastSelection != m_editSelectionPage->m_selectionButtonGroup->checkedId()) { + && d->m_lastSelection != d->ui->m_editSelectionPage->m_selectionButtonGroup->checkedId()) { QString errMsg = i18n( "Your previous selection was \"%1\". If you select another option, " @@ -243,7 +265,7 @@ if (KMessageBox::questionYesNo(this, errMsg) == KMessageBox::No) { dontLeavePage = true; } else { - loadWidgets(m_account); + loadWidgets(d->m_account); } } @@ -253,108 +275,108 @@ // and load the widgets with the current values // general info - m_pages.clearBit(Page_Name); - m_pages.clearBit(Page_InterestType); - m_pages.clearBit(Page_PreviousPayments); - m_pages.clearBit(Page_RecordPayment); - m_pages.clearBit(Page_VariableInterestDate); - m_pages.clearBit(Page_FirstPayment); + d->m_pages.clearBit(Page_Name); + d->m_pages.clearBit(Page_InterestType); + d->m_pages.clearBit(Page_PreviousPayments); + d->m_pages.clearBit(Page_RecordPayment); + d->m_pages.clearBit(Page_VariableInterestDate); + d->m_pages.clearBit(Page_FirstPayment); // loan calculation - m_pages.clearBit(Page_PaymentEdit); - m_pages.clearBit(Page_InterestEdit); - m_pages.clearBit(Page_PaymentFrequency); - m_pages.clearBit(Page_InterestCalculation); - m_pages.clearBit(Page_LoanAmount); - m_pages.clearBit(Page_Interest); - m_pages.clearBit(Page_Duration); - m_pages.clearBit(Page_Payment); - m_pages.clearBit(Page_FinalPayment); - m_pages.clearBit(Page_CalculationOverview); + d->m_pages.clearBit(Page_PaymentEdit); + d->m_pages.clearBit(Page_InterestEdit); + d->m_pages.clearBit(Page_PaymentFrequency); + d->m_pages.clearBit(Page_InterestCalculation); + d->m_pages.clearBit(Page_LoanAmount); + d->m_pages.clearBit(Page_Interest); + d->m_pages.clearBit(Page_Duration); + d->m_pages.clearBit(Page_Payment); + d->m_pages.clearBit(Page_FinalPayment); + d->m_pages.clearBit(Page_CalculationOverview); // payment - m_pages.clearBit(Page_InterestCategory); - m_pages.clearBit(Page_AdditionalFees); - m_pages.clearBit(Page_Schedule); - m_pages.setBit(Page_Summary); + d->m_pages.clearBit(Page_InterestCategory); + d->m_pages.clearBit(Page_AdditionalFees); + d->m_pages.clearBit(Page_Schedule); + d->m_pages.setBit(Page_Summary); // Attributes - m_pages.clearBit(Page_LoanAttributes); + d->m_pages.clearBit(Page_LoanAttributes); - m_pages.setBit(Page_EffectiveDate); + d->m_pages.setBit(Page_EffectiveDate); if (page(Page_Summary) != 0) { removePage(Page_Summary); } if (field("editInterestRateButton").toBool()) { - m_pages.setBit(Page_PaymentFrequency); - m_pages.setBit(Page_InterestType); - m_pages.setBit(Page_VariableInterestDate); - m_pages.setBit(Page_PaymentEdit); - m_pages.setBit(Page_InterestEdit); - m_pages.setBit(Page_InterestCategory); - m_pages.setBit(Page_Schedule); - m_pages.setBit(Page_SummaryEdit); + d->m_pages.setBit(Page_PaymentFrequency); + d->m_pages.setBit(Page_InterestType); + d->m_pages.setBit(Page_VariableInterestDate); + d->m_pages.setBit(Page_PaymentEdit); + d->m_pages.setBit(Page_InterestEdit); + d->m_pages.setBit(Page_InterestCategory); + d->m_pages.setBit(Page_Schedule); + d->m_pages.setBit(Page_SummaryEdit); } else if (field("editOtherCostButton").toBool()) { - m_pages.setBit(Page_PaymentFrequency); - m_pages.setBit(Page_AdditionalFees); - m_pages.setBit(Page_InterestCategory); - m_pages.setBit(Page_Schedule); - m_pages.setBit(Page_SummaryEdit); + d->m_pages.setBit(Page_PaymentFrequency); + d->m_pages.setBit(Page_AdditionalFees); + d->m_pages.setBit(Page_InterestCategory); + d->m_pages.setBit(Page_Schedule); + d->m_pages.setBit(Page_SummaryEdit); } else if (field("editOtherInfoButton").toBool()) { - m_pages.setBit(Page_Name); - m_pages.setBit(Page_InterestCalculation); - m_pages.setBit(Page_Interest); - m_pages.setBit(Page_Duration); - m_pages.setBit(Page_Payment); - m_pages.setBit(Page_FinalPayment); - m_pages.setBit(Page_CalculationOverview); - m_pages.setBit(Page_InterestCategory); - m_pages.setBit(Page_AdditionalFees); - m_pages.setBit(Page_Schedule); - m_pages.clearBit(Page_SummaryEdit); - setPage(Page_Summary, m_summaryPage); - m_pages.setBit(Page_Summary); + d->m_pages.setBit(Page_Name); + d->m_pages.setBit(Page_InterestCalculation); + d->m_pages.setBit(Page_Interest); + d->m_pages.setBit(Page_Duration); + d->m_pages.setBit(Page_Payment); + d->m_pages.setBit(Page_FinalPayment); + d->m_pages.setBit(Page_CalculationOverview); + d->m_pages.setBit(Page_InterestCategory); + d->m_pages.setBit(Page_AdditionalFees); + d->m_pages.setBit(Page_Schedule); + d->m_pages.clearBit(Page_SummaryEdit); + setPage(Page_Summary, d->ui->m_summaryPage); + d->m_pages.setBit(Page_Summary); } else if (field("editAttributesButton").toBool()) { - m_pages.setBit(Page_LoanAttributes); - m_pages.clearBit(Page_EffectiveDate); + d->m_pages.setBit(Page_LoanAttributes); + d->m_pages.clearBit(Page_EffectiveDate); } else { qWarning("%s,%d: This should never happen", __FILE__, __LINE__); } - m_lastSelection = m_editSelectionPage->m_selectionButtonGroup->checkedId(); + d->m_lastSelection = d->ui->m_editSelectionPage->m_selectionButtonGroup->checkedId(); } // if(!dontLeavePage) - } else if (currentPage() == m_additionalFeesPage) { + } else if (currentPage() == d->ui->m_additionalFeesPage) { if (field("editOtherCostButton").toBool()) { - updateLoanInfo(); + d->updateLoanInfo(); updateEditSummary(); } - } else if (currentPage() == m_interestEditPage) { + } else if (currentPage() == d->ui->m_interestEditPage) { // copy the necessary data to the widgets used for calculation //FIXME: port to fields - m_interestPage->m_interestRateEdit->setValue(field("newInterestRateEdit").value()); - m_paymentPage->m_paymentEdit->setValue(field("newPaymentEdit").value()); + d->ui->m_interestPage->m_interestRateEdit->setValue(field("newInterestRateEdit").value()); + d->ui->m_paymentPage->m_paymentEdit->setValue(field("newPaymentEdit").value()); // if interest rate and payment amount is given, then force // the term to be recalculated. The final payment is adjusted to // 0 if the loan was ment to be fully repayed - m_durationPage->updateTermWidgets(m_account.term()); + d->ui->m_durationPage->updateTermWidgets(d->m_account.term()); if (field("interestRateEditValid").toBool() && field("paymentEditValid").toBool()) { // if there's an amortization going on, we can evaluate // the new term. If the amortization is 0 (interest only // payments) then we keep the term as entered by the user. if (field("loanAmountEdit").value() != field("finalPaymentEdit").value()) { setField("durationValueEdit", 0); } - if (m_fullyRepayLoan) - m_finalPaymentPage->m_finalPaymentEdit->loadText(MyMoneyMoney().formatMoney(m_account.fraction(MyMoneyFile::instance()->security(m_account.currencyId())))); + if (d->m_fullyRepayLoan) + d->ui->m_finalPaymentPage->m_finalPaymentEdit->loadText(MyMoneyMoney().formatMoney(d->m_account.fraction(MyMoneyFile::instance()->security(d->m_account.currencyId())))); } /* @@ -388,39 +410,40 @@ m_loanAmountEdit->setText(balance.formatMoney()); */ // now re-calculate the figures - dontLeavePage = !calculateLoan(); + dontLeavePage = !d->calculateLoan(); // reset the original loan amount to the widget //FIXME: port to fields - m_loanAmountPage->m_loanAmountEdit->setValue(m_account.loanAmount()); + d->ui->m_loanAmountPage->m_loanAmountEdit->setValue(d->m_account.loanAmount()); if (!dontLeavePage) { - updateLoanInfo(); + d->updateLoanInfo(); updateEditSummary(); } } if (!dontLeavePage) dontLeavePage = ! KNewLoanWizard::validateCurrentPage(); // These might have been set by KNewLoanWizard - m_pages.clearBit(Page_PreviousPayments); - m_pages.clearBit(Page_RecordPayment); + d->m_pages.clearBit(Page_PreviousPayments); + d->m_pages.clearBit(Page_RecordPayment); if (dontLeavePage) return false; // we never need to show this page - if (currentPage() == m_previousPaymentsPage) + if (currentPage() == d->ui->m_previousPaymentsPage) dontLeavePage = KNewLoanWizard::validateCurrentPage(); return ! dontLeavePage; } void KEditLoanWizard::updateEditSummary() { + Q_D(KEditLoanWizard); // calculate the number of affected transactions - MyMoneyTransactionFilter filter(m_account.id()); + MyMoneyTransactionFilter filter(d->m_account.id()); filter.setDateFilter(field("effectiveChangeDateEdit").toDate(), QDate()); int count = 0; @@ -446,27 +469,29 @@ const MyMoneySchedule KEditLoanWizard::schedule() const { - MyMoneySchedule sched = m_schedule; + Q_D(const KEditLoanWizard); + MyMoneySchedule sched = d->m_schedule; sched.setTransaction(transaction()); sched.setOccurrence(eMyMoney::Schedule::Occurrence(field("paymentFrequencyUnitEdit").toInt())); - if (field("nextDueDateEdit").toDate() < m_schedule.startDate()) + if (field("nextDueDateEdit").toDate() < d->m_schedule.startDate()) sched.setStartDate(field("nextDueDateEdit").toDate()); return sched; } const MyMoneyAccount KEditLoanWizard::account() const { - MyMoneyAccountLoan acc(m_account); + Q_D(const KEditLoanWizard); + MyMoneyAccountLoan acc(d->m_account); if (field("interestOnReceptionButton").toBool()) acc.setInterestCalculation(MyMoneyAccountLoan::paymentReceived); else acc.setInterestCalculation(MyMoneyAccountLoan::paymentDue); - MyMoneyFile *file = MyMoneyFile::instance(); + auto file = MyMoneyFile::instance(); - QString institution = m_loanAttributesPage->m_qcomboboxInstitutions->currentText(); + QString institution = d->ui->m_loanAttributesPage->m_qcomboboxInstitutions->currentText(); if (institution != i18n("(No Institution)")) { QList list; file->institutionList(list); @@ -482,7 +507,7 @@ acc.setFixedInterestRate(field("fixedInterestButton").toBool()); acc.setFinalPayment(field("finalPaymentEdit").value()); - acc.setTerm(m_durationPage->term()); + acc.setTerm(d->ui->m_durationPage->term()); acc.setPeriodicPayment(field("paymentEdit").value()); acc.setInterestRate(field("effectiveChangeDateEdit").toDate(), field("interestRateEdit").value()); @@ -499,10 +524,11 @@ const MyMoneyTransaction KEditLoanWizard::transaction() const { - MyMoneyTransaction t = KNewLoanWizard::transaction(); - MyMoneySplit s = t.splitByAccount(QString("Phony-ID")); + Q_D(const KEditLoanWizard); + auto t = d->transaction(); + auto s = t.splitByAccount(QString("Phony-ID")); - s.setAccountId(m_account.id()); + s.setAccountId(d->m_account.id()); t.modifySplit(s); return t; diff --git a/kmymoney/wizards/newloanwizard/knewloanwizard.h b/kmymoney/wizards/newloanwizard/knewloanwizard.h --- a/kmymoney/wizards/newloanwizard/knewloanwizard.h +++ b/kmymoney/wizards/newloanwizard/knewloanwizard.h @@ -26,20 +26,20 @@ // ---------------------------------------------------------------------------- // QT Includes -#include #include // ---------------------------------------------------------------------------- // KDE Includes // ---------------------------------------------------------------------------- // Project Includes -#include "ui_knewloanwizarddecl.h" -#include "mymoneyschedule.h" -#include "mymoneyaccountloan.h" -#include "mymoneysplit.h" -#include "mymoneytransaction.h" +class QString; + +class MyMoneyAccount; +class MyMoneySchedule; +class MyMoneyAccountLoan; +class MyMoneyTransaction; /** * @author Thomas Baumgart @@ -54,16 +54,8 @@ * created loan. * */ -class MyMoneyAccountLoan; -class KNewLoanWizardDecl : public QWizard, public Ui::KNewLoanWizardDecl -{ -public: - KNewLoanWizardDecl(QWidget *parent) : QWizard(parent) { - setupUi(this); - } -}; - -class KNewLoanWizard : public KNewLoanWizardDecl +class KNewLoanWizardPrivate; +class KNewLoanWizard : public QWizard { Q_OBJECT @@ -83,7 +75,7 @@ Page_AssetAccount, Page_Summary }; - KNewLoanWizard(QWidget *parent = 0); + explicit KNewLoanWizard(QWidget *parent = nullptr); ~KNewLoanWizard(); /** @@ -130,31 +122,11 @@ */ int nextId() const; -protected: - /** - * This method returns the transaction that is stored within - * the schedule. See schedule(). - * - * @return MyMoneyTransaction object to be used within the schedule - */ - MyMoneyTransaction transaction() const; - protected slots: // void slotNewPayee(const QString&); void slotReloadEditWidgets(); -protected: - void loadAccountList(); - void resetCalculator(); - void updateLoanAmount(); - void updateInterestRate(); - void updateDuration(); - void updatePayment(); - void updateFinalPayment(); - void updateLoanInfo(); - int calculateLoan(); - signals: /** * This signal is emitted, when a new category name has been @@ -182,10 +154,12 @@ void createPayee(const QString& txt, QString& id); protected: - MyMoneyAccountLoan m_account; - MyMoneyTransaction m_transaction; - MyMoneySplit m_split; - QBitArray m_pages; + const QScopedPointer d_ptr; + KNewLoanWizard(KNewLoanWizardPrivate &dd, QWidget *parent); + +private: + Q_DISABLE_COPY(KNewLoanWizard) + Q_DECLARE_PRIVATE(KNewLoanWizard) }; #endif diff --git a/kmymoney/wizards/newloanwizard/knewloanwizard.cpp b/kmymoney/wizards/newloanwizard/knewloanwizard.cpp --- a/kmymoney/wizards/newloanwizard/knewloanwizard.cpp +++ b/kmymoney/wizards/newloanwizard/knewloanwizard.cpp @@ -21,292 +21,138 @@ ***************************************************************************/ #include "knewloanwizard.h" +#include "knewloanwizard_p.h" // ---------------------------------------------------------------------------- // QT Includes #include -#include // ---------------------------------------------------------------------------- // KDE Includes -#include -#include - // ---------------------------------------------------------------------------- // Project Includes -#include "kmymoneyutils.h" #include "kmymoneydateinput.h" #include "kmymoneyedit.h" #include "kmymoneyaccountselector.h" -#include "kmymoneysettings.h" -#include "mymoneyfinancialcalculator.h" -#include "mymoneyfile.h" -#include "mymoneyaccountloan.h" #include "mymoneypayee.h" KNewLoanWizard::KNewLoanWizard(QWidget *parent) : - KNewLoanWizardDecl(parent), m_pages(Page_Summary + 1, true) + QWizard(parent), + d_ptr(new KNewLoanWizardPrivate(this)) { - setModal(true); - - KMyMoneyMVCCombo::setSubstringSearchForChildren(m_namePage, !KMyMoneySettings::stringMatchFromStart()); - - // make sure, the back button does not clear fields - setOption(QWizard::IndependentPages, true); - - // connect(m_payeeEdit, SIGNAL(newPayee(QString)), this, SLOT(slotNewPayee(QString))); - connect(m_namePage->m_payeeEdit, SIGNAL(createItem(QString,QString&)), this, SIGNAL(createPayee(QString,QString&))); - - connect(m_additionalFeesPage, SIGNAL(newCategory(MyMoneyAccount&)), this, SIGNAL(newCategory(MyMoneyAccount&))); - - connect(MyMoneyFile::instance(), SIGNAL(dataChanged()), this, SLOT(slotReloadEditWidgets())); - - resetCalculator(); - - slotReloadEditWidgets(); - - // As default we assume a liability loan, with fixed interest rate, - // with a first payment due on the 30th of this month. All payments - // should be recorded and none have been made so far. - - //FIXME: port - m_firstPaymentPage->m_firstDueDateEdit->loadDate(QDate(QDate::currentDate().year(), QDate::currentDate().month(), 30)); - - // FIXME: we currently only support interest calculation on reception - m_pages.clearBit(Page_InterestCalculation); - - // turn off all pages that are contained here for derived classes - m_pages.clearBit(Page_EditIntro); - m_pages.clearBit(Page_EditSelection); - m_pages.clearBit(Page_EffectiveDate); - m_pages.clearBit(Page_PaymentEdit); - m_pages.clearBit(Page_InterestEdit); - m_pages.clearBit(Page_SummaryEdit); - - // for now, we don't have online help :-( - setOption(QWizard::HaveHelpButton, false); - - // setup a phony transaction for additional fee processing - m_account = MyMoneyAccount("Phony-ID", MyMoneyAccount()); - m_split.setAccountId(m_account.id()); - m_split.setValue(MyMoneyMoney()); - m_transaction.addSplit(m_split); + Q_D(KNewLoanWizard); + d->init(); +} - KMyMoneyUtils::updateWizardButtons(this); +KNewLoanWizard::KNewLoanWizard(KNewLoanWizardPrivate &dd, QWidget *parent) : + QWizard(parent), + d_ptr(&dd) +{ + Q_D(KNewLoanWizard); + d->init(); } KNewLoanWizard::~KNewLoanWizard() { } const MyMoneyAccountLoan KNewLoanWizard::account() const { - return m_account; + Q_D(const KNewLoanWizard); + return d->m_account; } int KNewLoanWizard::nextId() const { + Q_D(const KNewLoanWizard); // Starting from the current page, look for the first enabled page // and return that value // If the end of the list is encountered first, then return -1. - for (int i = currentId() + 1; i < m_pages.size() && i < pageIds().size(); ++i) { - if (m_pages.testBit(i)) + for (int i = currentId() + 1; i < d->m_pages.size() && i < pageIds().size(); ++i) { + if (d->m_pages.testBit(i)) return pageIds()[i]; } return -1; } -void KNewLoanWizard::resetCalculator() -{ - m_loanAmountPage->resetCalculator(); - m_interestPage->resetCalculator(); - m_durationPage->resetCalculator(); - m_paymentPage->resetCalculator(); - m_finalPaymentPage->resetCalculator(); - - setField("additionalCost", MyMoneyMoney().formatMoney(m_account.fraction(MyMoneyFile::instance()->security(m_account.currencyId())))); -} - -void KNewLoanWizard::updateLoanAmount() -{ - QString txt; - //FIXME: port - if (! field("loanAmountEditValid").toBool()) { - txt = QString("<") + i18n("calculate") + QString(">"); - } else { - txt = field("loanAmountEdit").value().formatMoney(m_account.fraction(MyMoneyFile::instance()->security(m_account.currencyId()))); - } - setField("loanAmount1", txt); - setField("loanAmount2", txt); - setField("loanAmount3", txt); - setField("loanAmount4", txt); - setField("loanAmount5", txt); -} - -void KNewLoanWizard::updateInterestRate() -{ - QString txt; - //FIXME: port - if (! field("interestRateEditValid").toBool()) { - txt = QString("<") + i18n("calculate") + QString(">"); - } else { - txt = field("interestRateEdit").value().formatMoney("", 3) + QString("%"); - } - setField("interestRate1", txt); - setField("interestRate2", txt); - setField("interestRate3", txt); - setField("interestRate4", txt); - setField("interestRate5", txt); -} - -void KNewLoanWizard::updateDuration() -{ - QString txt; - //FIXME: port - if (field("durationValueEdit").toInt() == 0) { - txt = QString("<") + i18n("calculate") + QString(">"); - } else { - txt = QString().sprintf("%d ", field("durationValueEdit").toInt()) - + field("durationUnitEdit").toString(); - } - setField("duration1", txt); - setField("duration2", txt); - setField("duration3", txt); - setField("duration4", txt); - setField("duration5", txt); -} - -void KNewLoanWizard::updatePayment() -{ - QString txt; - //FIXME: port - if (! field("paymentEditValid").toBool()) { - txt = QString("<") + i18n("calculate") + QString(">"); - } else { - txt = field("paymentEdit").value().formatMoney(m_account.fraction(MyMoneyFile::instance()->security(m_account.currencyId()))); - } - setField("payment1", txt); - setField("payment2", txt); - setField("payment3", txt); - setField("payment4", txt); - setField("payment5", txt); - setField("basePayment", txt); -} - -void KNewLoanWizard::updateFinalPayment() -{ - QString txt; - //FIXME: port - if (! field("finalPaymentEditValid").toBool()) { - txt = QString("<") + i18n("calculate") + QString(">"); - } else { - txt = field("finalPaymentEdit").value().formatMoney(m_account.fraction(MyMoneyFile::instance()->security(m_account.currencyId()))); - } - setField("balloon1", txt); - setField("balloon2", txt); - setField("balloon3", txt); - setField("balloon4", txt); - setField("balloon5", txt); -} - -void KNewLoanWizard::updateLoanInfo() -{ - updateLoanAmount(); - updateInterestRate(); - updateDuration(); - updatePayment(); - updateFinalPayment(); - m_additionalFeesPage->updatePeriodicPayment(m_account); - - QString txt; - - int fraction = m_account.fraction(MyMoneyFile::instance()->security(m_account.currencyId())); - setField("loanAmount6", field("loanAmountEdit").value().formatMoney(fraction)); - setField("interestRate6", QString(field("interestRateEdit").value().formatMoney("", 3) + QString("%"))); - txt = QString().sprintf("%d ", field("durationValueEdit").toInt()) - + field("durationUnitEdit").toString(); - setField("duration6", txt); - setField("payment6", field("paymentEdit").value().formatMoney(fraction)); - setField("balloon6", field("finalPaymentEdit").value().formatMoney(fraction)); -} - bool KNewLoanWizard::validateCurrentPage() { - bool dontLeavePage = false; + Q_D(KNewLoanWizard); + auto dontLeavePage = false; KLocalizedString ks = ki18n( "The loan wizard is unable to calculate two different values for your loan " "at the same time. " "Please enter a value for the %1 on this page or backup to the page where the " "current value to be calculated is defined and fill in a value."); - if (currentPage() == m_lendBorrowPage) { + if (currentPage() == d->ui->m_lendBorrowPage) { // load the appropriate categories into the list - loadAccountList(); + d->loadAccountList(); - } else if (currentPage() == m_interestTypePage) { + } else if (currentPage() == d->ui->m_interestTypePage) { if (field("fixedInterestButton").toBool()) { - m_pages.setBit(Page_PreviousPayments); + d->m_pages.setBit(Page_PreviousPayments); if (field("previousPaymentButton").toBool()) - m_pages.setBit(Page_RecordPayment); + d->m_pages.setBit(Page_RecordPayment); else - m_pages.clearBit(Page_RecordPayment); - m_pages.clearBit(Page_VariableInterestDate); + d->m_pages.clearBit(Page_RecordPayment); + d->m_pages.clearBit(Page_VariableInterestDate); } else { - m_pages.clearBit(Page_PreviousPayments); - m_pages.clearBit(Page_RecordPayment); - m_pages.setBit(Page_VariableInterestDate); + d->m_pages.clearBit(Page_PreviousPayments); + d->m_pages.clearBit(Page_RecordPayment); + d->m_pages.setBit(Page_VariableInterestDate); } - } else if (currentPage() == m_previousPaymentsPage) { + } else if (currentPage() == d->ui->m_previousPaymentsPage) { if (field("previousPaymentButton").toBool()) { - m_pages.setBit(Page_RecordPayment); + d->m_pages.setBit(Page_RecordPayment); } else if (field("noPreviousPaymentButton").toBool()) { - m_pages.clearBit(Page_RecordPayment); + d->m_pages.clearBit(Page_RecordPayment); } - } else if (currentPage() == m_loanAmountPage) { + } else if (currentPage() == d->ui->m_loanAmountPage) { if (field("thisYearPaymentButton").toBool() && !field("loanAmountEditValid").toBool()) { dontLeavePage = true; KMessageBox::error(0, i18n("You selected, that payments have already been made towards this loan. " "This requires you to enter the loan amount exactly as found on your " "last statement."), i18n("Calculation error")); } else - updateLoanAmount(); + d->updateLoanAmount(); - } else if (currentPage() == m_interestPage) { + } else if (currentPage() == d->ui->m_interestPage) { if (!field("loanAmountEditValid").toBool() && !field("interestRateEditValid").toBool()) { dontLeavePage = true; KMessageBox::error(0, ks.subs(i18n("interest rate")).toString(), i18n("Calculation error")); } else - updateInterestRate(); + d->updateInterestRate(); - } else if (currentPage() == m_durationPage) { + } else if (currentPage() == d->ui->m_durationPage) { if ((!field("loanAmountEditValid").toBool() || !field("interestRateEditValid").toBool()) && field("durationValueEdit").toInt() == 0) { dontLeavePage = true; KMessageBox::error(0, ks.subs(i18n("term")).toString(), i18n("Calculation error")); } else - updateDuration(); + d->updateDuration(); - } else if (currentPage() == m_paymentPage) { + } else if (currentPage() == d->ui->m_paymentPage) { if ((!field("loanAmountEditValid").toBool() || !field("interestRateEditValid").toBool() || field("durationValueEdit").toInt() == 0) && !field("paymentEditValid").toBool()) { dontLeavePage = true; KMessageBox::error(0, ks.subs(i18n("principal and interest")).toString(), i18n("Calculation error")); } else - updatePayment(); + d->updatePayment(); - } else if (currentPage() == m_finalPaymentPage) { + } else if (currentPage() == d->ui->m_finalPaymentPage) { if ((!field("loanAmountEditValid").toBool() || !field("interestRateEditValid").toBool() || field("durationValueEdit").toInt() == 0 @@ -316,297 +162,28 @@ // we assume the final payment to be 0 instead of presenting a dialog setField("finalPaymentEdit", QVariant::fromValue((MyMoneyMoney()))); } - updateFinalPayment(); - if (!calculateLoan()) { + d->updateFinalPayment(); + if (!d->calculateLoan()) { dontLeavePage = true; } else - updateLoanInfo(); - } else if (currentPage() == m_schedulePage) { + d->updateLoanInfo(); + } else if (currentPage() == d->ui->m_schedulePage) { if (field("allPaymentsButton").toBool() || field("noPreviousPaymentButton").toBool()) { - if (m_assetAccountPage) - m_pages.setBit(Page_AssetAccount); + if (d->ui->m_assetAccountPage) + d->m_pages.setBit(Page_AssetAccount); } else { - if (m_assetAccountPage) - m_pages.clearBit(Page_AssetAccount); - m_assetAccountPage->m_assetAccountEdit->slotDeselectAllAccounts(); + if (d->ui->m_assetAccountPage) + d->m_pages.clearBit(Page_AssetAccount); + d->ui->m_assetAccountPage->m_assetAccountEdit->slotDeselectAllAccounts(); } } if (!dontLeavePage) - return KNewLoanWizardDecl::validateCurrentPage(); + return true; else return false; } -int KNewLoanWizard::calculateLoan() -{ - MyMoneyFinancialCalculator calc; - double val; - int PF; - QString result; - - // FIXME: for now, we only support interest calculation at the end of the period - calc.setBep(); - // FIXME: for now, we only support periodic compounding - calc.setDisc(); - - PF = MyMoneySchedule::eventsPerYear(eMyMoney::Schedule::Occurrence(field("paymentFrequencyUnitEdit").toInt())); - if (PF == 0) - return 0; - calc.setPF(PF); - - // FIXME: for now we only support compounding frequency == payment frequency - calc.setCF(PF); - - if (field("loanAmountEditValid").toBool()) { - val = field("loanAmountEdit").value().abs().toDouble(); - if (field("borrowButton").toBool()) - val = -val; - calc.setPv(val); - } - - if (field("interestRateEditValid").toBool()) { - val = field("interestRateEdit").value().abs().toDouble(); - calc.setIr(val); - } - - if (field("paymentEditValid").toBool()) { - val = field("paymentEdit").value().abs().toDouble(); - if (field("lendButton").toBool()) - val = -val; - calc.setPmt(val); - } - - if (field("finalPaymentEditValid").toBool()) { - val = field("finalPaymentEditValid").value().abs().toDouble(); - if (field("lendButton").toBool()) - val = -val; - calc.setFv(val); - } - - if (field("durationValueEdit").toInt() != 0) { - calc.setNpp(m_durationPage->term()); - } - - int fraction = m_account.fraction(MyMoneyFile::instance()->security(m_account.currencyId())); - // setup of parameters is done, now do the calculation - try { - //FIXME: port - if (!field("loanAmountEditValid").toBool()) { - // calculate the amount of the loan out of the other information - val = calc.presentValue(); - m_loanAmountPage->m_loanAmountEdit->loadText(MyMoneyMoney(static_cast(val)).abs().formatMoney(fraction)); - result = i18n("KMyMoney has calculated the amount of the loan as %1.", m_loanAmountPage->m_loanAmountEdit->lineedit()->text()); - - } else if (!field("interestRateEditValid").toBool()) { - // calculate the interest rate out of the other information - val = calc.interestRate(); - - m_interestPage->m_interestRateEdit->loadText(MyMoneyMoney(static_cast(val)).abs().formatMoney("", 3)); - result = i18n("KMyMoney has calculated the interest rate to %1%.", m_interestPage->m_interestRateEdit->lineedit()->text()); - - } else if (!field("paymentEditValid").toBool()) { - // calculate the periodical amount of the payment out of the other information - val = calc.payment(); - setField("paymentEdit", QVariant::fromValue(MyMoneyMoney(val).abs())); - // reset payment as it might have changed due to rounding - val = field("paymentEdit").value().abs().toDouble(); - if (field("lendButton").toBool()) - val = -val; - calc.setPmt(val); - - result = i18n("KMyMoney has calculated a periodic payment of %1 to cover principal and interest.", m_paymentPage->m_paymentEdit->lineedit()->text()); - - val = calc.futureValue(); - if ((field("borrowButton").toBool() && val < 0 && qAbs(val) >= qAbs(calc.payment())) - || (field("lendButton").toBool() && val > 0 && qAbs(val) >= qAbs(calc.payment()))) { - calc.setNpp(calc.npp() - 1); - m_durationPage->updateTermWidgets(calc.npp()); - val = calc.futureValue(); - MyMoneyMoney refVal(static_cast(val)); - m_finalPaymentPage->m_finalPaymentEdit->loadText(refVal.abs().formatMoney(fraction)); - result += QString(" "); - result += i18n("The number of payments has been decremented and the final payment has been modified to %1.", m_finalPaymentPage->m_finalPaymentEdit->lineedit()->text()); - } else if ((field("borrowButton").toBool() && val < 0 && qAbs(val) < qAbs(calc.payment())) - || (field("lendButton").toBool() && val > 0 && qAbs(val) < qAbs(calc.payment()))) { - m_finalPaymentPage->m_finalPaymentEdit->loadText(MyMoneyMoney().formatMoney(fraction)); - } else { - MyMoneyMoney refVal(static_cast(val)); - m_finalPaymentPage->m_finalPaymentEdit->loadText(refVal.abs().formatMoney(fraction)); - result += i18n("The final payment has been modified to %1.", m_finalPaymentPage->m_finalPaymentEdit->lineedit()->text()); - } - - } else if (field("durationValueEdit").toInt() == 0) { - // calculate the number of payments out of the other information - val = calc.numPayments(); - if (val == 0) - throw MYMONEYEXCEPTION("incorrect fincancial calculation"); - - // if the number of payments has a fractional part, then we - // round it to the smallest integer and calculate the balloon payment - result = i18n("KMyMoney has calculated the term of your loan as %1. ", m_durationPage->updateTermWidgets(qFloor(val))); - - if (val != qFloor(val)) { - calc.setNpp(qFloor(val)); - val = calc.futureValue(); - MyMoneyMoney refVal(static_cast(val)); - m_finalPaymentPage->m_finalPaymentEdit->loadText(refVal.abs().formatMoney(fraction)); - result += i18n("The final payment has been modified to %1.", m_finalPaymentPage->m_finalPaymentEdit->lineedit()->text()); - } - - } else { - // calculate the future value of the loan out of the other information - val = calc.futureValue(); - - // we differentiate between the following cases: - // a) the future value is greater than a payment - // b) the future value is less than a payment or the loan is overpaid - // c) all other cases - // - // a) means, we have paid more than we owed. This can't be - // b) means, we paid more than we owed but the last payment is - // less in value than regular payments. That means, that the - // future value is to be treated as (fully payed back) - // c) the loan is not payed back yet - - if ((field("borrowButton").toBool() && val < 0 && qAbs(val) > qAbs(calc.payment())) - || (field("lendButton").toBool() && val > 0 && qAbs(val) > qAbs(calc.payment()))) { - // case a) - qDebug("Future Value is %f", val); - throw MYMONEYEXCEPTION("incorrect fincancial calculation"); - - } else if ((field("borrowButton").toBool() && val < 0 && qAbs(val) <= qAbs(calc.payment())) - || (field("lendButton").toBool() && val > 0 && qAbs(val) <= qAbs(calc.payment()))) { - // case b) - val = 0; - } - - MyMoneyMoney refVal(static_cast(val)); - result = i18n("KMyMoney has calculated a final payment of %1 for this loan.", refVal.abs().formatMoney(fraction)); - - if (field("finalPaymentEditValid").toBool()) { - if ((field("finalPaymentEdit").value().abs() - refVal.abs()).abs().toDouble() > 1) { - throw MYMONEYEXCEPTION("incorrect fincancial calculation"); - } - result = i18n("KMyMoney has successfully verified your loan information."); - } - //FIXME: port - m_finalPaymentPage->m_finalPaymentEdit->loadText(refVal.abs().formatMoney(fraction)); - } - - } catch (const MyMoneyException &) { - KMessageBox::error(0, - i18n("You have entered mis-matching information. Please backup to the " - "appropriate page and update your figures or leave one value empty " - "to let KMyMoney calculate it for you"), - i18n("Calculation error")); - return 0; - } - - result += i18n("\n\nAccept this or modify the loan information and recalculate."); - - KMessageBox::information(0, result, i18n("Calculation successful")); - return 1; -} - -void KNewLoanWizard::loadAccountList() -{ - AccountSet interestSet, assetSet; - - if (field("borrowButton").toBool()) { - interestSet.addAccountType(eMyMoney::Account::Expense); - } else { - interestSet.addAccountType(eMyMoney::Account::Income); - } - if (m_interestCategoryPage) - interestSet.load(m_interestCategoryPage->m_interestAccountEdit); - - assetSet.addAccountType(eMyMoney::Account::Checkings); - assetSet.addAccountType(eMyMoney::Account::Savings); - assetSet.addAccountType(eMyMoney::Account::Cash); - assetSet.addAccountType(eMyMoney::Account::Asset); - assetSet.addAccountType(eMyMoney::Account::Currency); - if (m_assetAccountPage) - assetSet.load(m_assetAccountPage->m_assetAccountEdit); - - assetSet.addAccountType(eMyMoney::Account::CreditCard); - assetSet.addAccountType(eMyMoney::Account::Liability); - if (m_schedulePage) - assetSet.load(m_schedulePage->m_paymentAccountEdit); -} - -MyMoneyTransaction KNewLoanWizard::transaction() const -{ - MyMoneyTransaction t; - bool hasInterest = !field("interestRateEdit").value().isZero(); - - MyMoneySplit sPayment, sInterest, sAmortization; - // setup accounts. at this point, we cannot fill in the id of the - // account that the amortization will be performed on, because we - // create the account. So the id is yet unknown. - sPayment.setAccountId(field("paymentAccountEdit").toStringList().first()); - - - //Only create the interest split if not zero - if (hasInterest) { - sInterest.setAccountId(field("interestAccountEdit").toStringList().first()); - sInterest.setValue(MyMoneyMoney::autoCalc); - sInterest.setShares(sInterest.value()); - sInterest.setAction(MyMoneySplit::ActionInterest); - } - - // values - if (field("borrowButton").toBool()) { - sPayment.setValue(-field("paymentEdit").value()); - } else { - sPayment.setValue(field("paymentEdit").value()); - } - - sAmortization.setValue(MyMoneyMoney::autoCalc); - // don't forget the shares - sPayment.setShares(sPayment.value()); - - sAmortization.setShares(sAmortization.value()); - - // setup the commodity - MyMoneyAccount acc = MyMoneyFile::instance()->account(sPayment.accountId()); - t.setCommodity(acc.currencyId()); - - // actions - sPayment.setAction(MyMoneySplit::ActionAmortization); - sAmortization.setAction(MyMoneySplit::ActionAmortization); - - // payee - QString payeeId = field("payeeEdit").toString(); - sPayment.setPayeeId(payeeId); - sAmortization.setPayeeId(payeeId); - - MyMoneyAccount account("Phony-ID", MyMoneyAccount()); - sAmortization.setAccountId(account.id()); - - // IMPORTANT: Payment split must be the first one, because - // the schedule view expects it this way during display - t.addSplit(sPayment); - t.addSplit(sAmortization); - - if (hasInterest) { - t.addSplit(sInterest); - } - - // copy the splits from the other costs and update the payment split - foreach (const MyMoneySplit& it, m_transaction.splits()) { - if (it.accountId() != account.id()) { - MyMoneySplit sp = it; - sp.clearId(); - t.addSplit(sp); - sPayment.setValue(sPayment.value() - sp.value()); - sPayment.setShares(sPayment.value()); - t.modifySplit(sPayment); - } - } - return t; -} - MyMoneySchedule KNewLoanWizard::schedule() const { MyMoneySchedule sched(field("nameEdit").toString(), @@ -618,23 +195,25 @@ false, false); - MyMoneyTransaction t = transaction(); + Q_D(const KNewLoanWizard); + MyMoneyTransaction t = d->transaction(); t.setPostDate(field("nextDueDateEdit").toDate()); sched.setTransaction(t); return sched; } void KNewLoanWizard::slotReloadEditWidgets() { + Q_D(KNewLoanWizard); // load the various account widgets - loadAccountList(); + d->loadAccountList(); // reload payee widget - QString payeeId = field("payeeEdit").toString(); + auto payeeId = field("payeeEdit").toString(); //FIXME: port - m_namePage->m_payeeEdit->loadPayees(MyMoneyFile::instance()->payeeList()); + d->ui->m_namePage->m_payeeEdit->loadPayees(MyMoneyFile::instance()->payeeList()); if (!payeeId.isEmpty()) { setField("payeeEdit", payeeId); diff --git a/kmymoney/wizards/newloanwizard/knewloanwizarddecl.ui b/kmymoney/wizards/newloanwizard/knewloanwizard.ui rename from kmymoney/wizards/newloanwizard/knewloanwizarddecl.ui rename to kmymoney/wizards/newloanwizard/knewloanwizard.ui --- a/kmymoney/wizards/newloanwizard/knewloanwizarddecl.ui +++ b/kmymoney/wizards/newloanwizard/knewloanwizard.ui @@ -3,8 +3,8 @@ - KNewLoanWizardDecl - + KNewLoanWizard + 0 diff --git a/kmymoney/wizards/newloanwizard/knewloanwizard_p.h b/kmymoney/wizards/newloanwizard/knewloanwizard_p.h new file mode 100644 --- /dev/null +++ b/kmymoney/wizards/newloanwizard/knewloanwizard_p.h @@ -0,0 +1,529 @@ +/*************************************************************************** + knewloanwizard_p.cpp - description + ------------------- + copyright : (C) 2017 by Łukasz Wojniłowicz + + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef KNEWLOANWIZARD_P_H +#define KNEWLOANWIZARD_P_H + +#include "knewloanwizard.h" + +// ---------------------------------------------------------------------------- +// QT Includes + +#include +#include + +// ---------------------------------------------------------------------------- +// KDE Includes + +#include +#include + +// ---------------------------------------------------------------------------- +// Project Includes + +#include "ui_knewloanwizard.h" + +#include "kmymoneyutils.h" +#include "kmymoneysettings.h" + +#include "mymoneyfinancialcalculator.h" +#include "mymoneyfile.h" +#include "mymoneyaccountloan.h" +#include "mymoneyschedule.h" +#include "mymoneysplit.h" +#include "mymoneytransaction.h" + +namespace Ui { class KNewLoanWizard; } + +class KNewLoanWizard; +class KNewLoanWizardPrivate +{ + Q_DISABLE_COPY(KNewLoanWizardPrivate) + Q_DECLARE_PUBLIC(KNewLoanWizard) + +public: + KNewLoanWizardPrivate(KNewLoanWizard *qq) : + q_ptr(qq), + ui(new Ui::KNewLoanWizard) + { + } + + ~KNewLoanWizardPrivate() + { + delete ui; + } + + void init() + { + Q_Q(KNewLoanWizard); + ui->setupUi(q); + m_pages = QBitArray(KNewLoanWizard::Page_Summary + 1, true); + q->setModal(true); + + KMyMoneyMVCCombo::setSubstringSearchForChildren(ui->m_namePage, !KMyMoneySettings::stringMatchFromStart()); + + // make sure, the back button does not clear fields + q->setOption(QWizard::IndependentPages, true); + + // connect(m_payeeEdit, SIGNAL(newPayee(QString)), this, SLOT(slotNewPayee(QString))); + q->connect(ui->m_namePage->m_payeeEdit, &KMyMoneyMVCCombo::createItem, q, &KNewLoanWizard::createPayee); + + q->connect(ui->m_additionalFeesPage, &AdditionalFeesWizardPage::newCategory, q, &KNewLoanWizard::newCategory); + + q->connect(MyMoneyFile::instance(), &MyMoneyFile::dataChanged, q, &KNewLoanWizard::slotReloadEditWidgets); + + resetCalculator(); + + q->slotReloadEditWidgets(); + + // As default we assume a liability loan, with fixed interest rate, + // with a first payment due on the 30th of this month. All payments + // should be recorded and none have been made so far. + + //FIXME: port + ui->m_firstPaymentPage->m_firstDueDateEdit->loadDate(QDate(QDate::currentDate().year(), QDate::currentDate().month(), 30)); + + // FIXME: we currently only support interest calculation on reception + m_pages.clearBit(KNewLoanWizard::Page_InterestCalculation); + + // turn off all pages that are contained here for derived classes + m_pages.clearBit(KNewLoanWizard::Page_EditIntro); + m_pages.clearBit(KNewLoanWizard::Page_EditSelection); + m_pages.clearBit(KNewLoanWizard::Page_EffectiveDate); + m_pages.clearBit(KNewLoanWizard::Page_PaymentEdit); + m_pages.clearBit(KNewLoanWizard::Page_InterestEdit); + m_pages.clearBit(KNewLoanWizard::Page_SummaryEdit); + + // for now, we don't have online help :-( + q->setOption(QWizard::HaveHelpButton, false); + + // setup a phony transaction for additional fee processing + m_account = MyMoneyAccount("Phony-ID", MyMoneyAccount()); + m_split.setAccountId(m_account.id()); + m_split.setValue(MyMoneyMoney()); + m_transaction.addSplit(m_split); + + KMyMoneyUtils::updateWizardButtons(q); + } + + void resetCalculator() + { + Q_Q(KNewLoanWizard); + ui->m_loanAmountPage->resetCalculator(); + ui->m_interestPage->resetCalculator(); + ui->m_durationPage->resetCalculator(); + ui->m_paymentPage->resetCalculator(); + ui->m_finalPaymentPage->resetCalculator(); + + q->setField("additionalCost", MyMoneyMoney().formatMoney(m_account.fraction(MyMoneyFile::instance()->security(m_account.currencyId())))); + } + + void updateLoanAmount() + { + Q_Q(KNewLoanWizard); + QString txt; + //FIXME: port + if (! q->field("loanAmountEditValid").toBool()) { + txt = QString("<") + i18n("calculate") + QString(">"); + } else { + txt = q->field("loanAmountEdit").value().formatMoney(m_account.fraction(MyMoneyFile::instance()->security(m_account.currencyId()))); + } + q->setField("loanAmount1", txt); + q->setField("loanAmount2", txt); + q->setField("loanAmount3", txt); + q->setField("loanAmount4", txt); + q->setField("loanAmount5", txt); + } + + void updateInterestRate() + { + Q_Q(KNewLoanWizard); + QString txt; + //FIXME: port + if (! q->field("interestRateEditValid").toBool()) { + txt = QString("<") + i18n("calculate") + QString(">"); + } else { + txt = q->field("interestRateEdit").value().formatMoney(QString(), 3) + QString("%"); + } + q->setField("interestRate1", txt); + q->setField("interestRate2", txt); + q->setField("interestRate3", txt); + q->setField("interestRate4", txt); + q->setField("interestRate5", txt); + } + + void updateDuration() + { + Q_Q(KNewLoanWizard); + QString txt; + //FIXME: port + if (q->field("durationValueEdit").toInt() == 0) { + txt = QString("<") + i18n("calculate") + QString(">"); + } else { + txt = QString().sprintf("%d ", q->field("durationValueEdit").toInt()) + + q->field("durationUnitEdit").toString(); + } + q->setField("duration1", txt); + q->setField("duration2", txt); + q->setField("duration3", txt); + q->setField("duration4", txt); + q->setField("duration5", txt); + } + + void updatePayment() + { + Q_Q(KNewLoanWizard); + QString txt; + //FIXME: port + if (! q->field("paymentEditValid").toBool()) { + txt = QString("<") + i18n("calculate") + QString(">"); + } else { + txt = q->field("paymentEdit").value().formatMoney(m_account.fraction(MyMoneyFile::instance()->security(m_account.currencyId()))); + } + q->setField("payment1", txt); + q->setField("payment2", txt); + q->setField("payment3", txt); + q->setField("payment4", txt); + q->setField("payment5", txt); + q->setField("basePayment", txt); + } + + void updateFinalPayment() + { + Q_Q(KNewLoanWizard); + QString txt; + //FIXME: port + if (! q->field("finalPaymentEditValid").toBool()) { + txt = QString("<") + i18n("calculate") + QString(">"); + } else { + txt = q->field("finalPaymentEdit").value().formatMoney(m_account.fraction(MyMoneyFile::instance()->security(m_account.currencyId()))); + } + q->setField("balloon1", txt); + q->setField("balloon2", txt); + q->setField("balloon3", txt); + q->setField("balloon4", txt); + q->setField("balloon5", txt); + } + + void updateLoanInfo() + { + Q_Q(KNewLoanWizard); + updateLoanAmount(); + updateInterestRate(); + updateDuration(); + updatePayment(); + updateFinalPayment(); + ui->m_additionalFeesPage->updatePeriodicPayment(m_account); + + QString txt; + + int fraction = m_account.fraction(MyMoneyFile::instance()->security(m_account.currencyId())); + q->setField("loanAmount6", q->field("loanAmountEdit").value().formatMoney(fraction)); + q->setField("interestRate6", QString(q->field("interestRateEdit").value().formatMoney("", 3) + QString("%"))); + txt = QString().sprintf("%d ", q->field("durationValueEdit").toInt()) + + q->field("durationUnitEdit").toString(); + q->setField("duration6", txt); + q->setField("payment6", q->field("paymentEdit").value().formatMoney(fraction)); + q->setField("balloon6", q->field("finalPaymentEdit").value().formatMoney(fraction)); + } + + int calculateLoan() + { + Q_Q(KNewLoanWizard); + MyMoneyFinancialCalculator calc; + double val; + int PF; + QString result; + + // FIXME: for now, we only support interest calculation at the end of the period + calc.setBep(); + // FIXME: for now, we only support periodic compounding + calc.setDisc(); + + PF = MyMoneySchedule::eventsPerYear(eMyMoney::Schedule::Occurrence(q->field("paymentFrequencyUnitEdit").toInt())); + if (PF == 0) + return 0; + calc.setPF(PF); + + // FIXME: for now we only support compounding frequency == payment frequency + calc.setCF(PF); + + if (q->field("loanAmountEditValid").toBool()) { + val = q->field("loanAmountEdit").value().abs().toDouble(); + if (q->field("borrowButton").toBool()) + val = -val; + calc.setPv(val); + } + + if (q->field("interestRateEditValid").toBool()) { + val = q->field("interestRateEdit").value().abs().toDouble(); + calc.setIr(val); + } + + if (q->field("paymentEditValid").toBool()) { + val = q->field("paymentEdit").value().abs().toDouble(); + if (q->field("lendButton").toBool()) + val = -val; + calc.setPmt(val); + } + + if (q->field("finalPaymentEditValid").toBool()) { + val = q->field("finalPaymentEditValid").value().abs().toDouble(); + if (q->field("lendButton").toBool()) + val = -val; + calc.setFv(val); + } + + if (q->field("durationValueEdit").toInt() != 0) { + calc.setNpp(ui->m_durationPage->term()); + } + + int fraction = m_account.fraction(MyMoneyFile::instance()->security(m_account.currencyId())); + // setup of parameters is done, now do the calculation + try { + //FIXME: port + if (!q->field("loanAmountEditValid").toBool()) { + // calculate the amount of the loan out of the other information + val = calc.presentValue(); + ui->m_loanAmountPage->m_loanAmountEdit->loadText(MyMoneyMoney(static_cast(val)).abs().formatMoney(fraction)); + result = i18n("KMyMoney has calculated the amount of the loan as %1.", ui->m_loanAmountPage->m_loanAmountEdit->lineedit()->text()); + + } else if (!q->field("interestRateEditValid").toBool()) { + // calculate the interest rate out of the other information + val = calc.interestRate(); + + ui->m_interestPage->m_interestRateEdit->loadText(MyMoneyMoney(static_cast(val)).abs().formatMoney("", 3)); + result = i18n("KMyMoney has calculated the interest rate to %1%.", ui->m_interestPage->m_interestRateEdit->lineedit()->text()); + + } else if (!q->field("paymentEditValid").toBool()) { + // calculate the periodical amount of the payment out of the other information + val = calc.payment(); + q->setField("paymentEdit", QVariant::fromValue(MyMoneyMoney(val).abs())); + // reset payment as it might have changed due to rounding + val = q->field("paymentEdit").value().abs().toDouble(); + if (q->field("lendButton").toBool()) + val = -val; + calc.setPmt(val); + + result = i18n("KMyMoney has calculated a periodic payment of %1 to cover principal and interest.", ui->m_paymentPage->m_paymentEdit->lineedit()->text()); + + val = calc.futureValue(); + if ((q->field("borrowButton").toBool() && val < 0 && qAbs(val) >= qAbs(calc.payment())) + || (q->field("lendButton").toBool() && val > 0 && qAbs(val) >= qAbs(calc.payment()))) { + calc.setNpp(calc.npp() - 1); + ui->m_durationPage->updateTermWidgets(calc.npp()); + val = calc.futureValue(); + MyMoneyMoney refVal(static_cast(val)); + ui->m_finalPaymentPage->m_finalPaymentEdit->loadText(refVal.abs().formatMoney(fraction)); + result += QString(" "); + result += i18n("The number of payments has been decremented and the final payment has been modified to %1.", ui->m_finalPaymentPage->m_finalPaymentEdit->lineedit()->text()); + } else if ((q->field("borrowButton").toBool() && val < 0 && qAbs(val) < qAbs(calc.payment())) + || (q->field("lendButton").toBool() && val > 0 && qAbs(val) < qAbs(calc.payment()))) { + ui->m_finalPaymentPage->m_finalPaymentEdit->loadText(MyMoneyMoney().formatMoney(fraction)); + } else { + MyMoneyMoney refVal(static_cast(val)); + ui->m_finalPaymentPage->m_finalPaymentEdit->loadText(refVal.abs().formatMoney(fraction)); + result += i18n("The final payment has been modified to %1.", ui->m_finalPaymentPage->m_finalPaymentEdit->lineedit()->text()); + } + + } else if (q->field("durationValueEdit").toInt() == 0) { + // calculate the number of payments out of the other information + val = calc.numPayments(); + if (val == 0) + throw MYMONEYEXCEPTION("incorrect fincancial calculation"); + + // if the number of payments has a fractional part, then we + // round it to the smallest integer and calculate the balloon payment + result = i18n("KMyMoney has calculated the term of your loan as %1. ", ui->m_durationPage->updateTermWidgets(qFloor(val))); + + if (val != qFloor(val)) { + calc.setNpp(qFloor(val)); + val = calc.futureValue(); + MyMoneyMoney refVal(static_cast(val)); + ui->m_finalPaymentPage->m_finalPaymentEdit->loadText(refVal.abs().formatMoney(fraction)); + result += i18n("The final payment has been modified to %1.", ui->m_finalPaymentPage->m_finalPaymentEdit->lineedit()->text()); + } + + } else { + // calculate the future value of the loan out of the other information + val = calc.futureValue(); + + // we differentiate between the following cases: + // a) the future value is greater than a payment + // b) the future value is less than a payment or the loan is overpaid + // c) all other cases + // + // a) means, we have paid more than we owed. This can't be + // b) means, we paid more than we owed but the last payment is + // less in value than regular payments. That means, that the + // future value is to be treated as (fully payed back) + // c) the loan is not payed back yet + + if ((q->field("borrowButton").toBool() && val < 0 && qAbs(val) > qAbs(calc.payment())) + || (q->field("lendButton").toBool() && val > 0 && qAbs(val) > qAbs(calc.payment()))) { + // case a) + qDebug("Future Value is %f", val); + throw MYMONEYEXCEPTION("incorrect fincancial calculation"); + + } else if ((q->field("borrowButton").toBool() && val < 0 && qAbs(val) <= qAbs(calc.payment())) + || (q->field("lendButton").toBool() && val > 0 && qAbs(val) <= qAbs(calc.payment()))) { + // case b) + val = 0; + } + + MyMoneyMoney refVal(static_cast(val)); + result = i18n("KMyMoney has calculated a final payment of %1 for this loan.", refVal.abs().formatMoney(fraction)); + + if (q->field("finalPaymentEditValid").toBool()) { + if ((q->field("finalPaymentEdit").value().abs() - refVal.abs()).abs().toDouble() > 1) { + throw MYMONEYEXCEPTION("incorrect fincancial calculation"); + } + result = i18n("KMyMoney has successfully verified your loan information."); + } + //FIXME: port + ui->m_finalPaymentPage->m_finalPaymentEdit->loadText(refVal.abs().formatMoney(fraction)); + } + + } catch (const MyMoneyException &) { + KMessageBox::error(0, + i18n("You have entered mis-matching information. Please backup to the " + "appropriate page and update your figures or leave one value empty " + "to let KMyMoney calculate it for you"), + i18n("Calculation error")); + return 0; + } + + result += i18n("\n\nAccept this or modify the loan information and recalculate."); + + KMessageBox::information(0, result, i18n("Calculation successful")); + return 1; + } + + /** + * This method returns the transaction that is stored within + * the schedule. See schedule(). + * + * @return MyMoneyTransaction object to be used within the schedule + */ + MyMoneyTransaction transaction() const + { + Q_Q(const KNewLoanWizard); + MyMoneyTransaction t; + bool hasInterest = !q->field("interestRateEdit").value().isZero(); + + MyMoneySplit sPayment, sInterest, sAmortization; + // setup accounts. at this point, we cannot fill in the id of the + // account that the amortization will be performed on, because we + // create the account. So the id is yet unknown. + sPayment.setAccountId(q->field("paymentAccountEdit").toStringList().first()); + + + //Only create the interest split if not zero + if (hasInterest) { + sInterest.setAccountId(q->field("interestAccountEdit").toStringList().first()); + sInterest.setValue(MyMoneyMoney::autoCalc); + sInterest.setShares(sInterest.value()); + sInterest.setAction(MyMoneySplit::ActionInterest); + } + + // values + if (q->field("borrowButton").toBool()) { + sPayment.setValue(-q->field("paymentEdit").value()); + } else { + sPayment.setValue(q->field("paymentEdit").value()); + } + + sAmortization.setValue(MyMoneyMoney::autoCalc); + // don't forget the shares + sPayment.setShares(sPayment.value()); + + sAmortization.setShares(sAmortization.value()); + + // setup the commodity + MyMoneyAccount acc = MyMoneyFile::instance()->account(sPayment.accountId()); + t.setCommodity(acc.currencyId()); + + // actions + sPayment.setAction(MyMoneySplit::ActionAmortization); + sAmortization.setAction(MyMoneySplit::ActionAmortization); + + // payee + QString payeeId = q->field("payeeEdit").toString(); + sPayment.setPayeeId(payeeId); + sAmortization.setPayeeId(payeeId); + + MyMoneyAccount account("Phony-ID", MyMoneyAccount()); + sAmortization.setAccountId(account.id()); + + // IMPORTANT: Payment split must be the first one, because + // the schedule view expects it this way during display + t.addSplit(sPayment); + t.addSplit(sAmortization); + + if (hasInterest) { + t.addSplit(sInterest); + } + + // copy the splits from the other costs and update the payment split + foreach (const MyMoneySplit& it, m_transaction.splits()) { + if (it.accountId() != account.id()) { + MyMoneySplit sp = it; + sp.clearId(); + t.addSplit(sp); + sPayment.setValue(sPayment.value() - sp.value()); + sPayment.setShares(sPayment.value()); + t.modifySplit(sPayment); + } + } + return t; + } + + void loadAccountList() + { + Q_Q(KNewLoanWizard); + AccountSet interestSet, assetSet; + + if (q->field("borrowButton").toBool()) { + interestSet.addAccountType(eMyMoney::Account::Expense); + } else { + interestSet.addAccountType(eMyMoney::Account::Income); + } + if (ui->m_interestCategoryPage) + interestSet.load(ui->m_interestCategoryPage->m_interestAccountEdit); + + assetSet.addAccountType(eMyMoney::Account::Checkings); + assetSet.addAccountType(eMyMoney::Account::Savings); + assetSet.addAccountType(eMyMoney::Account::Cash); + assetSet.addAccountType(eMyMoney::Account::Asset); + assetSet.addAccountType(eMyMoney::Account::Currency); + if (ui->m_assetAccountPage) + assetSet.load(ui->m_assetAccountPage->m_assetAccountEdit); + + assetSet.addAccountType(eMyMoney::Account::CreditCard); + assetSet.addAccountType(eMyMoney::Account::Liability); + if (ui->m_schedulePage) + assetSet.load(ui->m_schedulePage->m_paymentAccountEdit); + } + + KNewLoanWizard *q_ptr; + Ui::KNewLoanWizard *ui; + MyMoneyAccountLoan m_account; + MyMoneyTransaction m_transaction; + MyMoneySplit m_split; + QBitArray m_pages; +}; + +#endif