File indexing completed on 2024-05-12 05:06:35

0001 /*
0002     SPDX-FileCopyrightText: 2001-2002 Michael Edwardes <mte@users.sourceforge.net>
0003     SPDX-FileCopyrightText: 2001 Felix Rodriguez <frodriguez@users.sourceforge.net>
0004     SPDX-FileCopyrightText: 2002-2003 Kevin Tambascio <ktambascio@users.sourceforge.net>
0005     SPDX-FileCopyrightText: 2006-2019 Thomas Baumgart <tbaumgart@kde.org>
0006     SPDX-FileCopyrightText: 2006 Ace Jones <acejones@users.sourceforge.net>
0007     SPDX-FileCopyrightText: 2017-2018 Łukasz Wojniłowicz <lukasz.wojnilowicz@gmail.com>
0008     SPDX-License-Identifier: GPL-2.0-or-later
0009 */
0010 
0011 #include "mymoneyaccountloan.h"
0012 #include "mymoneyaccount_p.h"
0013 
0014 // ----------------------------------------------------------------------------
0015 // QT Includes
0016 
0017 #include <QDate>
0018 #include <QMap>
0019 #include <QRegularExpression>
0020 #include <QSet>
0021 
0022 // ----------------------------------------------------------------------------
0023 // KDE Includes
0024 
0025 // ----------------------------------------------------------------------------
0026 // Project Includes
0027 
0028 #include "mymoneymoney.h"
0029 
0030 class MyMoneyAccountLoanPrivate : public MyMoneyAccountPrivate
0031 {
0032 public:
0033     MyMoneyAccountLoanPrivate(MyMoneyAccountLoan* qq)
0034         : MyMoneyAccountPrivate()
0035         , q(qq)
0036     {
0037     }
0038 
0039     void collectReferencedObjects() override
0040     {
0041         MyMoneyAccountPrivate::collectReferencedObjects();
0042         m_referencedObjects.insert(q->payee());
0043         m_referencedObjects.insert(q->schedule());
0044     }
0045     MyMoneyAccountLoan* q;
0046 };
0047 
0048 MyMoneyAccountLoan::MyMoneyAccountLoan(const MyMoneyAccount& acc)
0049     : MyMoneyAccount(new MyMoneyAccountLoanPrivate(this), acc)
0050 {
0051     Q_D(MyMoneyAccountLoan);
0052     *(static_cast<MyMoneyAccountPrivate*>(d)) = *acc.d_func();
0053 }
0054 
0055 const MyMoneyMoney MyMoneyAccountLoan::loanAmount() const
0056 {
0057     return MyMoneyMoney(value("loan-amount"));
0058 }
0059 
0060 void MyMoneyAccountLoan::setLoanAmount(const MyMoneyMoney& amount)
0061 {
0062     setValue("loan-amount", amount.toString());
0063 }
0064 
0065 const MyMoneyMoney MyMoneyAccountLoan::interestRate(const QDate& date) const
0066 {
0067     MyMoneyMoney rate;
0068 
0069     if (!date.isValid())
0070         return rate;
0071 
0072     const auto key = QStringLiteral("ir-%1").arg(date.toString(Qt::ISODate));
0073     static const QRegularExpression interestRateExp("ir-(\\d{4})-(\\d{2})-(\\d{2})");
0074 
0075     QMap<QString, QString>::ConstIterator it;
0076     const auto map = pairs();
0077     QString val;
0078     for (it = map.constBegin(); it != map.constEnd(); ++it) {
0079         const auto interestRateDate(interestRateExp.match(it.key()));
0080         if (interestRateDate.hasMatch()) {
0081             if (qstrcmp(it.key().toLatin1(), key.toLatin1()) <= 0)
0082                 val = *it;
0083             else
0084                 break;
0085 
0086         } else if (!val.isEmpty())
0087             break;
0088     }
0089     if (!val.isEmpty()) {
0090         rate = MyMoneyMoney(val);
0091     }
0092 
0093     return rate;
0094 }
0095 
0096 void MyMoneyAccountLoan::setInterestRate(const QDate& date, const MyMoneyMoney& value)
0097 {
0098     if (!date.isValid())
0099         return;
0100 
0101     const auto key = QStringLiteral("ir-%1").arg(date.toString(Qt::ISODate));
0102     setValue(key, value.toString());
0103 }
0104 
0105 MyMoneyAccountLoan::interestDueE MyMoneyAccountLoan::interestCalculation() const
0106 {
0107     QString payTime(value("interest-calculation"));
0108     if (payTime == "paymentDue")
0109         return paymentDue;
0110     return paymentReceived;
0111 }
0112 
0113 void MyMoneyAccountLoan::setInterestCalculation(const MyMoneyAccountLoan::interestDueE onReception)
0114 {
0115     if (onReception == paymentDue)
0116         setValue("interest-calculation", "paymentDue");
0117     else
0118         setValue("interest-calculation", "paymentReceived");
0119 }
0120 
0121 const QDate MyMoneyAccountLoan::nextInterestChange() const
0122 {
0123     QDate rc;
0124 
0125     static const QRegularExpression nextChangeExp("(\\d{4})-(\\d{2})-(\\d{2})");
0126     const auto nextChange(nextChangeExp.match(value("interest-nextchange")));
0127     if (nextChange.hasMatch()) {
0128         rc.setDate(nextChange.captured(1).toInt(), nextChange.captured(2).toInt(), nextChange.captured(3).toInt());
0129     }
0130     return rc;
0131 }
0132 
0133 void MyMoneyAccountLoan::setNextInterestChange(const QDate& date)
0134 {
0135     setValue("interest-nextchange", date.toString(Qt::ISODate));
0136 }
0137 
0138 int MyMoneyAccountLoan::interestChangeFrequency(int* unit) const
0139 {
0140     int rc = -1;
0141 
0142     if (unit)
0143         *unit = 1;
0144 
0145     static const QRegularExpression frequencyExp("(\\d+)/(\\d{1})");
0146     const auto frequency(frequencyExp.match(value("interest-changefrequency")));
0147     if (frequency.hasMatch()) {
0148         rc = frequency.captured(1).toInt();
0149         if (unit != 0) {
0150             *unit = frequency.captured(2).toInt();
0151         }
0152     }
0153     return rc;
0154 }
0155 
0156 void MyMoneyAccountLoan::setInterestChangeFrequency(const int amount, const int unit)
0157 {
0158     const auto val = QStringLiteral("%1/%2").arg(amount).arg(unit);
0159     setValue("interest-changeFrequency", val);
0160 }
0161 
0162 const QString MyMoneyAccountLoan::schedule() const
0163 {
0164     return QString(value("schedule").toLatin1());
0165 }
0166 
0167 void MyMoneyAccountLoan::setSchedule(const QString& sched)
0168 {
0169     setValue("schedule", sched);
0170 }
0171 
0172 bool MyMoneyAccountLoan::fixedInterestRate() const
0173 {
0174     // make sure, that an empty kvp element returns true
0175     return !(value("fixed-interest") == "no");
0176 }
0177 
0178 void MyMoneyAccountLoan::setFixedInterestRate(const bool fixed)
0179 {
0180     setValue("fixed-interest", fixed ? "yes" : "no");
0181     if (fixed) {
0182         deletePair("interest-nextchange");
0183         deletePair("interest-changeFrequency");
0184     }
0185 }
0186 
0187 const MyMoneyMoney MyMoneyAccountLoan::finalPayment() const
0188 {
0189     return MyMoneyMoney(value("final-payment"));
0190 }
0191 
0192 void MyMoneyAccountLoan::setFinalPayment(const MyMoneyMoney& finalPayment)
0193 {
0194     setValue("final-payment", finalPayment.toString());
0195 }
0196 
0197 unsigned int MyMoneyAccountLoan::term() const
0198 {
0199     return value("term").toUInt();
0200 }
0201 
0202 void MyMoneyAccountLoan::setTerm(const unsigned int payments)
0203 {
0204     setValue("term", QString::number(payments));
0205 }
0206 
0207 const MyMoneyMoney MyMoneyAccountLoan::periodicPayment() const
0208 {
0209     return MyMoneyMoney(value("periodic-payment"));
0210 }
0211 
0212 void MyMoneyAccountLoan::setPeriodicPayment(const MyMoneyMoney& payment)
0213 {
0214     setValue("periodic-payment", payment.toString());
0215 }
0216 
0217 const QString MyMoneyAccountLoan::payee() const
0218 {
0219     return value("payee");
0220 }
0221 
0222 void MyMoneyAccountLoan::setPayee(const QString& payee)
0223 {
0224     setValue("payee", payee);
0225 }
0226 
0227 const QString MyMoneyAccountLoan::interestAccountId() const
0228 {
0229     return QString();
0230 }
0231 
0232 void MyMoneyAccountLoan::setInterestAccountId(const QString& /* id */)
0233 {
0234 
0235 }
0236 
0237 void MyMoneyAccountLoan::setInterestCompounding(int frequency)
0238 {
0239     setValue("compoundingFrequency", QString("%1").arg(frequency));
0240 }
0241 
0242 int MyMoneyAccountLoan::interestCompounding() const
0243 {
0244     return value("compoundingFrequency").toInt();
0245 }