File indexing completed on 2024-05-12 16:42:41
0001 /* 0002 SPDX-FileCopyrightText: 2002-2017 Thomas Baumgart <tbaumgart@kde.org> 0003 SPDX-FileCopyrightText: 2004 Kevin Tambascio <ktambascio@users.sourceforge.net> 0004 SPDX-FileCopyrightText: 2005-2006 Ace Jones <acejones@users.sourceforge.net> 0005 SPDX-FileCopyrightText: 2017-2018 Łukasz Wojniłowicz <lukasz.wojnilowicz@gmail.com> 0006 SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 0009 #include "mymoneysplit.h" 0010 #include "mymoneysplit_p.h" 0011 0012 // ---------------------------------------------------------------------------- 0013 // QT Includes 0014 0015 // ---------------------------------------------------------------------------- 0016 // KDE Includes 0017 0018 // ---------------------------------------------------------------------------- 0019 // Project Includes 0020 0021 #include "mymoneyutils.h" 0022 #include "mymoneytransaction.h" 0023 #include "mymoneyexception.h" 0024 0025 MyMoneySplit::MyMoneySplit() : 0026 MyMoneyObject(*new MyMoneySplitPrivate) 0027 { 0028 } 0029 0030 MyMoneySplit::MyMoneySplit(const QString &id) : 0031 MyMoneyObject(*new MyMoneySplitPrivate, id) 0032 { 0033 Q_D(MyMoneySplit); 0034 d->m_reconcileFlag = eMyMoney::Split::State::NotReconciled; 0035 } 0036 0037 MyMoneySplit::MyMoneySplit(const MyMoneySplit& other) : 0038 MyMoneyObject(*new MyMoneySplitPrivate(*other.d_func()), other.id()), 0039 MyMoneyKeyValueContainer(other) 0040 { 0041 } 0042 0043 MyMoneySplit::MyMoneySplit(const QString& id, const MyMoneySplit& other) : 0044 MyMoneyObject(*new MyMoneySplitPrivate(*other.d_func()), id), 0045 MyMoneyKeyValueContainer(other) 0046 { 0047 } 0048 0049 MyMoneySplit::~MyMoneySplit() 0050 { 0051 } 0052 0053 bool MyMoneySplit::operator == (const MyMoneySplit& right) const 0054 { 0055 Q_D(const MyMoneySplit); 0056 auto d2 = static_cast<const MyMoneySplitPrivate *>(right.d_func()); 0057 // clang-format off 0058 return MyMoneyObject::operator==(right) 0059 && MyMoneyKeyValueContainer::operator==(right) 0060 && d->m_account == d2->m_account 0061 && d->m_costCenter == d2->m_costCenter 0062 && d->m_payee == d2->m_payee 0063 && d->m_tagList == d2->m_tagList 0064 && d->m_memo == d2->m_memo 0065 && d->m_action == d2->m_action 0066 && d->m_reconcileDate == d2->m_reconcileDate 0067 && d->m_reconcileFlag == d2->m_reconcileFlag 0068 && ((d->m_number.length() == 0 && d2->m_number.length() == 0) || d->m_number == d2->m_number) 0069 && d->m_shares == d2->m_shares 0070 && d->m_value == d2->m_value 0071 && d->m_price == d2->m_price 0072 && d->m_transactionId == d2->m_transactionId; 0073 // clang-format on 0074 } 0075 0076 MyMoneySplit MyMoneySplit::operator-() const 0077 { 0078 MyMoneySplit rc(*this); 0079 rc.d_func()->m_shares = -rc.d_func()->m_shares; 0080 rc.d_func()->m_value = -rc.d_func()->m_value; 0081 return rc; 0082 } 0083 0084 QString MyMoneySplit::accountId() const 0085 { 0086 Q_D(const MyMoneySplit); 0087 return d->m_account; 0088 } 0089 0090 void MyMoneySplit::setAccountId(const QString& account) 0091 { 0092 Q_D(MyMoneySplit); 0093 d->m_account = account; 0094 } 0095 0096 QString MyMoneySplit::costCenterId() const 0097 { 0098 Q_D(const MyMoneySplit); 0099 return d->m_costCenter; 0100 } 0101 0102 void MyMoneySplit::setCostCenterId(const QString& costCenter) 0103 { 0104 Q_D(MyMoneySplit); 0105 d->m_costCenter = costCenter; 0106 } 0107 0108 QString MyMoneySplit::memo() const 0109 { 0110 Q_D(const MyMoneySplit); 0111 return d->m_memo; 0112 } 0113 0114 void MyMoneySplit::setMemo(const QString& memo) 0115 { 0116 Q_D(MyMoneySplit); 0117 d->m_memo = memo; 0118 } 0119 0120 eMyMoney::Split::State MyMoneySplit::reconcileFlag() const 0121 { 0122 Q_D(const MyMoneySplit); 0123 return d->m_reconcileFlag; 0124 } 0125 0126 QDate MyMoneySplit::reconcileDate() const 0127 { 0128 Q_D(const MyMoneySplit); 0129 return d->m_reconcileDate; 0130 } 0131 0132 void MyMoneySplit::setReconcileDate(const QDate& date) 0133 { 0134 Q_D(MyMoneySplit); 0135 d->m_reconcileDate = date; 0136 } 0137 0138 void MyMoneySplit::setReconcileFlag(const eMyMoney::Split::State flag) 0139 { 0140 Q_D(MyMoneySplit); 0141 d->m_reconcileFlag = flag; 0142 } 0143 0144 MyMoneyMoney MyMoneySplit::shares() const 0145 { 0146 Q_D(const MyMoneySplit); 0147 return d->m_shares; 0148 } 0149 0150 void MyMoneySplit::setShares(const MyMoneyMoney& shares) 0151 { 0152 Q_D(MyMoneySplit); 0153 d->m_shares = shares; 0154 } 0155 0156 void MyMoneySplit::negateShares() 0157 { 0158 Q_D(MyMoneySplit); 0159 d->m_shares = -d->m_shares; 0160 } 0161 0162 QString MyMoneySplit::value(const QString& key) const 0163 { 0164 return MyMoneyKeyValueContainer::value(key); 0165 } 0166 0167 void MyMoneySplit::setValue(const QString& key, const QString& value) 0168 { 0169 MyMoneyKeyValueContainer::setValue(key, value); 0170 } 0171 0172 void MyMoneySplit::setValue(const MyMoneyMoney& value) 0173 { 0174 Q_D(MyMoneySplit); 0175 d->m_value = value; 0176 } 0177 0178 void MyMoneySplit::setValue(const MyMoneyMoney& value, const QString& transactionCurrencyId, const QString& splitCurrencyId) 0179 { 0180 if (transactionCurrencyId == splitCurrencyId) 0181 setValue(value); 0182 else 0183 setShares(value); 0184 } 0185 0186 void MyMoneySplit::negateValue() 0187 { 0188 Q_D(MyMoneySplit); 0189 d->m_value = -d->m_value; 0190 } 0191 0192 QString MyMoneySplit::payeeId() const 0193 { 0194 Q_D(const MyMoneySplit); 0195 return d->m_payee; 0196 } 0197 0198 void MyMoneySplit::setPayeeId(const QString& payee) 0199 { 0200 Q_D(MyMoneySplit); 0201 d->m_payee = payee; 0202 } 0203 0204 QList<QString> MyMoneySplit::tagIdList() const 0205 { 0206 Q_D(const MyMoneySplit); 0207 return d->m_tagList; 0208 } 0209 0210 void MyMoneySplit::setTagIdList(const QList<QString>& tagList) 0211 { 0212 Q_D(MyMoneySplit); 0213 d->m_tagList = tagList; 0214 } 0215 0216 void MyMoneySplit::setAction(eMyMoney::Split::InvestmentTransactionType type) 0217 { 0218 switch (type) { 0219 case eMyMoney::Split::InvestmentTransactionType::BuyShares: 0220 case eMyMoney::Split::InvestmentTransactionType::SellShares: 0221 setAction(actionName(Split::Action::BuyShares)); 0222 break; 0223 case eMyMoney::Split::InvestmentTransactionType::Dividend: 0224 setAction(actionName(Split::Action::Dividend)); 0225 break; 0226 case eMyMoney::Split::InvestmentTransactionType::Yield: 0227 setAction(actionName(Split::Action::Yield)); 0228 break; 0229 case eMyMoney::Split::InvestmentTransactionType::ReinvestDividend: 0230 setAction(actionName(Split::Action::ReinvestDividend)); 0231 break; 0232 case eMyMoney::Split::InvestmentTransactionType::AddShares: 0233 case eMyMoney::Split::InvestmentTransactionType::RemoveShares: 0234 setAction(actionName(Split::Action::AddShares)); 0235 break; 0236 case eMyMoney::Split::InvestmentTransactionType::SplitShares: 0237 setAction(actionName(Split::Action::SplitShares)); 0238 break; 0239 case eMyMoney::Split::InvestmentTransactionType::InterestIncome: 0240 setAction(actionName(Split::Action::InterestIncome)); 0241 break; 0242 case eMyMoney::Split::InvestmentTransactionType::UnknownTransactionType: 0243 break; 0244 } 0245 } 0246 0247 QString MyMoneySplit::action() const 0248 { 0249 Q_D(const MyMoneySplit); 0250 return d->m_action; 0251 } 0252 0253 void MyMoneySplit::setAction(const QString& action) 0254 { 0255 Q_D(MyMoneySplit); 0256 d->m_action = action; 0257 } 0258 0259 bool MyMoneySplit::isAmortizationSplit() const 0260 { 0261 Q_D(const MyMoneySplit); 0262 return d->m_action == actionName(Split::Action::Amortization); 0263 } 0264 0265 bool MyMoneySplit::isInterestSplit() const 0266 { 0267 Q_D(const MyMoneySplit); 0268 return d->m_action == actionName(Split::Action::Interest); 0269 } 0270 0271 QString MyMoneySplit::number() const 0272 { 0273 Q_D(const MyMoneySplit); 0274 return d->m_number; 0275 } 0276 0277 void MyMoneySplit::setNumber(const QString& number) 0278 { 0279 Q_D(MyMoneySplit); 0280 d->m_number = number; 0281 } 0282 0283 bool MyMoneySplit::isAutoCalc() const 0284 { 0285 Q_D(const MyMoneySplit); 0286 return (d->m_shares == MyMoneyMoney::autoCalc) || (d->m_value == MyMoneyMoney::autoCalc); 0287 } 0288 0289 QString MyMoneySplit::bankID() const 0290 { 0291 Q_D(const MyMoneySplit); 0292 return d->m_bankID; 0293 } 0294 0295 void MyMoneySplit::setBankID(const QString& bankID) 0296 { 0297 Q_D(MyMoneySplit); 0298 d->m_bankID = bankID; 0299 } 0300 0301 QString MyMoneySplit::transactionId() const 0302 { 0303 Q_D(const MyMoneySplit); 0304 return d->m_transactionId; 0305 } 0306 0307 void MyMoneySplit::setTransactionId(const QString& id) 0308 { 0309 Q_D(MyMoneySplit); 0310 d->m_transactionId = id; 0311 } 0312 0313 0314 MyMoneyMoney MyMoneySplit::value() const 0315 { 0316 Q_D(const MyMoneySplit); 0317 return d->m_value; 0318 } 0319 0320 MyMoneyMoney MyMoneySplit::value(const QString& transactionCurrencyId, const QString& splitCurrencyId) const 0321 { 0322 Q_D(const MyMoneySplit); 0323 return (transactionCurrencyId == splitCurrencyId) ? d->m_value : d->m_shares; 0324 } 0325 0326 MyMoneyMoney MyMoneySplit::actualPrice() const 0327 { 0328 Q_D(const MyMoneySplit); 0329 return d->m_price; 0330 } 0331 0332 void MyMoneySplit::setPrice(const MyMoneyMoney& price) 0333 { 0334 Q_D(MyMoneySplit); 0335 d->m_price = price; 0336 } 0337 0338 MyMoneyMoney MyMoneySplit::price() const 0339 { 0340 Q_D(const MyMoneySplit); 0341 if (!d->m_price.isZero()) 0342 return d->m_price; 0343 if (!d->m_value.isZero() && !d->m_shares.isZero()) 0344 return d->m_value / d->m_shares; 0345 return MyMoneyMoney::ONE; 0346 } 0347 0348 bool MyMoneySplit::hasReferenceTo(const QString& id) const 0349 { 0350 Q_D(const MyMoneySplit); 0351 auto rc = false; 0352 if (isMatched()) { 0353 rc = matchedTransaction().hasReferenceTo(id); 0354 } 0355 for (int i = 0; i < d->m_tagList.size(); i++) 0356 if (id == d->m_tagList[i]) 0357 return true; 0358 return rc || (id == d->m_account) || (id == d->m_payee) || (id == d->m_costCenter); 0359 } 0360 0361 bool MyMoneySplit::isMatched() const 0362 { 0363 Q_D(const MyMoneySplit); 0364 return d->m_isMatched; 0365 } 0366 0367 void MyMoneySplit::addMatch(const MyMoneyTransaction& _t) 0368 { 0369 Q_D(MyMoneySplit); 0370 // now we allow matching of two manual transactions 0371 d->m_matchedTransaction = _t; 0372 d->m_matchedTransaction.clearId(); 0373 d->m_isMatched = true; 0374 } 0375 0376 void MyMoneySplit::removeMatch() 0377 { 0378 Q_D(MyMoneySplit); 0379 d->m_matchedTransaction = MyMoneyTransaction(); 0380 d->m_isMatched = false; 0381 } 0382 0383 MyMoneyTransaction MyMoneySplit::matchedTransaction() const 0384 { 0385 Q_D(const MyMoneySplit); 0386 if (d->m_isMatched) 0387 return d->m_matchedTransaction; 0388 0389 return MyMoneyTransaction(); 0390 } 0391 0392 bool MyMoneySplit::replaceId(const QString& newId, const QString& oldId) 0393 { 0394 auto changed = false; 0395 Q_D(MyMoneySplit); 0396 0397 if (d->m_payee == oldId) { 0398 d->m_payee = newId; 0399 changed = true; 0400 } else if (d->m_account == oldId) { 0401 d->m_account = newId; 0402 changed = true; 0403 } else if (d->m_costCenter == oldId) { 0404 d->m_costCenter = newId; 0405 changed = true; 0406 } 0407 0408 if (isMatched()) { 0409 MyMoneyTransaction t = matchedTransaction(); 0410 if (t.replaceId(newId, oldId)) { 0411 removeMatch(); 0412 addMatch(t); 0413 changed = true; 0414 } 0415 } 0416 0417 return changed; 0418 } 0419 0420 QString MyMoneySplit::actionName(Split::Action action) 0421 { 0422 static const QHash<Split::Action, QString> actionNames { 0423 {Split::Action::Check, QStringLiteral("Check")}, 0424 {Split::Action::Deposit, QStringLiteral("Deposit")}, 0425 {Split::Action::Transfer, QStringLiteral("Transfer")}, 0426 {Split::Action::Withdrawal, QStringLiteral("Withdrawal")}, 0427 {Split::Action::ATM, QStringLiteral("ATM")}, 0428 {Split::Action::Amortization, QStringLiteral("Amortization")}, 0429 {Split::Action::Interest, QStringLiteral("Interest")}, 0430 {Split::Action::BuyShares, QStringLiteral("Buy")}, 0431 {Split::Action::Dividend, QStringLiteral("Dividend")}, 0432 {Split::Action::ReinvestDividend, QStringLiteral("Reinvest")}, 0433 {Split::Action::Yield, QStringLiteral("Yield")}, 0434 {Split::Action::AddShares, QStringLiteral("Add")}, 0435 {Split::Action::SplitShares, QStringLiteral("Split")}, 0436 {Split::Action::InterestIncome, QStringLiteral("IntIncome")}, 0437 }; 0438 return actionNames[action]; 0439 }