Changeset View
Changeset View
Standalone View
Standalone View
kmymoney/wizards/newaccountwizard/knewaccountwizard.cpp
Context not available. | |||||
4 | begin : Tue Sep 25 2006 | 4 | begin : Tue Sep 25 2006 | ||
---|---|---|---|---|---|
5 | copyright : (C) 2007 Thomas Baumgart | 5 | copyright : (C) 2007 Thomas Baumgart | ||
6 | email : Thomas Baumgart <ipwizard@users.sourceforge.net> | 6 | email : Thomas Baumgart <ipwizard@users.sourceforge.net> | ||
7 | (C) 2017 by Łukasz Wojniłowicz <lukasz.wojnilowicz@gmail.com> | ||||
7 | ***************************************************************************/ | 8 | ***************************************************************************/ | ||
8 | 9 | | |||
9 | /*************************************************************************** | 10 | /*************************************************************************** | ||
Context not available. | |||||
22 | // QT Includes | 23 | // QT Includes | ||
23 | 24 | | |||
24 | #include <QCheckBox> | 25 | #include <QCheckBox> | ||
25 | #include <QLabel> | | |||
26 | #include <QList> | 26 | #include <QList> | ||
27 | #include <qmath.h> | | |||
28 | #include <QIcon> | | |||
29 | #include <QTimer> | | |||
30 | 27 | | |||
31 | // ---------------------------------------------------------------------------- | 28 | // ---------------------------------------------------------------------------- | ||
32 | // KDE Includes | 29 | // KDE Includes | ||
33 | 30 | | |||
34 | #include <KLocalizedString> | 31 | #include <KLocalizedString> | ||
35 | #include <KLineEdit> | 32 | #include <KLineEdit> | ||
36 | #include <KMessageBox> | | |||
37 | 33 | | |||
38 | // ---------------------------------------------------------------------------- | 34 | // ---------------------------------------------------------------------------- | ||
39 | // Project Includes | 35 | // Project Includes | ||
40 | 36 | | |||
37 | #include "kaccountsummarypage.h" | ||||
38 | #include "kaccounttypepage.h" | ||||
39 | #include "kbrokeragepage.h" | ||||
40 | #include "kcreditcardschedulepage.h" | ||||
41 | #include "kgeneralloaninfopage.h" | ||||
42 | #include "khierarchypage.h" | ||||
43 | #include "kinstitutionpage.h" | ||||
44 | #include "kloandetailspage.h" | ||||
45 | #include "kloanpaymentpage.h" | ||||
46 | #include "kloanpayoutpage.h" | ||||
47 | #include "kloanschedulepage.h" | ||||
48 | | ||||
49 | #include "kaccounttypepage_p.h" | ||||
50 | #include "kbrokeragepage_p.h" | ||||
51 | #include "kcreditcardschedulepage_p.h" | ||||
52 | #include "kgeneralloaninfopage_p.h" | ||||
53 | #include "kinstitutionpage_p.h" | ||||
54 | #include "kloandetailspage_p.h" | ||||
55 | #include "kloanpayoutpage_p.h" | ||||
56 | #include "kloanschedulepage_p.h" | ||||
57 | | ||||
41 | #include "kmymoneycurrencyselector.h" | 58 | #include "kmymoneycurrencyselector.h" | ||
42 | #include "kmymoneyaccountselector.h" | | |||
43 | #include "mymoneyfinancialcalculator.h" | | |||
44 | #include "kcurrencycalculator.h" | 59 | #include "kcurrencycalculator.h" | ||
45 | #include "kmymoneyglobalsettings.h" | 60 | #include "kmymoneyglobalsettings.h" | ||
46 | #include <kguiutils.h> | | |||
47 | 61 | | |||
48 | #include "mymoneyutils.h" | | |||
49 | #include "ksplittransactiondlg.h" | | |||
50 | #include "kequitypriceupdatedlg.h" | | |||
51 | #include "accountsmodel.h" | | |||
52 | #include "accountsproxymodel.h" | | |||
53 | #include "models.h" | | |||
54 | #include "modelenums.h" | | |||
55 | #include "icons.h" | | |||
56 | #include "mymoneyfile.h" | 62 | #include "mymoneyfile.h" | ||
57 | #include "mymoneyinstitution.h" | 63 | #include "mymoneyinstitution.h" | ||
58 | #include "mymoneyaccountloan.h" | 64 | #include "mymoneyaccountloan.h" | ||
59 | #include "mymoneypayee.h" | | |||
60 | #include "mymoneyprice.h" | 65 | #include "mymoneyprice.h" | ||
61 | #include "mymoneysplit.h" | 66 | #include "mymoneysplit.h" | ||
62 | #include "mymoneytransaction.h" | 67 | #include "mymoneytransaction.h" | ||
Context not available. | |||||
67 | 72 | | |||
68 | namespace NewAccountWizard | 73 | namespace NewAccountWizard | ||
69 | { | 74 | { | ||
70 | enum steps { | 75 | Wizard::Wizard(QWidget *parent, bool modal, Qt::WindowFlags flags) | ||
71 | StepInstitution = 1, | 76 | : KMyMoneyWizard(*new WizardPrivate(this), parent, modal, flags) | ||
72 | StepAccount, | 77 | { | ||
73 | StepBroker, | 78 | Q_D(Wizard); | ||
74 | StepDetails, | 79 | setTitle(i18n("KMyMoney New Account Setup")); | ||
75 | StepPayments, | 80 | addStep(i18n("Institution")); | ||
76 | StepFees, | 81 | addStep(i18n("Account")); | ||
77 | StepSchedule, | 82 | addStep(i18n("Broker")); | ||
78 | StepPayout, | 83 | addStep(i18n("Details")); | ||
79 | StepParentAccount, | 84 | addStep(i18n("Payments")); | ||
80 | StepFinish | 85 | addStep(i18n("Fees")); | ||
81 | }; | 86 | addStep(i18n("Schedule")); | ||
82 | 87 | addStep(i18n("Payout")); | |||
83 | Wizard::Wizard(QWidget *parent, bool modal, Qt::WindowFlags flags) | 88 | addStep(i18n("Parent Account")); | ||
84 | : KMyMoneyWizard(parent, modal, flags) | 89 | addStep(i18nc("Finish the wizard", "Finish")); | ||
85 | { | 90 | d->setStepHidden(StepBroker); | ||
86 | setTitle(i18n("KMyMoney New Account Setup")); | 91 | d->setStepHidden(StepSchedule); | ||
87 | addStep(i18n("Institution")); | 92 | d->setStepHidden(StepPayout); | ||
88 | addStep(i18n("Account")); | 93 | d->setStepHidden(StepDetails); | ||
89 | addStep(i18n("Broker")); | 94 | d->setStepHidden(StepPayments); | ||
90 | addStep(i18n("Details")); | 95 | d->setStepHidden(StepFees); | ||
91 | addStep(i18n("Payments")); | 96 | | ||
92 | addStep(i18n("Fees")); | 97 | d->m_institutionPage = new InstitutionPage(this); | ||
93 | addStep(i18n("Schedule")); | 98 | d->m_accountTypePage = new AccountTypePage(this); | ||
94 | addStep(i18n("Payout")); | 99 | // Investment Pages | ||
95 | addStep(i18n("Parent Account")); | 100 | d->m_brokeragepage = new BrokeragePage(this); | ||
96 | addStep(i18nc("Finish the wizard", "Finish")); | 101 | // Credit Card Pages | ||
97 | setStepHidden(StepBroker); | 102 | d->m_schedulePage = new CreditCardSchedulePage(this); | ||
98 | setStepHidden(StepSchedule); | 103 | // Loan Pages | ||
99 | setStepHidden(StepPayout); | 104 | d->m_generalLoanInfoPage = new GeneralLoanInfoPage(this); | ||
100 | setStepHidden(StepDetails); | 105 | d->m_loanDetailsPage = new LoanDetailsPage(this); | ||
101 | setStepHidden(StepPayments); | 106 | d->m_loanPaymentPage = new LoanPaymentPage(this); | ||
102 | setStepHidden(StepFees); | 107 | d->m_loanSchedulePage = new LoanSchedulePage(this); | ||
103 | 108 | d->m_loanPayoutPage = new LoanPayoutPage(this); | |||
104 | m_institutionPage = new InstitutionPage(this); | 109 | // Not a loan page | ||
105 | m_accountTypePage = new AccountTypePage(this); | 110 | d->m_hierarchyPage = new HierarchyPage(this); | ||
106 | // Investment Pages | 111 | // Finish | ||
107 | m_brokeragepage = new BrokeragePage(this); | 112 | d->m_accountSummaryPage = new AccountSummaryPage(this); | ||
108 | // Credit Card Pages | 113 | | ||
109 | m_schedulePage = new CreditCardSchedulePage(this); | 114 | d->setFirstPage(d->m_institutionPage); | ||
110 | // Loan Pages | 115 | } | ||
111 | m_generalLoanInfoPage = new GeneralLoanInfoPage(this); | 116 | | ||
112 | m_loanDetailsPage = new LoanDetailsPage(this); | 117 | Wizard::~Wizard() | ||
113 | m_loanPaymentPage = new LoanPaymentPage(this); | 118 | { | ||
114 | m_loanSchedulePage = new LoanSchedulePage(this); | 119 | } | ||
115 | m_loanPayoutPage = new LoanPayoutPage(this); | 120 | | ||
116 | // Not a loan page | 121 | void Wizard::setAccount(const MyMoneyAccount& acc) | ||
117 | m_hierarchyPage = new HierarchyPage(this); | 122 | { | ||
118 | // Finish | 123 | Q_D(Wizard); | ||
119 | m_accountSummaryPage = new AccountSummaryPage(this); | 124 | d->m_account = acc; | ||
120 | 125 | d->m_accountTypePage->setAccount(d->m_account); | |||
121 | setFirstPage(m_institutionPage); | 126 | | ||
122 | } | 127 | if (!acc.institutionId().isEmpty()) { | ||
123 | 128 | d->m_institutionPage->selectExistingInstitution(acc.institutionId()); | |||
124 | void Wizard::setAccount(const MyMoneyAccount& acc) | | |||
125 | { | | |||
126 | m_account = acc; | | |||
127 | m_accountTypePage->setAccount(m_account); | | |||
128 | | ||||
129 | if (!acc.institutionId().isEmpty()) { | | |||
130 | m_institutionPage->selectExistingInstitution(acc.institutionId()); | | |||
131 | } | | |||
132 | } | | |||
133 | | ||||
134 | const MyMoneySecurity& Wizard::currency() const | | |||
135 | { | | |||
136 | return m_accountTypePage->currency(); | | |||
137 | } | | |||
138 | | ||||
139 | MyMoneyMoney Wizard::interestRate() const | | |||
140 | { | | |||
141 | return m_loanDetailsPage->m_interestRate->value() / MyMoneyMoney(100, 1); | | |||
142 | } | | |||
143 | | ||||
144 | int Wizard::precision() const | | |||
145 | { | | |||
146 | return MyMoneyMoney::denomToPrec(currency().smallestAccountFraction()); | | |||
147 | } | | |||
148 | | ||||
149 | const MyMoneyAccount& Wizard::account() | | |||
150 | { | | |||
151 | m_account = MyMoneyAccountLoan(); | | |||
152 | m_account.setName(m_accountTypePage->m_accountName->text()); | | |||
153 | m_account.setOpeningDate(m_accountTypePage->m_openingDate->date()); | | |||
154 | m_account.setAccountType(m_accountTypePage->accountType()); | | |||
155 | m_account.setInstitutionId(m_institutionPage->institution().id()); | | |||
156 | m_account.setNumber(m_institutionPage->m_accountNumber->text()); | | |||
157 | m_account.setValue("iban", m_institutionPage->m_iban->text()); | | |||
158 | if (m_accountTypePage->m_preferredAccount->isChecked()) | | |||
159 | m_account.setValue("PreferredAccount", "Yes"); | | |||
160 | else | | |||
161 | m_account.deletePair("PreferredAccount"); | | |||
162 | | ||||
163 | m_account.setCurrencyId(currency().id()); | | |||
164 | if (m_account.isLoan()) { | | |||
165 | // in case we lend the money we adjust the account type | | |||
166 | if (!moneyBorrowed()) | | |||
167 | m_account.setAccountType(Account::AssetLoan); | | |||
168 | m_account.setLoanAmount(m_loanDetailsPage->m_loanAmount->value()); | | |||
169 | m_account.setInterestRate(m_loanSchedulePage->firstPaymentDueDate(), m_loanDetailsPage->m_interestRate->value()); | | |||
170 | m_account.setInterestCalculation(m_loanDetailsPage->m_paymentDue->currentIndex() == 0 ? MyMoneyAccountLoan::paymentReceived : MyMoneyAccountLoan::paymentDue); | | |||
171 | m_account.setFixedInterestRate(m_generalLoanInfoPage->m_interestType->currentIndex() == 0); | | |||
172 | m_account.setFinalPayment(m_loanDetailsPage->m_balloonAmount->value()); | | |||
173 | m_account.setTerm(m_loanDetailsPage->term()); | | |||
174 | m_account.setPeriodicPayment(m_loanDetailsPage->m_paymentAmount->value()); | | |||
175 | m_account.setPayee(m_generalLoanInfoPage->m_payee->selectedItem()); | | |||
176 | m_account.setInterestCompounding((int)m_generalLoanInfoPage->m_compoundFrequency->currentItem()); | | |||
177 | | ||||
178 | if (!m_account.fixedInterestRate()) { | | |||
179 | m_account.setNextInterestChange(m_generalLoanInfoPage->m_interestChangeDateEdit->date()); | | |||
180 | m_account.setInterestChangeFrequency(m_generalLoanInfoPage->m_interestFrequencyAmountEdit->value(), m_generalLoanInfoPage->m_interestFrequencyUnitEdit->currentIndex()); | | |||
181 | } | 129 | } | ||
182 | } | 130 | } | ||
183 | return m_account; | | |||
184 | } | | |||
185 | | ||||
186 | MyMoneyTransaction Wizard::payoutTransaction() | | |||
187 | { | | |||
188 | MyMoneyTransaction t; | | |||
189 | if (m_account.isLoan() // we're creating a loan | | |||
190 | && openingBalance().isZero() // and don't have an opening balance | | |||
191 | && !m_loanPayoutPage->m_noPayoutTransaction->isChecked()) { // and the user wants to have a payout transaction | | |||
192 | t.setPostDate(m_loanPayoutPage->m_payoutDate->date()); | | |||
193 | t.setCommodity(m_account.currencyId()); | | |||
194 | MyMoneySplit s; | | |||
195 | s.setAccountId(m_account.id()); | | |||
196 | s.setShares(m_loanDetailsPage->m_loanAmount->value()); | | |||
197 | if (moneyBorrowed()) | | |||
198 | s.setShares(-s.shares()); | | |||
199 | s.setValue(s.shares()); | | |||
200 | t.addSplit(s); | | |||
201 | | ||||
202 | s.clearId(); | | |||
203 | s.setValue(-s.value()); | | |||
204 | s.setAccountId(m_loanPayoutPage->payoutAccountId()); | | |||
205 | MyMoneyMoney shares; | | |||
206 | KCurrencyCalculator::setupSplitPrice(shares, t, s, QMap<QString, MyMoneyMoney>(), this); | | |||
207 | s.setShares(shares); | | |||
208 | t.addSplit(s); | | |||
209 | } | | |||
210 | return t; | | |||
211 | } | | |||
212 | | ||||
213 | const MyMoneyAccount& Wizard::parentAccount() | | |||
214 | { | | |||
215 | return m_accountTypePage->allowsParentAccount() | | |||
216 | ? m_hierarchyPage->parentAccount() | | |||
217 | : (m_accountTypePage->accountType() == Account::Loan | | |||
218 | ? m_generalLoanInfoPage->parentAccount() | | |||
219 | : m_accountTypePage->parentAccount()); | | |||
220 | } | | |||
221 | | ||||
222 | MyMoneyAccount Wizard::brokerageAccount() const | | |||
223 | { | | |||
224 | MyMoneyAccount account; | | |||
225 | if (m_account.accountType() == Account::Investment | | |||
226 | && m_brokeragepage->m_createBrokerageButton->isChecked()) { | | |||
227 | account.setName(m_account.brokerageName()); | | |||
228 | account.setAccountType(Account::Checkings); | | |||
229 | account.setInstitutionId(m_account.institutionId()); | | |||
230 | account.setOpeningDate(m_account.openingDate()); | | |||
231 | account.setCurrencyId(m_brokeragepage->m_brokerageCurrency->security().id()); | | |||
232 | if (m_brokeragepage->m_accountNumber->isEnabled() && !m_brokeragepage->m_accountNumber->text().isEmpty()) | | |||
233 | account.setNumber(m_brokeragepage->m_accountNumber->text()); | | |||
234 | if (m_brokeragepage->m_iban->isEnabled() && !m_brokeragepage->m_iban->text().isEmpty()) | | |||
235 | account.setValue("iban", m_brokeragepage->m_iban->text()); | | |||
236 | } | | |||
237 | return account; | | |||
238 | } | | |||
239 | | ||||
240 | const MyMoneySchedule& Wizard::schedule() | | |||
241 | { | | |||
242 | m_schedule = MyMoneySchedule(); | | |||
243 | 131 | | |||
244 | if (!m_account.id().isEmpty()) { | 132 | MyMoneyMoney Wizard::interestRate() const | ||
245 | if (m_schedulePage->m_reminderCheckBox->isChecked() && (m_account.accountType() == Account::CreditCard)) { | 133 | { | ||
246 | m_schedule.setName(m_schedulePage->m_name->text()); | 134 | Q_D(const Wizard); | ||
247 | m_schedule.setType(Schedule::Type::Transfer); | 135 | return d->m_loanDetailsPage->d_func()->ui->m_interestRate->value() / MyMoneyMoney(100, 1); | ||
248 | m_schedule.setPaymentType(static_cast<Schedule::PaymentType>(m_schedulePage->m_method->currentItem())); | 136 | } | ||
249 | m_schedule.setFixed(false); | 137 | | ||
250 | m_schedule.setOccurrencePeriod(Schedule::Occurrence::Monthly); | 138 | | ||
251 | m_schedule.setOccurrenceMultiplier(1); | 139 | | ||
252 | MyMoneyTransaction t; | 140 | const MyMoneyAccount& Wizard::account() | ||
141 | { | ||||
142 | Q_D(Wizard); | ||||
143 | d->m_account = MyMoneyAccountLoan(); | ||||
144 | d->m_account.setName(d->m_accountTypePage->d_func()->ui->m_accountName->text()); | ||||
145 | d->m_account.setOpeningDate(d->m_accountTypePage->d_func()->ui->m_openingDate->date()); | ||||
146 | d->m_account.setAccountType(d->m_accountTypePage->accountType()); | ||||
147 | d->m_account.setInstitutionId(d->m_institutionPage->institution().id()); | ||||
148 | d->m_account.setNumber(d->m_institutionPage->d_func()->ui->m_accountNumber->text()); | ||||
149 | d->m_account.setValue("iban", d->m_institutionPage->d_func()->ui->m_iban->text()); | ||||
150 | if (d->m_accountTypePage->d_func()->ui->m_preferredAccount->isChecked()) | ||||
151 | d->m_account.setValue("PreferredAccount", "Yes"); | ||||
152 | else | ||||
153 | d->m_account.deletePair("PreferredAccount"); | ||||
154 | | ||||
155 | d->m_account.setCurrencyId(d->currency().id()); | ||||
156 | if (d->m_account.isLoan()) { | ||||
157 | // in case we lend the money we adjust the account type | ||||
158 | if (!moneyBorrowed()) | ||||
159 | d->m_account.setAccountType(Account::AssetLoan); | ||||
160 | d->m_account.setLoanAmount(d->m_loanDetailsPage->d_func()->ui->m_loanAmount->value()); | ||||
161 | d->m_account.setInterestRate(d->m_loanSchedulePage->firstPaymentDueDate(), d->m_loanDetailsPage->d_func()->ui->m_interestRate->value()); | ||||
162 | d->m_account.setInterestCalculation(d->m_loanDetailsPage->d_func()->ui->m_paymentDue->currentIndex() == 0 ? MyMoneyAccountLoan::paymentReceived : MyMoneyAccountLoan::paymentDue); | ||||
163 | d->m_account.setFixedInterestRate(d->m_generalLoanInfoPage->d_func()->ui->m_interestType->currentIndex() == 0); | ||||
164 | d->m_account.setFinalPayment(d->m_loanDetailsPage->d_func()->ui->m_balloonAmount->value()); | ||||
165 | d->m_account.setTerm(d->m_loanDetailsPage->term()); | ||||
166 | d->m_account.setPeriodicPayment(d->m_loanDetailsPage->d_func()->ui->m_paymentAmount->value()); | ||||
167 | d->m_account.setPayee(d->m_generalLoanInfoPage->d_func()->ui->m_payee->selectedItem()); | ||||
168 | d->m_account.setInterestCompounding((int)d->m_generalLoanInfoPage->d_func()->ui->m_compoundFrequency->currentItem()); | ||||
169 | | ||||
170 | if (!d->m_account.fixedInterestRate()) { | ||||
171 | d->m_account.setNextInterestChange(d->m_generalLoanInfoPage->d_func()->ui->m_interestChangeDateEdit->date()); | ||||
172 | d->m_account.setInterestChangeFrequency(d->m_generalLoanInfoPage->d_func()->ui->m_interestFrequencyAmountEdit->value(), d->m_generalLoanInfoPage->d_func()->ui->m_interestFrequencyUnitEdit->currentIndex()); | ||||
173 | } | ||||
174 | } | ||||
175 | return d->m_account; | ||||
176 | } | ||||
177 | | ||||
178 | MyMoneyTransaction Wizard::payoutTransaction() | ||||
179 | { | ||||
180 | Q_D(Wizard); | ||||
181 | MyMoneyTransaction t; | ||||
182 | if (d->m_account.isLoan() // we're creating a loan | ||||
183 | && openingBalance().isZero() // and don't have an opening balance | ||||
184 | && !d->m_loanPayoutPage->d_func()->ui->m_noPayoutTransaction->isChecked()) { // and the user wants to have a payout transaction | ||||
185 | t.setPostDate(d->m_loanPayoutPage->d_func()->ui->m_payoutDate->date()); | ||||
186 | t.setCommodity(d->m_account.currencyId()); | ||||
253 | MyMoneySplit s; | 187 | MyMoneySplit s; | ||
254 | s.setPayeeId(m_schedulePage->m_payee->selectedItem()); | 188 | s.setAccountId(d->m_account.id()); | ||
255 | s.setAccountId(m_schedulePage->m_paymentAccount->selectedItem()); | 189 | s.setShares(d->m_loanDetailsPage->d_func()->ui->m_loanAmount->value()); | ||
256 | s.setMemo(i18n("Credit card payment")); | 190 | if (moneyBorrowed()) | ||
257 | s.setShares(-m_schedulePage->m_amount->value()); | 191 | s.setShares(-s.shares()); | ||
258 | s.setValue(s.shares()); | 192 | s.setValue(s.shares()); | ||
259 | t.addSplit(s); | 193 | t.addSplit(s); | ||
260 | 194 | | |||
261 | s.clearId(); | 195 | s.clearId(); | ||
262 | s.setAccountId(m_account.id()); | 196 | s.setValue(-s.value()); | ||
263 | s.setShares(m_schedulePage->m_amount->value()); | 197 | s.setAccountId(d->m_loanPayoutPage->payoutAccountId()); | ||
264 | s.setValue(s.shares()); | 198 | MyMoneyMoney shares; | ||
199 | KCurrencyCalculator::setupSplitPrice(shares, t, s, QMap<QString, MyMoneyMoney>(), this); | ||||
200 | s.setShares(shares); | ||||
265 | t.addSplit(s); | 201 | t.addSplit(s); | ||
202 | } | ||||
203 | return t; | ||||
204 | } | ||||
205 | | ||||
206 | const MyMoneyAccount& Wizard::parentAccount() | ||||
207 | { | ||||
208 | Q_D(Wizard); | ||||
209 | return d->m_accountTypePage->allowsParentAccount() | ||||
210 | ? d->m_hierarchyPage->parentAccount() | ||||
211 | : (d->m_accountTypePage->accountType() == Account::Loan | ||||
212 | ? d->m_generalLoanInfoPage->parentAccount() | ||||
213 | : d->m_accountTypePage->parentAccount()); | ||||
214 | } | ||||
215 | | ||||
216 | MyMoneyAccount Wizard::brokerageAccount() const | ||||
217 | { | ||||
218 | Q_D(const Wizard); | ||||
219 | MyMoneyAccount account; | ||||
220 | if (d->m_account.accountType() == Account::Investment | ||||
221 | && d->m_brokeragepage->d_func()->ui->m_createBrokerageButton->isChecked()) { | ||||
222 | account.setName(d->m_account.brokerageName()); | ||||
223 | account.setAccountType(Account::Checkings); | ||||
224 | account.setInstitutionId(d->m_account.institutionId()); | ||||
225 | account.setOpeningDate(d->m_account.openingDate()); | ||||
226 | account.setCurrencyId(d->m_brokeragepage->d_func()->ui->m_brokerageCurrency->security().id()); | ||||
227 | if (d->m_brokeragepage->d_func()->ui->m_accountNumber->isEnabled() && !d->m_brokeragepage->d_func()->ui->m_accountNumber->text().isEmpty()) | ||||
228 | account.setNumber(d->m_brokeragepage->d_func()->ui->m_accountNumber->text()); | ||||
229 | if (d->m_brokeragepage->d_func()->ui->m_iban->isEnabled() && !d->m_brokeragepage->d_func()->ui->m_iban->text().isEmpty()) | ||||
230 | account.setValue("iban", d->m_brokeragepage->d_func()->ui->m_iban->text()); | ||||
231 | } | ||||
232 | return account; | ||||
233 | } | ||||
234 | | ||||
235 | const MyMoneySchedule& Wizard::schedule() | ||||
236 | { | ||||
237 | Q_D(Wizard); | ||||
238 | d->m_schedule = MyMoneySchedule(); | ||||
239 | | ||||
240 | if (!d->m_account.id().isEmpty()) { | ||||
241 | if (d->m_schedulePage->d_func()->ui->m_reminderCheckBox->isChecked() && (d->m_account.accountType() == Account::CreditCard)) { | ||||
242 | d->m_schedule.setName(d->m_schedulePage->d_func()->ui->m_name->text()); | ||||
243 | d->m_schedule.setType(Schedule::Type::Transfer); | ||||
244 | d->m_schedule.setPaymentType(static_cast<Schedule::PaymentType>(d->m_schedulePage->d_func()->ui->m_method->currentItem())); | ||||
245 | d->m_schedule.setFixed(false); | ||||
246 | d->m_schedule.setOccurrencePeriod(Schedule::Occurrence::Monthly); | ||||
247 | d->m_schedule.setOccurrenceMultiplier(1); | ||||
248 | MyMoneyTransaction t; | ||||
249 | MyMoneySplit s; | ||||
250 | s.setPayeeId(d->m_schedulePage->d_func()->ui->m_payee->selectedItem()); | ||||
251 | s.setAccountId(d->m_schedulePage->d_func()->ui->m_paymentAccount->selectedItem()); | ||||
252 | s.setMemo(i18n("Credit card payment")); | ||||
253 | s.setShares(-d->m_schedulePage->d_func()->ui->m_amount->value()); | ||||
254 | s.setValue(s.shares()); | ||||
255 | t.addSplit(s); | ||||
266 | 256 | | |||
267 | // setup the next due date | 257 | s.clearId(); | ||
268 | t.setPostDate(m_schedulePage->m_date->date()); | 258 | s.setAccountId(d->m_account.id()); | ||
269 | m_schedule.setTransaction(t); | 259 | s.setShares(d->m_schedulePage->d_func()->ui->m_amount->value()); | ||
270 | 260 | s.setValue(s.shares()); | |||
271 | } else if (m_account.isLoan()) { | 261 | t.addSplit(s); | ||
272 | m_schedule.setName(i18n("Loan payment for %1", m_accountTypePage->m_accountName->text())); | | |||
273 | m_schedule.setType(Schedule::Type::LoanPayment); | | |||
274 | if (moneyBorrowed()) | | |||
275 | m_schedule.setPaymentType(Schedule::PaymentType::DirectDebit); | | |||
276 | else | | |||
277 | m_schedule.setPaymentType(Schedule::PaymentType::DirectDeposit); | | |||
278 | | ||||
279 | m_schedule.setFixed(true); | | |||
280 | m_schedule.setOccurrence(m_generalLoanInfoPage->m_paymentFrequency->currentItem()); | | |||
281 | 262 | | |||
282 | MyMoneyTransaction t; | 263 | // setup the next due date | ||
283 | t.setCommodity(m_account.currencyId()); | 264 | t.setPostDate(d->m_schedulePage->d_func()->ui->m_date->date()); | ||
284 | MyMoneySplit s; | 265 | d->m_schedule.setTransaction(t); | ||
285 | // payment split | | |||
286 | s.setPayeeId(m_generalLoanInfoPage->m_payee->selectedItem()); | | |||
287 | s.setAccountId(m_loanSchedulePage->m_paymentAccount->selectedItem()); | | |||
288 | s.setMemo(i18n("Loan payment")); | | |||
289 | s.setValue(m_loanPaymentPage->basePayment() + m_loanPaymentPage->additionalFees()); | | |||
290 | if (moneyBorrowed()) { | | |||
291 | s.setValue(-s.value()); | | |||
292 | } | | |||
293 | s.setShares(s.value()); | | |||
294 | if (m_account.id() != QLatin1String("Phony-ID")) { | | |||
295 | // if the real account is already set perform the currency conversion if it's necessary | | |||
296 | MyMoneyMoney paymentShares; | | |||
297 | KCurrencyCalculator::setupSplitPrice(paymentShares, t, s, QMap<QString, MyMoneyMoney>(), this); | | |||
298 | s.setShares(paymentShares); | | |||
299 | } | | |||
300 | t.addSplit(s); | | |||
301 | 266 | | |||
302 | // principal split | 267 | } else if (d->m_account.isLoan()) { | ||
303 | s.clearId(); | 268 | d->m_schedule.setName(i18n("Loan payment for %1", d->m_accountTypePage->d_func()->ui->m_accountName->text())); | ||
304 | s.setAccountId(m_account.id()); | 269 | d->m_schedule.setType(Schedule::Type::LoanPayment); | ||
305 | s.setShares(MyMoneyMoney::autoCalc); | 270 | if (moneyBorrowed()) | ||
306 | s.setValue(MyMoneyMoney::autoCalc); | 271 | d->m_schedule.setPaymentType(Schedule::PaymentType::DirectDebit); | ||
307 | s.setMemo(i18n("Amortization")); | 272 | else | ||
308 | s.setAction(MyMoneySplit::ActionAmortization); | 273 | d->m_schedule.setPaymentType(Schedule::PaymentType::DirectDeposit); | ||
309 | t.addSplit(s); | 274 | | ||
275 | d->m_schedule.setFixed(true); | ||||
276 | d->m_schedule.setOccurrence(d->m_generalLoanInfoPage->d_func()->ui->m_paymentFrequency->currentItem()); | ||||
277 | | ||||
278 | MyMoneyTransaction t; | ||||
279 | t.setCommodity(d->m_account.currencyId()); | ||||
280 | MyMoneySplit s; | ||||
281 | // payment split | ||||
282 | s.setPayeeId(d->m_generalLoanInfoPage->d_func()->ui->m_payee->selectedItem()); | ||||
283 | s.setAccountId(d->m_loanSchedulePage->d_func()->ui->m_paymentAccount->selectedItem()); | ||||
284 | s.setMemo(i18n("Loan payment")); | ||||
285 | s.setValue(d->m_loanPaymentPage->basePayment() + d->m_loanPaymentPage->additionalFees()); | ||||
286 | if (moneyBorrowed()) { | ||||
287 | s.setValue(-s.value()); | ||||
288 | } | ||||
289 | s.setShares(s.value()); | ||||
290 | if (d->m_account.id() != QLatin1String("Phony-ID")) { | ||||
291 | // if the real account is already set perform the currency conversion if it's necessary | ||||
292 | MyMoneyMoney paymentShares; | ||||
293 | KCurrencyCalculator::setupSplitPrice(paymentShares, t, s, QMap<QString, MyMoneyMoney>(), this); | ||||
294 | s.setShares(paymentShares); | ||||
295 | } | ||||
296 | t.addSplit(s); | ||||
310 | 297 | | |||
311 | // interest split | 298 | // principal split | ||
312 | //only add if interest is above zero | | |||
313 | if (!m_loanDetailsPage->m_interestRate->value().isZero()) { | | |||
314 | s.clearId(); | 299 | s.clearId(); | ||
315 | s.setAccountId(m_loanSchedulePage->m_interestCategory->selectedItem()); | 300 | s.setAccountId(d->m_account.id()); | ||
316 | s.setShares(MyMoneyMoney::autoCalc); | 301 | s.setShares(MyMoneyMoney::autoCalc); | ||
317 | s.setValue(MyMoneyMoney::autoCalc); | 302 | s.setValue(MyMoneyMoney::autoCalc); | ||
318 | s.setMemo(i18n("Interest")); | 303 | s.setMemo(i18n("Amortization")); | ||
319 | s.setAction(MyMoneySplit::ActionInterest); | 304 | s.setAction(MyMoneySplit::ActionAmortization); | ||
320 | t.addSplit(s); | 305 | t.addSplit(s); | ||
321 | } | | |||
322 | 306 | | |||
323 | // additional fee splits | 307 | // interest split | ||
324 | QList<MyMoneySplit> additionalSplits; | 308 | //only add if interest is above zero | ||
325 | m_loanPaymentPage->additionalFeesSplits(additionalSplits); | 309 | if (!d->m_loanDetailsPage->d_func()->ui->m_interestRate->value().isZero()) { | ||
326 | QList<MyMoneySplit>::const_iterator it; | 310 | s.clearId(); | ||
327 | MyMoneyMoney factor(moneyBorrowed() ? 1 : -1, 1); | 311 | s.setAccountId(d->m_loanSchedulePage->d_func()->ui->m_interestCategory->selectedItem()); | ||
312 | s.setShares(MyMoneyMoney::autoCalc); | ||||
313 | s.setValue(MyMoneyMoney::autoCalc); | ||||
314 | s.setMemo(i18n("Interest")); | ||||
315 | s.setAction(MyMoneySplit::ActionInterest); | ||||
316 | t.addSplit(s); | ||||
317 | } | ||||
328 | 318 | | |||
329 | for (it = additionalSplits.constBegin(); it != additionalSplits.constEnd(); ++it) { | 319 | // additional fee splits | ||
330 | s = (*it); | 320 | QList<MyMoneySplit> additionalSplits; | ||
331 | s.clearId(); | 321 | d->m_loanPaymentPage->additionalFeesSplits(additionalSplits); | ||
332 | s.setShares(s.shares() * factor); | 322 | QList<MyMoneySplit>::const_iterator it; | ||
333 | s.setValue(s.value() * factor); | 323 | MyMoneyMoney factor(moneyBorrowed() ? 1 : -1, 1); | ||
334 | t.addSplit(s); | 324 | | ||
335 | } | 325 | for (it = additionalSplits.constBegin(); it != additionalSplits.constEnd(); ++it) { | ||
326 | s = (*it); | ||||
327 | s.clearId(); | ||||
328 | s.setShares(s.shares() * factor); | ||||
329 | s.setValue(s.value() * factor); | ||||
330 | t.addSplit(s); | ||||
331 | } | ||||
336 | 332 | | |||
337 | // setup the next due date | 333 | // setup the next due date | ||
338 | t.setPostDate(m_loanSchedulePage->firstPaymentDueDate()); | 334 | t.setPostDate(d->m_loanSchedulePage->firstPaymentDueDate()); | ||
339 | m_schedule.setTransaction(t); | 335 | d->m_schedule.setTransaction(t); | ||
336 | } | ||||
340 | } | 337 | } | ||
338 | return d->m_schedule; | ||||
341 | } | 339 | } | ||
342 | return m_schedule; | | |||
343 | } | | |||
344 | | ||||
345 | MyMoneyMoney Wizard::openingBalance() const | | |||
346 | { | | |||
347 | // equity accounts don't have an opening balance | | |||
348 | if (m_accountTypePage->accountType() == Account::Equity) | | |||
349 | return MyMoneyMoney(); | | |||
350 | 340 | | |||
351 | if (m_accountTypePage->accountType() == Account::Loan) { | 341 | MyMoneyMoney Wizard::openingBalance() const | ||
352 | if (m_generalLoanInfoPage->recordAllPayments()) | 342 | { | ||
343 | Q_D(const Wizard); | ||||
344 | // equity accounts don't have an opening balance | ||||
345 | if (d->m_accountTypePage->accountType() == Account::Equity) | ||||
353 | return MyMoneyMoney(); | 346 | return MyMoneyMoney(); | ||
354 | if (moneyBorrowed()) | | |||
355 | return -(m_generalLoanInfoPage->m_openingBalance->value()); | | |||
356 | return m_generalLoanInfoPage->m_openingBalance->value(); | | |||
357 | } | | |||
358 | return m_accountTypePage->m_openingBalance->value(); | | |||
359 | } | | |||
360 | 347 | | |||
361 | MyMoneyPrice Wizard::conversionRate() const | 348 | if (d->m_accountTypePage->accountType() == Account::Loan) { | ||
362 | { | 349 | if (d->m_generalLoanInfoPage->recordAllPayments()) | ||
363 | if (MyMoneyFile::instance()->baseCurrency().id() == m_accountTypePage->m_currencyComboBox->security().id()) | 350 | return MyMoneyMoney(); | ||
351 | if (moneyBorrowed()) | ||||
352 | return -(d->m_generalLoanInfoPage->d_func()->ui->m_openingBalance->value()); | ||||
353 | return d->m_generalLoanInfoPage->d_func()->ui->m_openingBalance->value(); | ||||
354 | } | ||||
355 | return d->m_accountTypePage->d_func()->ui->m_openingBalance->value(); | ||||
356 | } | ||||
357 | | ||||
358 | MyMoneyPrice Wizard::conversionRate() const | ||||
359 | { | ||||
360 | Q_D(const Wizard); | ||||
361 | if (MyMoneyFile::instance()->baseCurrency().id() == d->m_accountTypePage->d_func()->ui->m_currencyComboBox->security().id()) | ||||
362 | return MyMoneyPrice(MyMoneyFile::instance()->baseCurrency().id(), | ||||
363 | d->m_accountTypePage->d_func()->ui->m_currencyComboBox->security().id(), | ||||
364 | d->m_accountTypePage->d_func()->ui->m_openingDate->date(), | ||||
365 | MyMoneyMoney::ONE, | ||||
366 | i18n("User")); | ||||
364 | return MyMoneyPrice(MyMoneyFile::instance()->baseCurrency().id(), | 367 | return MyMoneyPrice(MyMoneyFile::instance()->baseCurrency().id(), | ||
365 | m_accountTypePage->m_currencyComboBox->security().id(), | 368 | d->m_accountTypePage->d_func()->ui->m_currencyComboBox->security().id(), | ||
366 | m_accountTypePage->m_openingDate->date(), | 369 | d->m_accountTypePage->d_func()->ui->m_openingDate->date(), | ||
367 | MyMoneyMoney::ONE, | 370 | d->m_accountTypePage->d_func()->ui->m_conversionRate->value(), | ||
368 | i18n("User")); | 371 | i18n("User")); | ||
369 | return MyMoneyPrice(MyMoneyFile::instance()->baseCurrency().id(), | | |||
370 | m_accountTypePage->m_currencyComboBox->security().id(), | | |||
371 | m_accountTypePage->m_openingDate->date(), | | |||
372 | m_accountTypePage->m_conversionRate->value(), | | |||
373 | i18n("User")); | | |||
374 | } | | |||
375 | | ||||
376 | bool Wizard::moneyBorrowed() const | | |||
377 | { | | |||
378 | return m_generalLoanInfoPage->m_loanDirection->currentIndex() == 0; | | |||
379 | } | | |||
380 | | ||||
381 | class InstitutionPage::Private | | |||
382 | { | | |||
383 | public: | | |||
384 | QList<MyMoneyInstitution> m_list; | | |||
385 | }; | | |||
386 | | ||||
387 | InstitutionPage::InstitutionPage(Wizard* wizard) : | | |||
388 | KInstitutionPageDecl(wizard), | | |||
389 | WizardPage<Wizard>(StepInstitution, this, wizard), | | |||
390 | d(new Private()) | | |||
391 | { | | |||
392 | connect(MyMoneyFile::instance(), SIGNAL(dataChanged()), this, SLOT(slotLoadWidgets())); | | |||
393 | connect(m_newInstitutionButton, SIGNAL(clicked()), this, SLOT(slotNewInstitution())); | | |||
394 | connect(m_institutionComboBox, SIGNAL(activated(int)), this, SLOT(slotSelectInstitution(int))); | | |||
395 | | ||||
396 | slotLoadWidgets(); | | |||
397 | m_institutionComboBox->setCurrentItem(0); | | |||
398 | slotSelectInstitution(0); | | |||
399 | } | | |||
400 | | ||||
401 | InstitutionPage::~InstitutionPage() | | |||
402 | { | | |||
403 | delete d; | | |||
404 | } | | |||
405 | | ||||
406 | void InstitutionPage::slotLoadWidgets() | | |||
407 | { | | |||
408 | m_institutionComboBox->clear(); | | |||
409 | | ||||
410 | d->m_list.clear(); | | |||
411 | MyMoneyFile::instance()->institutionList(d->m_list); | | |||
412 | qSort(d->m_list); | | |||
413 | | ||||
414 | QList<MyMoneyInstitution>::const_iterator it_l; | | |||
415 | m_institutionComboBox->addItem(QString()); | | |||
416 | for (it_l = d->m_list.constBegin(); it_l != d->m_list.constEnd(); ++it_l) { | | |||
417 | m_institutionComboBox->addItem((*it_l).name()); | | |||
418 | } | | |||
419 | } | | |||
420 | | ||||
421 | void InstitutionPage::slotNewInstitution() | | |||
422 | { | | |||
423 | MyMoneyInstitution institution; | | |||
424 | | ||||
425 | emit m_wizard->createInstitution(institution); | | |||
426 | | ||||
427 | if (!institution.id().isEmpty()) { | | |||
428 | QList<MyMoneyInstitution>::const_iterator it_l; | | |||
429 | int i = 0; | | |||
430 | for (it_l = d->m_list.constBegin(); it_l != d->m_list.constEnd(); ++it_l) { | | |||
431 | if ((*it_l).id() == institution.id()) { | | |||
432 | // select the item and remember that the very first one is the empty item | | |||
433 | m_institutionComboBox->setCurrentIndex(i + 1); | | |||
434 | slotSelectInstitution(i + 1); | | |||
435 | m_accountNumber->setFocus(); | | |||
436 | break; | | |||
437 | } | | |||
438 | ++i; | | |||
439 | } | | |||
440 | } | | |||
441 | } | | |||
442 | | ||||
443 | void InstitutionPage::slotSelectInstitution(const int index) | | |||
444 | { | | |||
445 | m_accountNumber->setEnabled(index != 0); | | |||
446 | m_iban->setEnabled(index != 0); | | |||
447 | } | | |||
448 | | ||||
449 | void InstitutionPage::selectExistingInstitution(const QString& id) | | |||
450 | { | | |||
451 | for (int i = 0; i < d->m_list.length(); ++i) { | | |||
452 | if (d->m_list[i].id() == id) { | | |||
453 | m_institutionComboBox->setCurrentIndex(i + 1); | | |||
454 | slotSelectInstitution(i + 1); | | |||
455 | break; | | |||
456 | } | | |||
457 | } | | |||
458 | } | | |||
459 | | ||||
460 | const MyMoneyInstitution& InstitutionPage::institution() const | | |||
461 | { | | |||
462 | static MyMoneyInstitution emptyInstitution; | | |||
463 | if (m_institutionComboBox->currentIndex() == 0) | | |||
464 | return emptyInstitution; | | |||
465 | | ||||
466 | return d->m_list[m_institutionComboBox->currentIndex()-1]; | | |||
467 | } | | |||
468 | | ||||
469 | KMyMoneyWizardPage* InstitutionPage::nextPage() const | | |||
470 | { | | |||
471 | return m_wizard->m_accountTypePage; | | |||
472 | } | | |||
473 | | ||||
474 | AccountTypePage::AccountTypePage(Wizard* wizard) : | | |||
475 | KAccountTypePageDecl(wizard), | | |||
476 | WizardPage<Wizard>(StepAccount, this, wizard), | | |||
477 | m_showPriceWarning(true) | | |||
478 | { | | |||
479 | m_typeSelection->insertItem(i18n("Checking"), (int)Account::Checkings); | | |||
480 | m_typeSelection->insertItem(i18n("Savings"), (int)Account::Savings); | | |||
481 | m_typeSelection->insertItem(i18n("Credit Card"), (int)Account::CreditCard); | | |||
482 | m_typeSelection->insertItem(i18n("Cash"), (int)Account::Cash); | | |||
483 | m_typeSelection->insertItem(i18n("Loan"), (int)Account::Loan); | | |||
484 | m_typeSelection->insertItem(i18n("Investment"), (int)Account::Investment); | | |||
485 | m_typeSelection->insertItem(i18n("Asset"), (int)Account::Asset); | | |||
486 | m_typeSelection->insertItem(i18n("Liability"), (int)Account::Liability); | | |||
487 | if (KMyMoneyGlobalSettings::expertMode()) { | | |||
488 | m_typeSelection->insertItem(i18n("Equity"), (int)Account::Equity); | | |||
489 | } | | |||
490 | | ||||
491 | m_typeSelection->setCurrentItem((int)Account::Checkings); | | |||
492 | | ||||
493 | m_currencyComboBox->setSecurity(MyMoneyFile::instance()->baseCurrency()); | | |||
494 | | ||||
495 | m_mandatoryGroup->add(m_accountName); | | |||
496 | m_mandatoryGroup->add(m_conversionRate->lineedit()); | | |||
497 | | ||||
498 | m_conversionRate->setValue(MyMoneyMoney::ONE); | | |||
499 | slotUpdateCurrency(); | | |||
500 | | ||||
501 | connect(m_typeSelection, SIGNAL(itemSelected(int)), this, SLOT(slotUpdateType(int))); | | |||
502 | connect(m_currencyComboBox, SIGNAL(activated(int)), this, SLOT(slotUpdateCurrency())); | | |||
503 | connect(m_conversionRate, SIGNAL(textChanged(QString)), this, SLOT(slotUpdateConversionRate(QString))); | | |||
504 | connect(m_conversionRate, SIGNAL(valueChanged(QString)), this, SLOT(slotPriceWarning())); | | |||
505 | connect(m_onlineQuote, SIGNAL(clicked()), this, SLOT(slotGetOnlineQuote())); | | |||
506 | } | | |||
507 | | ||||
508 | void AccountTypePage::slotUpdateType(int i) | | |||
509 | { | | |||
510 | hideShowPages(static_cast<Account>(i)); | | |||
511 | m_openingBalance->setDisabled(static_cast<Account>(i) == Account::Equity); | | |||
512 | } | | |||
513 | | ||||
514 | void AccountTypePage::hideShowPages(Account accountType) const | | |||
515 | { | | |||
516 | bool hideSchedulePage = (accountType != Account::CreditCard) | | |||
517 | && (accountType != Account::Loan); | | |||
518 | bool hideLoanPage = (accountType != Account::Loan); | | |||
519 | m_wizard->setStepHidden(StepDetails, hideLoanPage); | | |||
520 | m_wizard->setStepHidden(StepPayments, hideLoanPage); | | |||
521 | m_wizard->setStepHidden(StepFees, hideLoanPage); | | |||
522 | m_wizard->setStepHidden(StepSchedule, hideSchedulePage); | | |||
523 | m_wizard->setStepHidden(StepPayout, (accountType != Account::Loan)); | | |||
524 | m_wizard->setStepHidden(StepBroker, accountType != Account::Investment); | | |||
525 | m_wizard->setStepHidden(StepParentAccount, accountType == Account::Loan); | | |||
526 | // Force an update of the steps in case the list has changed | | |||
527 | m_wizard->reselectStep(); | | |||
528 | } | | |||
529 | | ||||
530 | KMyMoneyWizardPage* AccountTypePage::nextPage() const | | |||
531 | { | | |||
532 | if (accountType() == Account::Loan) | | |||
533 | return m_wizard->m_generalLoanInfoPage; | | |||
534 | if (accountType() == Account::CreditCard) | | |||
535 | return m_wizard->m_schedulePage; | | |||
536 | if (accountType() == Account::Investment) | | |||
537 | return m_wizard->m_brokeragepage; | | |||
538 | return m_wizard->m_hierarchyPage; | | |||
539 | } | | |||
540 | | ||||
541 | void AccountTypePage::slotUpdateCurrency() | | |||
542 | { | | |||
543 | MyMoneyAccount acc; | | |||
544 | acc.setAccountType(accountType()); | | |||
545 | | ||||
546 | m_openingBalance->setPrecision(MyMoneyMoney::denomToPrec(acc.fraction(currency()))); | | |||
547 | | ||||
548 | bool show = m_currencyComboBox->security().id() != MyMoneyFile::instance()->baseCurrency().id(); | | |||
549 | m_conversionLabel->setVisible(show); | | |||
550 | m_conversionRate->setVisible(show); | | |||
551 | m_conversionExample->setVisible(show); | | |||
552 | m_onlineQuote->setVisible(show); | | |||
553 | m_conversionRate->setEnabled(show); // make sure to include/exclude in mandatoryGroup | | |||
554 | m_conversionRate->setPrecision(m_currencyComboBox->security().pricePrecision()); | | |||
555 | m_mandatoryGroup->changed(); | | |||
556 | slotUpdateConversionRate(m_conversionRate->lineedit()->text()); | | |||
557 | } | | |||
558 | | ||||
559 | void AccountTypePage::slotGetOnlineQuote() | | |||
560 | { | | |||
561 | QString id = MyMoneyFile::instance()->baseCurrency().id() + ' ' + m_currencyComboBox->security().id(); | | |||
562 | QPointer<KEquityPriceUpdateDlg> dlg = new KEquityPriceUpdateDlg(this, id); | | |||
563 | if (dlg->exec() == QDialog::Accepted) { | | |||
564 | const MyMoneyPrice &price = dlg->price(id); | | |||
565 | if (price.isValid()) { | | |||
566 | m_conversionRate->setValue(price.rate(m_currencyComboBox->security().id())); | | |||
567 | if (price.date() != m_openingDate->date()) { | | |||
568 | priceWarning(true); | | |||
569 | } | | |||
570 | } | | |||
571 | } | | |||
572 | delete dlg; | | |||
573 | } | | |||
574 | | ||||
575 | void AccountTypePage::slotPriceWarning() | | |||
576 | { | | |||
577 | priceWarning(false); | | |||
578 | } | | |||
579 | | ||||
580 | void AccountTypePage::priceWarning(bool always) | | |||
581 | { | | |||
582 | if (m_showPriceWarning || always) { | | |||
583 | 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")); | | |||
584 | } | | |||
585 | m_showPriceWarning = false; | | |||
586 | } | | |||
587 | | ||||
588 | void AccountTypePage::slotUpdateConversionRate(const QString& txt) | | |||
589 | { | | |||
590 | m_conversionExample->setText(i18n("1 %1 equals %2", MyMoneyFile::instance()->baseCurrency().tradingSymbol(), MyMoneyMoney(txt).formatMoney(m_currencyComboBox->security().tradingSymbol(), m_currencyComboBox->security().pricePrecision()))); | | |||
591 | } | | |||
592 | | ||||
593 | bool AccountTypePage::isComplete() const | | |||
594 | { | | |||
595 | // check that the conversion rate is positive if enabled | | |||
596 | bool rc = !m_conversionRate->isVisible() || (!m_conversionRate->value().isZero() && !m_conversionRate->value().isNegative()); | | |||
597 | if (!rc) { | | |||
598 | m_wizard->m_nextButton->setToolTip(i18n("Conversion rate is not positive")); | | |||
599 | | ||||
600 | } else { | | |||
601 | rc = KMyMoneyWizardPage::isComplete(); | | |||
602 | | ||||
603 | if (!rc) { | | |||
604 | m_wizard->m_nextButton->setToolTip(i18n("No account name supplied")); | | |||
605 | } | | |||
606 | } | | |||
607 | hideShowPages(accountType()); | | |||
608 | return rc; | | |||
609 | } | | |||
610 | | ||||
611 | Account AccountTypePage::accountType() const | | |||
612 | { | | |||
613 | return static_cast<Account>(m_typeSelection->currentItem()); | | |||
614 | } | | |||
615 | | ||||
616 | const MyMoneySecurity& AccountTypePage::currency() const | | |||
617 | { | | |||
618 | return m_currencyComboBox->security(); | | |||
619 | } | | |||
620 | | ||||
621 | void AccountTypePage::setAccount(const MyMoneyAccount& acc) | | |||
622 | { | | |||
623 | if (acc.accountType() != Account::Unknown) { | | |||
624 | if (acc.accountType() == Account::AssetLoan) { | | |||
625 | m_typeSelection->setCurrentItem((int)Account::Loan); | | |||
626 | } else { | | |||
627 | m_typeSelection->setCurrentItem((int)acc.accountType()); | | |||
628 | } | | |||
629 | } | | |||
630 | m_openingDate->setDate(acc.openingDate()); | | |||
631 | m_accountName->setText(acc.name()); | | |||
632 | } | | |||
633 | | ||||
634 | const MyMoneyAccount& AccountTypePage::parentAccount() | | |||
635 | { | | |||
636 | switch (accountType()) { | | |||
637 | case Account::CreditCard: | | |||
638 | case Account::Liability: | | |||
639 | case Account::Loan: // Can be either but we return liability here | | |||
640 | return MyMoneyFile::instance()->liability(); | | |||
641 | break; | | |||
642 | case Account::Equity: | | |||
643 | return MyMoneyFile::instance()->equity(); | | |||
644 | default: | | |||
645 | break; | | |||
646 | } | | |||
647 | return MyMoneyFile::instance()->asset(); | | |||
648 | } | | |||
649 | | ||||
650 | bool AccountTypePage::allowsParentAccount() const | | |||
651 | { | | |||
652 | return accountType() != Account::Loan; | | |||
653 | } | | |||
654 | | ||||
655 | BrokeragePage::BrokeragePage(Wizard* wizard) : | | |||
656 | KBrokeragePageDecl(wizard), | | |||
657 | WizardPage<Wizard>(StepBroker, this, wizard) | | |||
658 | { | | |||
659 | connect(MyMoneyFile::instance(), SIGNAL(dataChanged()), this, SLOT(slotLoadWidgets())); | | |||
660 | } | | |||
661 | | ||||
662 | void BrokeragePage::slotLoadWidgets() | | |||
663 | { | | |||
664 | m_brokerageCurrency->update(QString("x")); | | |||
665 | } | | |||
666 | | ||||
667 | void BrokeragePage::enterPage() | | |||
668 | { | | |||
669 | // assign the currency of the investment account to the | | |||
670 | // brokerage account if nothing else has ever been selected | | |||
671 | if (m_brokerageCurrency->security().id().isEmpty()) { | | |||
672 | m_brokerageCurrency->setSecurity(m_wizard->m_accountTypePage->m_currencyComboBox->security()); | | |||
673 | } | | |||
674 | | ||||
675 | // check if the institution relevant fields should be enabled or not | | |||
676 | bool enabled = m_wizard->m_institutionPage->m_accountNumber->isEnabled(); | | |||
677 | m_accountNumberLabel->setEnabled(enabled); | | |||
678 | m_accountNumber->setEnabled(enabled); | | |||
679 | m_ibanLabel->setEnabled(enabled); | | |||
680 | m_iban->setEnabled(enabled); | | |||
681 | } | | |||
682 | | ||||
683 | KMyMoneyWizardPage* BrokeragePage::nextPage() const | | |||
684 | { | | |||
685 | return m_wizard->m_hierarchyPage; | | |||
686 | } | | |||
687 | | ||||
688 | CreditCardSchedulePage::CreditCardSchedulePage(Wizard* wizard) : | | |||
689 | KSchedulePageDecl(wizard), | | |||
690 | WizardPage<Wizard>(StepSchedule, this, wizard) | | |||
691 | { | | |||
692 | m_mandatoryGroup->add(m_name); | | |||
693 | m_mandatoryGroup->add(m_payee); | | |||
694 | m_mandatoryGroup->add(m_amount->lineedit()); | | |||
695 | m_mandatoryGroup->add(m_paymentAccount); | | |||
696 | connect(m_paymentAccount, SIGNAL(itemSelected(QString)), object(), SIGNAL(completeStateChanged())); | | |||
697 | connect(m_payee, SIGNAL(itemSelected(QString)), object(), SIGNAL(completeStateChanged())); | | |||
698 | connect(m_date, SIGNAL(dateChanged(QDate)), object(), SIGNAL(completeStateChanged())); | | |||
699 | | ||||
700 | connect(m_payee, SIGNAL(createItem(QString,QString&)), wizard, SIGNAL(createPayee(QString,QString&))); | | |||
701 | | ||||
702 | m_reminderCheckBox->setChecked(true); | | |||
703 | connect(m_reminderCheckBox, SIGNAL(toggled(bool)), object(), SIGNAL(completeStateChanged())); | | |||
704 | | ||||
705 | connect(MyMoneyFile::instance(), SIGNAL(dataChanged()), this, SLOT(slotLoadWidgets())); | | |||
706 | | ||||
707 | m_method->insertItem(i18n("Write check"), (int)Schedule::PaymentType::WriteChecque); | | |||
708 | #if 0 | | |||
709 | m_method->insertItem(i18n("Direct debit"), Schedule::PaymentType::DirectDebit); | | |||
710 | m_method->insertItem(i18n("Bank transfer"), Schedule::PaymentType::BankTransfer); | | |||
711 | #endif | | |||
712 | m_method->insertItem(i18n("Standing order"), (int)Schedule::PaymentType::StandingOrder); | | |||
713 | m_method->insertItem(i18n("Manual deposit"), (int)Schedule::PaymentType::ManualDeposit); | | |||
714 | m_method->insertItem(i18n("Direct deposit"), (int)Schedule::PaymentType::DirectDeposit); | | |||
715 | m_method->insertItem(i18nc("Other payment method", "Other"), (int)Schedule::PaymentType::Other); | | |||
716 | m_method->setCurrentItem((int)Schedule::PaymentType::DirectDebit); | | |||
717 | | ||||
718 | slotLoadWidgets(); | | |||
719 | } | | |||
720 | | ||||
721 | void CreditCardSchedulePage::enterPage() | | |||
722 | { | | |||
723 | if (m_name->text().isEmpty()) | | |||
724 | m_name->setText(i18n("Credit Card %1 monthly payment", m_wizard->m_accountTypePage->m_accountName->text())); | | |||
725 | } | | |||
726 | | ||||
727 | bool CreditCardSchedulePage::isComplete() const | | |||
728 | { | | |||
729 | bool rc = true; | | |||
730 | QString msg = i18n("Finish entry and create account"); | | |||
731 | if (m_reminderCheckBox->isChecked()) { | | |||
732 | msg = i18n("Finish entry and create account and schedule"); | | |||
733 | if (m_date->date() < m_wizard->m_accountTypePage->m_openingDate->date()) { | | |||
734 | rc = false; | | |||
735 | msg = i18n("Next due date is prior to opening date"); | | |||
736 | } | | |||
737 | if (m_paymentAccount->selectedItem().isEmpty()) { | | |||
738 | rc = false; | | |||
739 | msg = i18n("No account selected"); | | |||
740 | } | | |||
741 | if (m_amount->lineedit()->text().isEmpty()) { | | |||
742 | rc = false; | | |||
743 | msg = i18n("No amount for payment selected"); | | |||
744 | } | | |||
745 | if (m_payee->selectedItem().isEmpty()) { | | |||
746 | rc = false; | | |||
747 | msg = i18n("No payee for payment selected"); | | |||
748 | } | | |||
749 | if (m_name->text().isEmpty()) { | | |||
750 | rc = false; | | |||
751 | msg = i18n("No name assigned for schedule"); | | |||
752 | } | | |||
753 | } | | |||
754 | m_wizard->m_finishButton->setToolTip(msg); | | |||
755 | | ||||
756 | return rc; | | |||
757 | } | | |||
758 | | ||||
759 | void CreditCardSchedulePage::slotLoadWidgets() | | |||
760 | { | | |||
761 | AccountSet set; | | |||
762 | set.addAccountGroup(Account::Asset); | | |||
763 | set.load(m_paymentAccount->selector()); | | |||
764 | | ||||
765 | m_payee->loadPayees(MyMoneyFile::instance()->payeeList()); | | |||
766 | } | | |||
767 | | ||||
768 | KMyMoneyWizardPage* CreditCardSchedulePage::nextPage() const | | |||
769 | { | | |||
770 | return m_wizard->m_hierarchyPage; | | |||
771 | } | | |||
772 | | ||||
773 | GeneralLoanInfoPage::GeneralLoanInfoPage(Wizard* wizard) : | | |||
774 | KGeneralLoanInfoPageDecl(wizard), | | |||
775 | WizardPage<Wizard>(StepDetails, this, wizard), | | |||
776 | m_firstTime(true) | | |||
777 | { | | |||
778 | m_mandatoryGroup->add(m_payee); | | |||
779 | | ||||
780 | // remove the unsupported payment and compounding frequencies and setup default | | |||
781 | m_paymentFrequency->removeItem((int)Schedule::Occurrence::Once); | | |||
782 | m_paymentFrequency->removeItem((int)Schedule::Occurrence::EveryOtherYear); | | |||
783 | m_paymentFrequency->setCurrentItem((int)Schedule::Occurrence::Monthly); | | |||
784 | m_compoundFrequency->removeItem((int)Schedule::Occurrence::Once); | | |||
785 | m_compoundFrequency->removeItem((int)Schedule::Occurrence::EveryOtherYear); | | |||
786 | m_compoundFrequency->setCurrentItem((int)Schedule::Occurrence::Monthly); | | |||
787 | | ||||
788 | slotLoadWidgets(); | | |||
789 | | ||||
790 | connect(m_payee, SIGNAL(createItem(QString,QString&)), wizard, SIGNAL(createPayee(QString,QString&))); | | |||
791 | connect(m_anyPayments, SIGNAL(activated(int)), object(), SIGNAL(completeStateChanged())); | | |||
792 | connect(m_recordings, SIGNAL(activated(int)), object(), SIGNAL(completeStateChanged())); | | |||
793 | | ||||
794 | connect(m_interestType, SIGNAL(activated(int)), object(), SIGNAL(completeStateChanged())); | | |||
795 | connect(m_interestChangeDateEdit, SIGNAL(dateChanged(QDate)), object(), SIGNAL(completeStateChanged())); | | |||
796 | connect(m_openingBalance, SIGNAL(textChanged(QString)), object(), SIGNAL(completeStateChanged())); | | |||
797 | | ||||
798 | connect(MyMoneyFile::instance(), SIGNAL(dataChanged()), this, SLOT(slotLoadWidgets())); | | |||
799 | } | | |||
800 | | ||||
801 | KMyMoneyWizardPage* GeneralLoanInfoPage::nextPage() const | | |||
802 | { | | |||
803 | return m_wizard->m_loanDetailsPage; | | |||
804 | } | | |||
805 | | ||||
806 | bool GeneralLoanInfoPage::recordAllPayments() const | | |||
807 | { | | |||
808 | bool rc = true; // all payments | | |||
809 | if (m_recordings->isEnabled()) { | | |||
810 | if (m_recordings->currentIndex() != 0) | | |||
811 | rc = false; | | |||
812 | } | | |||
813 | return rc; | | |||
814 | } | | |||
815 | | ||||
816 | void GeneralLoanInfoPage::enterPage() | | |||
817 | { | | |||
818 | if (m_firstTime) { | | |||
819 | // setup default dates to last of this month and one year on top | | |||
820 | QDate firstDay(QDate::currentDate().year(), QDate::currentDate().month(), 1); | | |||
821 | m_firstPaymentDate->setDate(firstDay.addMonths(1).addDays(-1)); | | |||
822 | m_interestChangeDateEdit->setDate(m_firstPaymentDate->date().addYears(1));; | | |||
823 | m_firstTime = false; | | |||
824 | } | | |||
825 | } | | |||
826 | | ||||
827 | bool GeneralLoanInfoPage::isComplete() const | | |||
828 | { | | |||
829 | m_wizard->setStepHidden(StepPayout, !m_wizard->openingBalance().isZero()); | | |||
830 | bool rc = KMyMoneyWizardPage::isComplete(); | | |||
831 | if (!rc) { | | |||
832 | m_wizard->m_nextButton->setToolTip(i18n("No payee supplied")); | | |||
833 | } | | |||
834 | | ||||
835 | // fixup availability of items on this page | | |||
836 | m_recordings->setDisabled(m_anyPayments->currentIndex() == 0); | | |||
837 | | ||||
838 | m_interestFrequencyAmountEdit->setDisabled(m_interestType->currentIndex() == 0); | | |||
839 | m_interestFrequencyUnitEdit->setDisabled(m_interestType->currentIndex() == 0); | | |||
840 | m_interestChangeDateEdit->setDisabled(m_interestType->currentIndex() == 0); | | |||
841 | | ||||
842 | m_openingBalance->setDisabled(recordAllPayments()); | | |||
843 | | ||||
844 | if (m_openingBalance->isEnabled() && m_openingBalance->lineedit()->text().length() == 0) { | | |||
845 | rc = false; | | |||
846 | m_wizard->m_nextButton->setToolTip(i18n("No opening balance supplied")); | | |||
847 | } | 372 | } | ||
848 | 373 | | |||
849 | if (rc | 374 | bool Wizard::moneyBorrowed() const | ||
850 | && (m_interestType->currentIndex() != 0) | 375 | { | ||
851 | && (m_interestChangeDateEdit->date() <= m_firstPaymentDate->date())) { | 376 | Q_D(const Wizard); | ||
852 | rc = false; | 377 | return d->m_generalLoanInfoPage->d_func()->ui->m_loanDirection->currentIndex() == 0; | ||
853 | m_wizard->m_nextButton->setToolTip(i18n("An interest change can only happen after the first payment")); | | |||
854 | } | 378 | } | ||
855 | return rc; | | |||
856 | } | | |||
857 | | ||||
858 | const MyMoneyAccount& GeneralLoanInfoPage::parentAccount() | | |||
859 | { | | |||
860 | return (m_loanDirection->currentIndex() == 0) | | |||
861 | ? MyMoneyFile::instance()->liability() | | |||
862 | : MyMoneyFile::instance()->asset(); | | |||
863 | } | | |||
864 | | ||||
865 | void GeneralLoanInfoPage::slotLoadWidgets() | | |||
866 | { | | |||
867 | m_payee->loadPayees(MyMoneyFile::instance()->payeeList()); | | |||
868 | } | | |||
869 | | ||||
870 | LoanDetailsPage::LoanDetailsPage(Wizard* wizard) : | | |||
871 | KLoanDetailsPageDecl(wizard), | | |||
872 | WizardPage<Wizard>(StepPayments, this, wizard), | | |||
873 | m_needCalculate(true) | | |||
874 | { | | |||
875 | // force the balloon payment to zero (default) | | |||
876 | m_balloonAmount->setValue(MyMoneyMoney()); | | |||
877 | // allow any precision for the interest rate | | |||
878 | m_interestRate->setPrecision(-1); | | |||
879 | | ||||
880 | connect(m_paymentDue, SIGNAL(activated(int)), this, SLOT(slotValuesChanged())); | | |||
881 | | ||||
882 | connect(m_termAmount, SIGNAL(valueChanged(int)), this, SLOT(slotValuesChanged())); | | |||
883 | connect(m_termUnit, SIGNAL(highlighted(int)), this, SLOT(slotValuesChanged())); | | |||
884 | connect(m_loanAmount, SIGNAL(textChanged(QString)), this, SLOT(slotValuesChanged())); | | |||
885 | connect(m_interestRate, SIGNAL(textChanged(QString)), this, SLOT(slotValuesChanged())); | | |||
886 | connect(m_paymentAmount, SIGNAL(textChanged(QString)), this, SLOT(slotValuesChanged())); | | |||
887 | connect(m_balloonAmount, SIGNAL(textChanged(QString)), this, SLOT(slotValuesChanged())); | | |||
888 | | ||||
889 | connect(m_calculateButton, SIGNAL(clicked()), this, SLOT(slotCalculate())); | | |||
890 | } | | |||
891 | | ||||
892 | void LoanDetailsPage::enterPage() | | |||
893 | { | | |||
894 | // we need to remove a bunch of entries of the payment frequencies | | |||
895 | m_termUnit->clear(); | | |||
896 | | ||||
897 | m_mandatoryGroup->clear(); | | |||
898 | if (!m_wizard->openingBalance().isZero()) { | | |||
899 | m_mandatoryGroup->add(m_loanAmount->lineedit()); | | |||
900 | if (m_loanAmount->lineedit()->text().length() == 0) { | | |||
901 | m_loanAmount->setValue(m_wizard->openingBalance().abs()); | | |||
902 | } | | |||
903 | } | | |||
904 | | ||||
905 | switch (m_wizard->m_generalLoanInfoPage->m_paymentFrequency->currentItem()) { | | |||
906 | default: | | |||
907 | m_termUnit->insertItem(i18n("Payments"), (int)Schedule::Occurrence::Once); | | |||
908 | m_termUnit->setCurrentItem((int)Schedule::Occurrence::Once); | | |||
909 | break; | | |||
910 | case Schedule::Occurrence::Monthly: | | |||
911 | m_termUnit->insertItem(i18n("Months"), (int)Schedule::Occurrence::Monthly); | | |||
912 | m_termUnit->insertItem(i18n("Years"), (int)Schedule::Occurrence::Yearly); | | |||
913 | m_termUnit->setCurrentItem((int)Schedule::Occurrence::Monthly); | | |||
914 | break; | | |||
915 | case Schedule::Occurrence::Yearly: | | |||
916 | m_termUnit->insertItem(i18n("Years"), (int)Schedule::Occurrence::Yearly); | | |||
917 | m_termUnit->setCurrentItem((int)Schedule::Occurrence::Yearly); | | |||
918 | break; | | |||
919 | } | | |||
920 | } | | |||
921 | | ||||
922 | void LoanDetailsPage::slotValuesChanged() | | |||
923 | { | | |||
924 | m_needCalculate = true; | | |||
925 | m_wizard->completeStateChanged(); | | |||
926 | } | | |||
927 | | ||||
928 | void LoanDetailsPage::slotCalculate() | | |||
929 | { | | |||
930 | MyMoneyFinancialCalculator calc; | | |||
931 | double val; | | |||
932 | int PF, CF; | | |||
933 | QString result; | | |||
934 | bool moneyBorrowed = m_wizard->moneyBorrowed(); | | |||
935 | bool moneyLend = !moneyBorrowed; | | |||
936 | | ||||
937 | // FIXME: for now, we only support interest calculation at the end of the period | | |||
938 | calc.setBep(); | | |||
939 | // FIXME: for now, we only support periodic compounding | | |||
940 | calc.setDisc(); | | |||
941 | | ||||
942 | PF = m_wizard->m_generalLoanInfoPage->m_paymentFrequency->eventsPerYear(); | | |||
943 | CF = m_wizard->m_generalLoanInfoPage->m_compoundFrequency->eventsPerYear(); | | |||
944 | | ||||
945 | if (PF == 0 || CF == 0) | | |||
946 | return; | | |||
947 | | ||||
948 | calc.setPF(PF); | | |||
949 | calc.setCF(CF); | | |||
950 | | ||||
951 | | ||||
952 | if (!m_loanAmount->lineedit()->text().isEmpty()) { | | |||
953 | val = m_loanAmount->value().abs().toDouble(); | | |||
954 | if (moneyBorrowed) | | |||
955 | val = -val; | | |||
956 | calc.setPv(val); | | |||
957 | } | | |||
958 | | ||||
959 | if (!m_interestRate->lineedit()->text().isEmpty()) { | | |||
960 | val = m_interestRate->value().abs().toDouble(); | | |||
961 | calc.setIr(val); | | |||
962 | } | | |||
963 | | ||||
964 | if (!m_paymentAmount->lineedit()->text().isEmpty()) { | | |||
965 | val = m_paymentAmount->value().abs().toDouble(); | | |||
966 | if (moneyLend) | | |||
967 | val = -val; | | |||
968 | calc.setPmt(val); | | |||
969 | } | | |||
970 | | ||||
971 | if (!m_balloonAmount->lineedit()->text().isEmpty()) { | | |||
972 | val = m_balloonAmount->value().abs().toDouble(); | | |||
973 | if (moneyLend) | | |||
974 | val = -val; | | |||
975 | calc.setFv(val); | | |||
976 | } | | |||
977 | | ||||
978 | if (m_termAmount->value() != 0) { | | |||
979 | calc.setNpp(term()); | | |||
980 | } | | |||
981 | | ||||
982 | // setup of parameters is done, now do the calculation | | |||
983 | try { | | |||
984 | if (m_loanAmount->lineedit()->text().isEmpty()) { | | |||
985 | // calculate the amount of the loan out of the other information | | |||
986 | val = calc.presentValue(); | | |||
987 | m_loanAmount->loadText(MyMoneyMoney(static_cast<double>(val)).abs().formatMoney(QString(), m_wizard->precision())); | | |||
988 | result = i18n("KMyMoney has calculated the amount of the loan as %1.", m_loanAmount->lineedit()->text()); | | |||
989 | | ||||
990 | } else if (m_interestRate->lineedit()->text().isEmpty()) { | | |||
991 | // calculate the interest rate out of the other information | | |||
992 | val = calc.interestRate(); | | |||
993 | | ||||
994 | m_interestRate->loadText(MyMoneyMoney(static_cast<double>(val)).abs().formatMoney(QString(), 3)); | | |||
995 | result = i18n("KMyMoney has calculated the interest rate to %1%.", m_interestRate->lineedit()->text()); | | |||
996 | | ||||
997 | } else if (m_paymentAmount->lineedit()->text().isEmpty()) { | | |||
998 | // calculate the periodical amount of the payment out of the other information | | |||
999 | val = calc.payment(); | | |||
1000 | m_paymentAmount->setValue(MyMoneyMoney(static_cast<double>(val)).abs()); | | |||
1001 | // reset payment as it might have changed due to rounding | | |||
1002 | val = m_paymentAmount->value().abs().toDouble(); | | |||
1003 | if (moneyLend) | | |||
1004 | val = -val; | | |||
1005 | calc.setPmt(val); | | |||
1006 | | ||||
1007 | result = i18n("KMyMoney has calculated a periodic payment of %1 to cover principal and interest.", m_paymentAmount->lineedit()->text()); | | |||
1008 | | ||||
1009 | val = calc.futureValue(); | | |||
1010 | if ((moneyBorrowed && val < 0 && qAbs(val) >= qAbs(calc.payment())) | | |||
1011 | || (moneyLend && val > 0 && qAbs(val) >= qAbs(calc.payment()))) { | | |||
1012 | calc.setNpp(calc.npp() - 1); | | |||
1013 | // updateTermWidgets(calc.npp()); | | |||
1014 | val = calc.futureValue(); | | |||
1015 | MyMoneyMoney refVal(static_cast<double>(val)); | | |||
1016 | m_balloonAmount->loadText(refVal.abs().formatMoney(QString(), m_wizard->precision())); | | |||
1017 | result += QString(" "); | | |||
1018 | result += i18n("The number of payments has been decremented and the balloon payment has been modified to %1.", m_balloonAmount->lineedit()->text()); | | |||
1019 | } else if ((moneyBorrowed && val < 0 && qAbs(val) < qAbs(calc.payment())) | | |||
1020 | || (moneyLend && val > 0 && qAbs(val) < qAbs(calc.payment()))) { | | |||
1021 | m_balloonAmount->loadText(MyMoneyMoney().formatMoney(QString(), m_wizard->precision())); | | |||
1022 | } else { | | |||
1023 | MyMoneyMoney refVal(static_cast<double>(val)); | | |||
1024 | m_balloonAmount->loadText(refVal.abs().formatMoney(QString(), m_wizard->precision())); | | |||
1025 | result += i18n("The balloon payment has been modified to %1.", m_balloonAmount->lineedit()->text()); | | |||
1026 | } | | |||
1027 | | ||||
1028 | } else if (m_termAmount->value() == 0) { | | |||
1029 | // calculate the number of payments out of the other information | | |||
1030 | val = calc.numPayments(); | | |||
1031 | if (val == 0) | | |||
1032 | throw MYMONEYEXCEPTION("incorrect fincancial calculation"); | | |||
1033 | | ||||
1034 | // if the number of payments has a fractional part, then we | | |||
1035 | // round it to the smallest integer and calculate the balloon payment | | |||
1036 | result = i18n("KMyMoney has calculated the term of your loan as %1. ", updateTermWidgets(qFloor(val))); | | |||
1037 | | ||||
1038 | if (val != qFloor(val)) { | | |||
1039 | calc.setNpp(qFloor(val)); | | |||
1040 | val = calc.futureValue(); | | |||
1041 | MyMoneyMoney refVal(static_cast<double>(val)); | | |||
1042 | m_balloonAmount->loadText(refVal.abs().formatMoney(QString(), m_wizard->precision())); | | |||
1043 | result += i18n("The balloon payment has been modified to %1.", m_balloonAmount->lineedit()->text()); | | |||
1044 | } | | |||
1045 | | ||||
1046 | } else { | | |||
1047 | // calculate the future value of the loan out of the other information | | |||
1048 | val = calc.futureValue(); | | |||
1049 | | ||||
1050 | // we differentiate between the following cases: | | |||
1051 | // a) the future value is greater than a payment | | |||
1052 | // b) the future value is less than a payment or the loan is overpaid | | |||
1053 | // c) all other cases | | |||
1054 | // | | |||
1055 | // a) means, we have paid more than we owed. This can't be | | |||
1056 | // b) means, we paid more than we owed but the last payment is | | |||
1057 | // less in value than regular payments. That means, that the | | |||
1058 | // future value is to be treated as (fully payed back) | | |||
1059 | // c) the loan is not payed back yet | | |||
1060 | if ((moneyBorrowed && val < 0 && qAbs(val) > qAbs(calc.payment())) | | |||
1061 | || (moneyLend && val > 0 && qAbs(val) > qAbs(calc.payment()))) { | | |||
1062 | // case a) | | |||
1063 | qDebug("Future Value is %f", val); | | |||
1064 | throw MYMONEYEXCEPTION("incorrect fincancial calculation"); | | |||
1065 | | ||||
1066 | } else if ((moneyBorrowed && val < 0 && qAbs(val) <= qAbs(calc.payment())) | | |||
1067 | || (moneyLend && val > 0 && qAbs(val) <= qAbs(calc.payment()))) { | | |||
1068 | // case b) | | |||
1069 | val = 0; | | |||
1070 | } | | |||
1071 | | ||||
1072 | MyMoneyMoney refVal(static_cast<double>(val)); | | |||
1073 | result = i18n("KMyMoney has calculated a balloon payment of %1 for this loan.", refVal.abs().formatMoney(QString(), m_wizard->precision())); | | |||
1074 | | ||||
1075 | if (!m_balloonAmount->lineedit()->text().isEmpty()) { | | |||
1076 | if ((m_balloonAmount->value().abs() - refVal.abs()).abs().toDouble() > 1) { | | |||
1077 | throw MYMONEYEXCEPTION("incorrect fincancial calculation"); | | |||
1078 | } | | |||
1079 | result = i18n("KMyMoney has successfully verified your loan information."); | | |||
1080 | } | | |||
1081 | m_balloonAmount->loadText(refVal.abs().formatMoney(QString(), m_wizard->precision())); | | |||
1082 | } | | |||
1083 | | ||||
1084 | } catch (const MyMoneyException &) { | | |||
1085 | KMessageBox::error(0, | | |||
1086 | i18n("You have entered mis-matching information. Please modify " | | |||
1087 | "your figures or leave one value empty " | | |||
1088 | "to let KMyMoney calculate it for you"), | | |||
1089 | i18n("Calculation error")); | | |||
1090 | return; | | |||
1091 | } | | |||
1092 | | ||||
1093 | result += i18n("\n\nAccept this or modify the loan information and recalculate."); | | |||
1094 | | ||||
1095 | KMessageBox::information(0, result, i18n("Calculation successful")); | | |||
1096 | m_needCalculate = false; | | |||
1097 | | ||||
1098 | // now update change | | |||
1099 | m_wizard->completeStateChanged(); | | |||
1100 | } | | |||
1101 | | ||||
1102 | int LoanDetailsPage::term() const | | |||
1103 | { | | |||
1104 | int factor = 0; | | |||
1105 | | ||||
1106 | if (m_termAmount->value() != 0) { | | |||
1107 | factor = 1; | | |||
1108 | switch (m_termUnit->currentItem()) { | | |||
1109 | case Schedule::Occurrence::Yearly: // years | | |||
1110 | factor = 12; | | |||
1111 | // intentional fall through | | |||
1112 | | ||||
1113 | case Schedule::Occurrence::Monthly: // months | | |||
1114 | factor *= 30; | | |||
1115 | factor *= m_termAmount->value(); | | |||
1116 | // factor now is the duration in days. we divide this by the | | |||
1117 | // payment frequency and get the number of payments | | |||
1118 | factor /= m_wizard->m_generalLoanInfoPage->m_paymentFrequency->daysBetweenEvents(); | | |||
1119 | break; | | |||
1120 | | ||||
1121 | default: | | |||
1122 | qDebug("Unknown term unit %d in LoanDetailsPage::term(). Using payments.", (int)m_termUnit->currentItem()); | | |||
1123 | // intentional fall through | | |||
1124 | | ||||
1125 | case Schedule::Occurrence::Once: // payments | | |||
1126 | factor = m_termAmount->value(); | | |||
1127 | break; | | |||
1128 | } | | |||
1129 | } | | |||
1130 | return factor; | | |||
1131 | } | | |||
1132 | | ||||
1133 | QString LoanDetailsPage::updateTermWidgets(const double val) | | |||
1134 | { | | |||
1135 | long vl = qFloor(val); | | |||
1136 | | ||||
1137 | QString valString; | | |||
1138 | Schedule::Occurrence unit = m_termUnit->currentItem(); | | |||
1139 | | ||||
1140 | if ((unit == Schedule::Occurrence::Monthly) | | |||
1141 | && ((vl % 12) == 0)) { | | |||
1142 | vl /= 12; | | |||
1143 | unit = Schedule::Occurrence::Yearly; | | |||
1144 | } | | |||
1145 | | ||||
1146 | switch (unit) { | | |||
1147 | case Schedule::Occurrence::Monthly: | | |||
1148 | valString = i18np("one month", "%1 months", vl); | | |||
1149 | m_termUnit->setCurrentItem((int)Schedule::Occurrence::Monthly); | | |||
1150 | break; | | |||
1151 | case Schedule::Occurrence::Yearly: | | |||
1152 | valString = i18np("one year", "%1 years", vl); | | |||
1153 | m_termUnit->setCurrentItem((int)Schedule::Occurrence::Yearly); | | |||
1154 | break; | | |||
1155 | default: | | |||
1156 | valString = i18np("one payment", "%1 payments", vl); | | |||
1157 | m_termUnit->setCurrentItem((int)Schedule::Occurrence::Once); | | |||
1158 | break; | | |||
1159 | } | | |||
1160 | m_termAmount->setValue(vl); | | |||
1161 | return valString; | | |||
1162 | } | | |||
1163 | | ||||
1164 | bool LoanDetailsPage::isComplete() const | | |||
1165 | { | | |||
1166 | // bool rc = KMyMoneyWizardPage::isComplete(); | | |||
1167 | | ||||
1168 | int fieldCnt = 0; | | |||
1169 | | ||||
1170 | if (m_loanAmount->lineedit()->text().length() > 0) { | | |||
1171 | fieldCnt++; | | |||
1172 | } | | |||
1173 | | ||||
1174 | if (m_interestRate->lineedit()->text().length() > 0) { | | |||
1175 | fieldCnt++; | | |||
1176 | } | | |||
1177 | | ||||
1178 | if (m_termAmount->value() != 0) { | | |||
1179 | fieldCnt++; | | |||
1180 | } | | |||
1181 | | ||||
1182 | if (m_paymentAmount->lineedit()->text().length() > 0) { | | |||
1183 | fieldCnt++; | | |||
1184 | } | | |||
1185 | | ||||
1186 | if (m_balloonAmount->lineedit()->text().length() > 0) { | | |||
1187 | fieldCnt++; | | |||
1188 | } | | |||
1189 | | ||||
1190 | m_calculateButton->setEnabled(fieldCnt == 4 || (fieldCnt == 5 && m_needCalculate)); | | |||
1191 | | ||||
1192 | m_calculateButton->setAutoDefault(false); | | |||
1193 | m_calculateButton->setDefault(false); | | |||
1194 | if (m_needCalculate && fieldCnt == 4) { | | |||
1195 | m_wizard->m_nextButton->setToolTip(i18n("Press Calculate to verify the values")); | | |||
1196 | m_calculateButton->setAutoDefault(true); | | |||
1197 | m_calculateButton->setDefault(true); | | |||
1198 | } else if (fieldCnt != 5) { | | |||
1199 | m_wizard->m_nextButton->setToolTip(i18n("Not all details supplied")); | | |||
1200 | m_calculateButton->setAutoDefault(true); | | |||
1201 | m_calculateButton->setDefault(true); | | |||
1202 | } | | |||
1203 | m_wizard->m_nextButton->setAutoDefault(!m_calculateButton->autoDefault()); | | |||
1204 | m_wizard->m_nextButton->setDefault(!m_calculateButton->autoDefault()); | | |||
1205 | | ||||
1206 | return (fieldCnt == 5) && !m_needCalculate; | | |||
1207 | } | | |||
1208 | | ||||
1209 | KMyMoneyWizardPage* LoanDetailsPage::nextPage() const | | |||
1210 | { | | |||
1211 | return m_wizard->m_loanPaymentPage; | | |||
1212 | } | | |||
1213 | | ||||
1214 | | ||||
1215 | class LoanPaymentPage::Private | | |||
1216 | { | | |||
1217 | public: | | |||
1218 | MyMoneyAccount phonyAccount; | | |||
1219 | MyMoneySplit phonySplit; | | |||
1220 | MyMoneyTransaction additionalFeesTransaction; | | |||
1221 | MyMoneyMoney additionalFees; | | |||
1222 | }; | | |||
1223 | | ||||
1224 | LoanPaymentPage::LoanPaymentPage(Wizard* wizard) : | | |||
1225 | KLoanPaymentPageDecl(wizard), | | |||
1226 | WizardPage<Wizard>(StepFees, this, wizard), | | |||
1227 | d(new Private) | | |||
1228 | { | | |||
1229 | d->phonyAccount = MyMoneyAccount(QLatin1String("Phony-ID"), MyMoneyAccount()); | | |||
1230 | | ||||
1231 | d->phonySplit.setAccountId(d->phonyAccount.id()); | | |||
1232 | d->phonySplit.setValue(MyMoneyMoney()); | | |||
1233 | d->phonySplit.setShares(MyMoneyMoney()); | | |||
1234 | | ||||
1235 | d->additionalFeesTransaction.addSplit(d->phonySplit); | | |||
1236 | | ||||
1237 | connect(m_additionalFeesButton, SIGNAL(clicked()), this, SLOT(slotAdditionalFees())); | | |||
1238 | } | | |||
1239 | | ||||
1240 | LoanPaymentPage::~LoanPaymentPage() | | |||
1241 | { | | |||
1242 | delete d; | | |||
1243 | } | | |||
1244 | | ||||
1245 | MyMoneyMoney LoanPaymentPage::basePayment() const | | |||
1246 | { | | |||
1247 | return m_wizard->m_loanDetailsPage->m_paymentAmount->value(); | | |||
1248 | } | | |||
1249 | | ||||
1250 | MyMoneyMoney LoanPaymentPage::additionalFees() const | | |||
1251 | { | | |||
1252 | return d->additionalFees; | | |||
1253 | } | | |||
1254 | | ||||
1255 | void LoanPaymentPage::additionalFeesSplits(QList<MyMoneySplit>& list) | | |||
1256 | { | | |||
1257 | list.clear(); | | |||
1258 | | ||||
1259 | QList<MyMoneySplit>::ConstIterator it; | | |||
1260 | for (it = d->additionalFeesTransaction.splits().constBegin(); it != d->additionalFeesTransaction.splits().constEnd(); ++it) { | | |||
1261 | if ((*it).accountId() != d->phonyAccount.id()) { | | |||
1262 | list << (*it); | | |||
1263 | } | | |||
1264 | } | | |||
1265 | } | | |||
1266 | | ||||
1267 | void LoanPaymentPage::updateAmounts() | | |||
1268 | { | | |||
1269 | m_additionalFees->setText(d->additionalFees.formatMoney(m_wizard->currency().tradingSymbol(), m_wizard->precision())); | | |||
1270 | m_totalPayment->setText((basePayment() + d->additionalFees).formatMoney(m_wizard->currency().tradingSymbol(), m_wizard->precision())); | | |||
1271 | } | | |||
1272 | | ||||
1273 | void LoanPaymentPage::enterPage() | | |||
1274 | { | | |||
1275 | const MyMoneySecurity& currency = m_wizard->currency(); | | |||
1276 | | ||||
1277 | m_basePayment->setText(basePayment().formatMoney(currency.tradingSymbol(), m_wizard->precision())); | | |||
1278 | d->phonyAccount.setCurrencyId(currency.id()); | | |||
1279 | d->additionalFeesTransaction.setCommodity(currency.id()); | | |||
1280 | | ||||
1281 | updateAmounts(); | | |||
1282 | } | | |||
1283 | | ||||
1284 | void LoanPaymentPage::slotAdditionalFees() | | |||
1285 | { | | |||
1286 | QMap<QString, MyMoneyMoney> priceInfo; | | |||
1287 | QPointer<KSplitTransactionDlg> dlg = new KSplitTransactionDlg(d->additionalFeesTransaction, d->phonySplit, d->phonyAccount, false, !m_wizard->moneyBorrowed(), MyMoneyMoney(), priceInfo); | | |||
1288 | | ||||
1289 | // connect(dlg, SIGNAL(newCategory(MyMoneyAccount&)), this, SIGNAL(newCategory(MyMoneyAccount&))); | | |||
1290 | | ||||
1291 | if (dlg->exec() == QDialog::Accepted) { | | |||
1292 | d->additionalFeesTransaction = dlg->transaction(); | | |||
1293 | // sum up the additional fees | | |||
1294 | QList<MyMoneySplit>::ConstIterator it; | | |||
1295 | | ||||
1296 | d->additionalFees = MyMoneyMoney(); | | |||
1297 | for (it = d->additionalFeesTransaction.splits().constBegin(); it != d->additionalFeesTransaction.splits().constEnd(); ++it) { | | |||
1298 | if ((*it).accountId() != d->phonyAccount.id()) { | | |||
1299 | d->additionalFees += (*it).shares(); | | |||
1300 | } | | |||
1301 | } | | |||
1302 | updateAmounts(); | | |||
1303 | } | | |||
1304 | | ||||
1305 | delete dlg; | | |||
1306 | } | | |||
1307 | | ||||
1308 | KMyMoneyWizardPage* LoanPaymentPage::nextPage() const | | |||
1309 | { | | |||
1310 | return m_wizard->m_loanSchedulePage; | | |||
1311 | } | | |||
1312 | | ||||
1313 | | ||||
1314 | LoanSchedulePage::LoanSchedulePage(Wizard* wizard) : | | |||
1315 | KLoanSchedulePageDecl(wizard), | | |||
1316 | WizardPage<Wizard>(StepSchedule, this, wizard) | | |||
1317 | { | | |||
1318 | m_mandatoryGroup->add(m_interestCategory->lineEdit()); | | |||
1319 | m_mandatoryGroup->add(m_paymentAccount->lineEdit()); | | |||
1320 | connect(m_interestCategory, SIGNAL(createItem(QString,QString&)), this, SLOT(slotCreateCategory(QString,QString&))); | | |||
1321 | connect(MyMoneyFile::instance(), SIGNAL(dataChanged()), this, SLOT(slotLoadWidgets())); | | |||
1322 | } | | |||
1323 | | ||||
1324 | void LoanSchedulePage::slotCreateCategory(const QString& name, QString& id) | | |||
1325 | { | | |||
1326 | MyMoneyAccount acc, parent; | | |||
1327 | acc.setName(name); | | |||
1328 | | ||||
1329 | if (m_wizard->moneyBorrowed()) | | |||
1330 | parent = MyMoneyFile::instance()->expense(); | | |||
1331 | else | | |||
1332 | parent = MyMoneyFile::instance()->income(); | | |||
1333 | | ||||
1334 | emit m_wizard->createCategory(acc, parent); | | |||
1335 | | ||||
1336 | // return id | | |||
1337 | id = acc.id(); | | |||
1338 | } | | |||
1339 | | ||||
1340 | QDate LoanSchedulePage::firstPaymentDueDate() const | | |||
1341 | { | | |||
1342 | if (m_firstPaymentDueDate->isEnabled()) | | |||
1343 | return m_firstPaymentDueDate->date(); | | |||
1344 | return m_wizard->m_generalLoanInfoPage->m_firstPaymentDate->date(); | | |||
1345 | } | | |||
1346 | | ||||
1347 | void LoanSchedulePage::enterPage() | | |||
1348 | { | | |||
1349 | m_interestCategory->setFocus(); | | |||
1350 | m_firstPaymentDueDate->setDisabled(m_wizard->m_generalLoanInfoPage->recordAllPayments()); | | |||
1351 | slotLoadWidgets(); | | |||
1352 | } | | |||
1353 | | ||||
1354 | void LoanSchedulePage::slotLoadWidgets() | | |||
1355 | { | | |||
1356 | AccountSet set; | | |||
1357 | if (m_wizard->moneyBorrowed()) | | |||
1358 | set.addAccountGroup(Account::Expense); | | |||
1359 | else | | |||
1360 | set.addAccountGroup(Account::Income); | | |||
1361 | set.load(m_interestCategory->selector()); | | |||
1362 | | ||||
1363 | set.clear(); | | |||
1364 | set.addAccountGroup(Account::Asset); | | |||
1365 | set.load(m_paymentAccount->selector()); | | |||
1366 | } | | |||
1367 | | ||||
1368 | KMyMoneyWizardPage* LoanSchedulePage::nextPage() const | | |||
1369 | { | | |||
1370 | // if the balance widget of the general loan info page is enabled and | | |||
1371 | // the value is not zero, then the payout already happened and we don't | | |||
1372 | // aks for it. | | |||
1373 | if (m_wizard->openingBalance().isZero()) | | |||
1374 | return m_wizard->m_loanPayoutPage; | | |||
1375 | return m_wizard->m_accountSummaryPage; | | |||
1376 | } | | |||
1377 | | ||||
1378 | LoanPayoutPage::LoanPayoutPage(Wizard* wizard) : | | |||
1379 | KLoanPayoutPageDecl(wizard), | | |||
1380 | WizardPage<Wizard>(StepPayout, this, wizard) | | |||
1381 | { | | |||
1382 | m_mandatoryGroup->add(m_assetAccount->lineEdit()); | | |||
1383 | m_mandatoryGroup->add(m_loanAccount->lineEdit()); | | |||
1384 | | ||||
1385 | KGuiItem createAssetButtenItem(i18n("&Create..."), | | |||
1386 | QIcon::fromTheme(g_Icons[Icon::DocumentNew]), | | |||
1387 | i18n("Create a new asset account"), | | |||
1388 | i18n("If the asset account does not yet exist, press this button to create it.")); | | |||
1389 | KGuiItem::assign(m_createAssetButton, createAssetButtenItem); | | |||
1390 | m_createAssetButton->setToolTip(createAssetButtenItem.toolTip()); | | |||
1391 | m_createAssetButton->setWhatsThis(createAssetButtenItem.whatsThis()); | | |||
1392 | connect(m_createAssetButton, SIGNAL(clicked()), this, SLOT(slotCreateAssetAccount())); | | |||
1393 | | ||||
1394 | connect(m_noPayoutTransaction, SIGNAL(toggled(bool)), this, SLOT(slotButtonsToggled())); | | |||
1395 | connect(m_refinanceLoan, SIGNAL(toggled(bool)), this, SLOT(slotButtonsToggled())); | | |||
1396 | | ||||
1397 | connect(MyMoneyFile::instance(), SIGNAL(dataChanged()), this, SLOT(slotLoadWidgets())); | | |||
1398 | slotLoadWidgets(); | | |||
1399 | } | | |||
1400 | | ||||
1401 | void LoanPayoutPage::slotButtonsToggled() | | |||
1402 | { | | |||
1403 | // we don't go directly, as the order of the emission of signals to slots is | | |||
1404 | // not defined. Using a single shot timer postpones the call of m_mandatoryGroup::changed() | | |||
1405 | // until the next round of the main loop so we can be sure to see all relevant changes | | |||
1406 | // that happened in the meantime (eg. widgets are enabled and disabled) | | |||
1407 | QTimer::singleShot(0, m_mandatoryGroup, SLOT(changed())); | | |||
1408 | } | | |||
1409 | | ||||
1410 | void LoanPayoutPage::slotCreateAssetAccount() | | |||
1411 | { | | |||
1412 | MyMoneyAccount acc; | | |||
1413 | acc.setAccountType(Account::Asset); | | |||
1414 | acc.setOpeningDate(m_wizard->m_accountTypePage->m_openingDate->date()); | | |||
1415 | | ||||
1416 | emit m_wizard->createAccount(acc); | | |||
1417 | | ||||
1418 | if (!acc.id().isEmpty()) { | | |||
1419 | m_assetAccount->setSelectedItem(acc.id()); | | |||
1420 | } | | |||
1421 | } | | |||
1422 | | ||||
1423 | void LoanPayoutPage::slotLoadWidgets() | | |||
1424 | { | | |||
1425 | AccountSet set; | | |||
1426 | set.addAccountGroup(Account::Asset); | | |||
1427 | set.load(m_assetAccount->selector()); | | |||
1428 | | ||||
1429 | set.clear(); | | |||
1430 | set.addAccountType(Account::Loan); | | |||
1431 | set.load(m_loanAccount->selector()); | | |||
1432 | } | | |||
1433 | | ||||
1434 | void LoanPayoutPage::enterPage() | | |||
1435 | { | | |||
1436 | // only allow to create new asset accounts for liability loans | | |||
1437 | m_createAssetButton->setEnabled(m_wizard->moneyBorrowed()); | | |||
1438 | m_refinanceLoan->setEnabled(m_wizard->moneyBorrowed()); | | |||
1439 | if (!m_wizard->moneyBorrowed()) { | | |||
1440 | m_refinanceLoan->setChecked(false); | | |||
1441 | } | | |||
1442 | m_payoutDetailFrame->setDisabled(m_noPayoutTransaction->isChecked()); | | |||
1443 | } | | |||
1444 | | ||||
1445 | KMyMoneyWizardPage* LoanPayoutPage::nextPage() const | | |||
1446 | { | | |||
1447 | return m_wizard->m_accountSummaryPage; | | |||
1448 | } | | |||
1449 | | ||||
1450 | bool LoanPayoutPage::isComplete() const | | |||
1451 | { | | |||
1452 | return KMyMoneyWizardPage::isComplete() | m_noPayoutTransaction->isChecked(); | | |||
1453 | } | | |||
1454 | | ||||
1455 | QString LoanPayoutPage::payoutAccountId() const | | |||
1456 | { | | |||
1457 | if (m_refinanceLoan->isChecked()) { | | |||
1458 | return m_loanAccount->selectedItem(); | | |||
1459 | } else { | | |||
1460 | return m_assetAccount->selectedItem(); | | |||
1461 | } | | |||
1462 | } | | |||
1463 | | ||||
1464 | HierarchyFilterProxyModel::HierarchyFilterProxyModel(QObject *parent) | | |||
1465 | : AccountsProxyModel(parent) | | |||
1466 | { | | |||
1467 | } | | |||
1468 | | ||||
1469 | /** | | |||
1470 | * Filter the favorites accounts group. | | |||
1471 | */ | | |||
1472 | bool HierarchyFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const | | |||
1473 | { | | |||
1474 | if (!source_parent.isValid()) { | | |||
1475 | auto accCol = m_mdlColumns->indexOf(eAccountsModel::Column::Account); | | |||
1476 | QVariant data = sourceModel()->index(source_row, accCol, source_parent).data((int)eAccountsModel::Role::ID); | | |||
1477 | if (data.isValid() && data.toString() == AccountsModel::favoritesAccountId) | | |||
1478 | return false; | | |||
1479 | } | | |||
1480 | return AccountsProxyModel::filterAcceptsRow(source_row, source_parent); | | |||
1481 | } | | |||
1482 | | ||||
1483 | /** | | |||
1484 | * Filter all but the first column. | | |||
1485 | */ | | |||
1486 | bool HierarchyFilterProxyModel::filterAcceptsColumn(int source_column, const QModelIndex &source_parent) const | | |||
1487 | { | | |||
1488 | Q_UNUSED(source_parent) | | |||
1489 | if (source_column == 0) | | |||
1490 | return true; | | |||
1491 | return false; | | |||
1492 | } | | |||
1493 | | ||||
1494 | HierarchyPage::HierarchyPage(Wizard* wizard) : | | |||
1495 | KHierarchyPageDecl(wizard), | | |||
1496 | WizardPage<Wizard>(StepParentAccount, this, wizard), | | |||
1497 | m_filterProxyModel(nullptr) | | |||
1498 | { | | |||
1499 | // the proxy filter model | | |||
1500 | m_filterProxyModel = new HierarchyFilterProxyModel(this); | | |||
1501 | m_filterProxyModel->setHideClosedAccounts(true); | | |||
1502 | m_filterProxyModel->setHideEquityAccounts(!KMyMoneyGlobalSettings::expertMode()); | | |||
1503 | m_filterProxyModel->addAccountGroup(QVector<Account> {Account::Asset, Account::Liability}); | | |||
1504 | auto const model = Models::instance()->accountsModel(); | | |||
1505 | m_filterProxyModel->setSourceModel(model); | | |||
1506 | m_filterProxyModel->setSourceColumns(model->getColumns()); | | |||
1507 | m_filterProxyModel->setDynamicSortFilter(true); | | |||
1508 | | ||||
1509 | m_parentAccounts->setModel(m_filterProxyModel); | | |||
1510 | m_parentAccounts->sortByColumn((int)eAccountsModel::Column::Account, Qt::AscendingOrder); | | |||
1511 | | ||||
1512 | connect(m_parentAccounts->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), this, SLOT(parentAccountChanged())); | | |||
1513 | } | | |||
1514 | | ||||
1515 | void HierarchyPage::enterPage() | | |||
1516 | { | | |||
1517 | // Ensure that the list reflects the Account Type | | |||
1518 | MyMoneyAccount topAccount = m_wizard->m_accountTypePage->parentAccount(); | | |||
1519 | m_filterProxyModel->clear(); | | |||
1520 | m_filterProxyModel->addAccountGroup(QVector<Account> {topAccount.accountGroup()}); | | |||
1521 | m_parentAccounts->expandAll(); | | |||
1522 | } | | |||
1523 | | ||||
1524 | KMyMoneyWizardPage* HierarchyPage::nextPage() const | | |||
1525 | { | | |||
1526 | return m_wizard->m_accountSummaryPage; | | |||
1527 | } | | |||
1528 | | ||||
1529 | const MyMoneyAccount& HierarchyPage::parentAccount() | | |||
1530 | { | | |||
1531 | QVariant data = m_parentAccounts->model()->data(m_parentAccounts->currentIndex(), (int)eAccountsModel::Role::Account); | | |||
1532 | if (data.isValid()) { | | |||
1533 | m_parentAccount = data.value<MyMoneyAccount>(); | | |||
1534 | } else { | | |||
1535 | m_parentAccount = MyMoneyAccount(); | | |||
1536 | } | | |||
1537 | return m_parentAccount; | | |||
1538 | } | | |||
1539 | | ||||
1540 | bool HierarchyPage::isComplete() const | | |||
1541 | { | | |||
1542 | return m_parentAccounts->currentIndex().isValid(); | | |||
1543 | } | | |||
1544 | | ||||
1545 | void HierarchyPage::parentAccountChanged() | | |||
1546 | { | | |||
1547 | completeStateChanged(); | | |||
1548 | } | | |||
1549 | | ||||
1550 | AccountSummaryPage::AccountSummaryPage(Wizard* wizard) : | | |||
1551 | KAccountSummaryPageDecl(wizard), | | |||
1552 | WizardPage<Wizard>(StepFinish, this, wizard) | | |||
1553 | { | | |||
1554 | } | | |||
1555 | | ||||
1556 | void AccountSummaryPage::enterPage() | | |||
1557 | { | | |||
1558 | MyMoneyAccount acc = m_wizard->account(); | | |||
1559 | MyMoneySecurity sec = m_wizard->currency(); | | |||
1560 | acc.fraction(sec); | | |||
1561 | | ||||
1562 | // assign an id to the account inside the wizard which is required for a schedule | | |||
1563 | // get the schedule and clear the id again in the wizards object. | | |||
1564 | MyMoneyAccount tmp(QLatin1String("Phony-ID"), acc); | | |||
1565 | m_wizard->setAccount(tmp); | | |||
1566 | MyMoneySchedule sch = m_wizard->schedule(); | | |||
1567 | m_wizard->setAccount(acc); | | |||
1568 | | ||||
1569 | m_dataList->clear(); | | |||
1570 | | ||||
1571 | | ||||
1572 | | ||||
1573 | // Account data | | |||
1574 | m_dataList->setFontWeight(QFont::Bold); | | |||
1575 | m_dataList->append(i18n("Account information")); | | |||
1576 | m_dataList->setFontWeight(QFont::Normal); | | |||
1577 | m_dataList->append(i18nc("Account name", "Name: %1", acc.name())); | | |||
1578 | if (!acc.isLoan()) | | |||
1579 | m_dataList->append(i18n("Subaccount of %1", m_wizard->parentAccount().name())); | | |||
1580 | QString accTypeText; | | |||
1581 | if (acc.accountType() == Account::AssetLoan) | | |||
1582 | accTypeText = i18n("Loan"); | | |||
1583 | else | | |||
1584 | accTypeText = m_wizard->m_accountTypePage->m_typeSelection->currentText(); | | |||
1585 | m_dataList->append(i18n("Type: %1", accTypeText)); | | |||
1586 | | ||||
1587 | m_dataList->append(i18n("Currency: %1", m_wizard->currency().name())); | | |||
1588 | m_dataList->append(i18n("Opening date: %1", QLocale().toString(acc.openingDate()))); | | |||
1589 | if (m_wizard->currency().id() != MyMoneyFile::instance()->baseCurrency().id()) { | | |||
1590 | m_dataList->append(i18n("Conversion rate: %1", m_wizard->conversionRate().rate(QString()).formatMoney(QString(), m_wizard->currency().pricePrecision()))); | | |||
1591 | } | | |||
1592 | if (!acc.isLoan() || !m_wizard->openingBalance().isZero()) | | |||
1593 | m_dataList->append(i18n("Opening balance: %1", MyMoneyUtils::formatMoney(m_wizard->openingBalance(), acc, sec))); | | |||
1594 | | ||||
1595 | if (!m_wizard->m_institutionPage->institution().id().isEmpty()) { | | |||
1596 | m_dataList->append(i18n("Institution: %1", m_wizard->m_institutionPage->institution().name())); | | |||
1597 | if (!acc.number().isEmpty()) { | | |||
1598 | m_dataList->append(i18n("Number: %1", acc.number())); | | |||
1599 | } | | |||
1600 | if (!acc.value("iban").isEmpty()) { | | |||
1601 | m_dataList->append(i18n("IBAN: %1", acc.value("iban"))); | | |||
1602 | } | | |||
1603 | } | | |||
1604 | | ||||
1605 | if (acc.accountType() == Account::Investment) { | | |||
1606 | if (m_wizard->m_brokeragepage->m_createBrokerageButton->isChecked()) { | | |||
1607 | m_dataList->setFontWeight(QFont::Bold); | | |||
1608 | m_dataList->append(i18n("Brokerage Account")); | | |||
1609 | m_dataList->setFontWeight(QFont::Normal); | | |||
1610 | | ||||
1611 | m_dataList->append(i18nc("Account name", "Name: %1 (Brokerage)", acc.name())); | | |||
1612 | m_dataList->append(i18n("Currency: %1", m_wizard->m_brokeragepage->m_brokerageCurrency->security().name())); | | |||
1613 | if (m_wizard->m_brokeragepage->m_accountNumber->isEnabled() && !m_wizard->m_brokeragepage->m_accountNumber->text().isEmpty()) | | |||
1614 | m_dataList->append(i18n("Number: %1", m_wizard->m_brokeragepage->m_accountNumber->text())); | | |||
1615 | if (m_wizard->m_brokeragepage->m_iban->isEnabled() && !m_wizard->m_brokeragepage->m_iban->text().isEmpty()) | | |||
1616 | m_dataList->append(i18n("IBAN: %1", m_wizard->m_brokeragepage->m_iban->text())); | | |||
1617 | } | | |||
1618 | } | | |||
1619 | | ||||
1620 | // Loan | | |||
1621 | if (acc.isLoan()) { | | |||
1622 | m_dataList->setFontWeight(QFont::Bold); | | |||
1623 | m_dataList->append(i18n("Loan information")); | | |||
1624 | m_dataList->setFontWeight(QFont::Normal); | | |||
1625 | if (m_wizard->moneyBorrowed()) { | | |||
1626 | m_dataList->append(i18n("Amount borrowed: %1", m_wizard->m_loanDetailsPage->m_loanAmount->value().formatMoney(m_wizard->currency().tradingSymbol(), m_wizard->precision()))); | | |||
1627 | } else { | | |||
1628 | m_dataList->append(i18n("Amount lent: %1", m_wizard->m_loanDetailsPage->m_loanAmount->value().formatMoney(m_wizard->currency().tradingSymbol(), m_wizard->precision()))); | | |||
1629 | } | | |||
1630 | m_dataList->append(i18n("Interest rate: %1 %", m_wizard->m_loanDetailsPage->m_interestRate->value().formatMoney(QString(), -1))); | | |||
1631 | m_dataList->append(i18n("Interest rate is %1", m_wizard->m_generalLoanInfoPage->m_interestType->currentText())); | | |||
1632 | m_dataList->append(i18n("Principal and interest: %1", MyMoneyUtils::formatMoney(m_wizard->m_loanDetailsPage->m_paymentAmount->value(), acc, sec))); | | |||
1633 | m_dataList->append(i18n("Additional Fees: %1", MyMoneyUtils::formatMoney(m_wizard->m_loanPaymentPage->additionalFees(), acc, sec))); | | |||
1634 | m_dataList->append(i18n("Payment frequency: %1", m_wizard->m_generalLoanInfoPage->m_paymentFrequency->currentText())); | | |||
1635 | m_dataList->append(i18n("Payment account: %1", m_wizard->m_loanSchedulePage->m_paymentAccount->currentText())); | | |||
1636 | | ||||
1637 | if (!m_wizard->m_loanPayoutPage->m_noPayoutTransaction->isChecked() && m_wizard->openingBalance().isZero()) { | | |||
1638 | m_dataList->setFontWeight(QFont::Bold); | | |||
1639 | m_dataList->append(i18n("Payout information")); | | |||
1640 | m_dataList->setFontWeight(QFont::Normal); | | |||
1641 | if (m_wizard->m_loanPayoutPage->m_refinanceLoan->isChecked()) { | | |||
1642 | m_dataList->append(i18n("Refinance: %1", m_wizard->m_loanPayoutPage->m_loanAccount->currentText())); | | |||
1643 | } else { | | |||
1644 | if (m_wizard->moneyBorrowed()) | | |||
1645 | m_dataList->append(i18n("Transfer amount to %1", m_wizard->m_loanPayoutPage->m_assetAccount->currentText())); | | |||
1646 | else | | |||
1647 | m_dataList->append(i18n("Transfer amount from %1", m_wizard->m_loanPayoutPage->m_assetAccount->currentText())); | | |||
1648 | } | | |||
1649 | m_dataList->append(i18n("Payment date: %1 ", QLocale().toString(m_wizard->m_loanPayoutPage->m_payoutDate->date()))); | | |||
1650 | } | | |||
1651 | } | | |||
1652 | | ||||
1653 | // Schedule | | |||
1654 | if (!(sch == MyMoneySchedule())) { | | |||
1655 | m_dataList->setFontWeight(QFont::Bold); | | |||
1656 | m_dataList->append(i18n("Schedule information")); | | |||
1657 | m_dataList->setFontWeight(QFont::Normal); | | |||
1658 | m_dataList->append(i18nc("Schedule name", "Name: %1", sch.name())); | | |||
1659 | if (acc.accountType() == Account::CreditCard) { | | |||
1660 | MyMoneyAccount paymentAccount = MyMoneyFile::instance()->account(m_wizard->m_schedulePage->m_paymentAccount->selectedItem()); | | |||
1661 | m_dataList->append(i18n("Occurrence: Monthly")); | | |||
1662 | m_dataList->append(i18n("Paid from %1", paymentAccount.name())); | | |||
1663 | m_dataList->append(i18n("Pay to %1", m_wizard->m_schedulePage->m_payee->currentText())); | | |||
1664 | m_dataList->append(i18n("Amount: %1", MyMoneyUtils::formatMoney(m_wizard->m_schedulePage->m_amount->value(), acc, sec))); | | |||
1665 | m_dataList->append(i18n("First payment due on %1", QLocale().toString(sch.nextDueDate()))); | | |||
1666 | m_dataList->append(i18n("Payment method: %1", m_wizard->m_schedulePage->m_method->currentText())); | | |||
1667 | } | | |||
1668 | if (acc.isLoan()) { | | |||
1669 | m_dataList->append(i18n("Occurrence: %1", m_wizard->m_generalLoanInfoPage->m_paymentFrequency->currentText())); | | |||
1670 | m_dataList->append(i18n("Amount: %1", MyMoneyUtils::formatMoney(m_wizard->m_loanPaymentPage->basePayment() + m_wizard->m_loanPaymentPage->additionalFees(), acc, sec))); | | |||
1671 | m_dataList->append(i18n("First payment due on %1", QLocale().toString(m_wizard->m_loanSchedulePage->firstPaymentDueDate()))); | | |||
1672 | } | | |||
1673 | } | | |||
1674 | } | | |||
1675 | } | 379 | } | ||
Context not available. |