File indexing completed on 2024-05-12 16:42:42
0001 /* 0002 SPDX-FileCopyrightText: 2000-2002 Michael Edwardes <mte@users.sourceforge.net> 0003 SPDX-FileCopyrightText: 2001-2017 Thomas Baumgart <tbaumgart@kde.org> 0004 SPDX-FileCopyrightText: 2001 Felix Rodriguez <frodriguez@users.sourceforge.net> 0005 SPDX-FileCopyrightText: 2003 Kevin Tambascio <ktambascio@users.sourceforge.net> 0006 SPDX-FileCopyrightText: 2004-2005 Ace Jones <acejones@users.sourceforge.net> 0007 SPDX-FileCopyrightText: 2006 Darren Gould <darren_gould@gmx.de> 0008 SPDX-License-Identifier: GPL-2.0-or-later 0009 */ 0010 0011 #ifndef MYMONEYTRANSACTION_H 0012 #define MYMONEYTRANSACTION_H 0013 0014 // ---------------------------------------------------------------------------- 0015 // QT Includes 0016 0017 #include <QMetaType> 0018 0019 // ---------------------------------------------------------------------------- 0020 // Project Includes 0021 0022 #include "mymoneykeyvaluecontainer.h" 0023 #include "mymoneyobject.h" 0024 #include "kmm_mymoney_export.h" 0025 #include "mymoneyunittestable.h" 0026 0027 class QString; 0028 class QDate; 0029 0030 class MyMoneyMoney; 0031 class MyMoneySplit; 0032 class QStringList; 0033 0034 template <typename T> class QList; 0035 0036 /** 0037 * This class represents a transaction within the MyMoneyEngine. A transaction 0038 * contains none, one or more splits of type MyMoneySplit. They are stored in 0039 * a QList<MyMoneySplit> within this object. A transaction containing only 0040 * a single split with an amount not equal to 0 is an unbalanced transaction. It 0041 * is tolerated by the engine, but in general not a good idea as it is financially 0042 * wrong. 0043 */ 0044 class MyMoneyTransactionPrivate; 0045 class KMM_MYMONEY_EXPORT MyMoneyTransaction : public MyMoneyObject, public MyMoneyKeyValueContainer 0046 { 0047 Q_DECLARE_PRIVATE_D(MyMoneyObject::d_ptr, MyMoneyTransaction) 0048 0049 KMM_MYMONEY_UNIT_TESTABLE 0050 0051 public: 0052 0053 MyMoneyTransaction(); 0054 explicit MyMoneyTransaction(const QString &id); 0055 0056 MyMoneyTransaction(const QString& id, 0057 const MyMoneyTransaction& other); 0058 0059 MyMoneyTransaction(const MyMoneyTransaction & other); 0060 MyMoneyTransaction(MyMoneyTransaction && other); 0061 MyMoneyTransaction & operator=(MyMoneyTransaction other); 0062 friend void swap(MyMoneyTransaction& first, MyMoneyTransaction& second); 0063 0064 ~MyMoneyTransaction(); 0065 0066 friend QDataStream &operator<<(QDataStream &, MyMoneyTransaction &); 0067 friend QDataStream &operator>>(QDataStream &, MyMoneyTransaction &); 0068 0069 QDate entryDate() const; 0070 void setEntryDate(const QDate& date); 0071 0072 QDate postDate() const; 0073 void setPostDate(const QDate& date); 0074 0075 QString memo() const; 0076 void setMemo(const QString& memo); 0077 0078 QList<MyMoneySplit> splits() const; 0079 QList<MyMoneySplit>& splits(); 0080 MyMoneySplit firstSplit() const; 0081 uint splitCount() const; 0082 0083 QString commodity() const; 0084 void setCommodity(const QString& commodityId); 0085 0086 QString bankID() const; 0087 void setBankID(const QString& bankID); 0088 0089 bool operator == (const MyMoneyTransaction& right) const; 0090 bool operator != (const MyMoneyTransaction& r) const; 0091 bool operator < (const MyMoneyTransaction& r) const; 0092 bool operator <= (const MyMoneyTransaction& r) const; 0093 bool operator > (const MyMoneyTransaction& r) const; 0094 0095 /** 0096 * This method is used to extract a split for a given accountId 0097 * from a transaction. A parameter controls, whether the accountId 0098 * should match or not. In case of 'not match', the first not-matching 0099 * split is returned. 0100 * 0101 * @param accountId the account to look for 0102 * @param match if true, the account Id must match 0103 * if false, the account Id must not match 0104 * 0105 * @return reference to split within the transaction is returned 0106 */ 0107 MyMoneySplit splitByAccount(const QString& accountId, const bool match = true) const; 0108 0109 /** 0110 * This method is essentially the same as the previous method, except that 0111 * takes a list of accounts instead of just one. 0112 * 0113 * @param accountIds the list of accounts to look for 0114 * @param match if true, the account Id must match 0115 * if false, the account Id must not match 0116 * 0117 * @return reference to split within the transaction is returned 0118 */ 0119 MyMoneySplit splitByAccount(const QStringList& accountIds, const bool match = true) const; 0120 0121 /** 0122 * This method is used to extract a split from a transaction. 0123 * 0124 * @param splitId the split to look for 0125 * 0126 * @return reference to split within the transaction is returned 0127 */ 0128 MyMoneySplit splitById(const QString& splitId) const; 0129 0130 /** 0131 * This method is used to extract a split for a given payeeId 0132 * from a transaction. 0133 * 0134 * @param payeeId the payee to look for 0135 * 0136 * @return reference to split within the transaction is returned 0137 */ 0138 MyMoneySplit splitByPayee(const QString& payeeId) const; 0139 0140 /** 0141 * This method is used to check if the given account is used 0142 * in any of the splits of this transaction 0143 * 0144 * @param id account id that should be checked for usage 0145 */ 0146 bool accountReferenced(const QString& id) const; 0147 0148 /** 0149 * This method is used to add a split to the transaction. The split 0150 * will be assigned an id. The id member must be empty and the 0151 * accountId member must be filled. 0152 * 0153 * @param split reference to the split that should be added 0154 * 0155 */ 0156 void addSplit(MyMoneySplit &split); 0157 0158 /** 0159 * This method is used to modify a split in a transaction 0160 */ 0161 void modifySplit(const MyMoneySplit& split); 0162 0163 /** 0164 * This method is used to remove a split from a transaction 0165 */ 0166 void removeSplit(const MyMoneySplit& split); 0167 0168 /** 0169 * This method is used to remove all splits from a transaction 0170 */ 0171 void removeSplits(); 0172 0173 /** 0174 * This method is used to return the sum of all splits of this transaction 0175 * 0176 * @return MyMoneyMoney value of sum of all splits 0177 */ 0178 MyMoneyMoney splitSum() const; 0179 0180 /** 0181 * This method is used to reverse a transaction by reversing the values of each split 0182 */ 0183 void reverse(); 0184 0185 /** 0186 * This method returns information if the transaction 0187 * contains information of a loan payment or not. 0188 * Loan payment transactions have at least one 0189 * split that is identified with a MyMoneySplit::action() of type 0190 * MyMoneySplit::actionName(eMyMoney::Split::Action::Amortization). 0191 * 0192 * @retval false transaction is no loan payment transaction 0193 * @retval true transaction is a loan payment transaction 0194 * 0195 * @note Upon internal failures, the return value @p false will be used. 0196 */ 0197 bool isLoanPayment() const; 0198 0199 /** 0200 * This method returns a const reference to the amortization split. 0201 * In case none is found, a reference to an empty split will be returned. 0202 */ 0203 MyMoneySplit amortizationSplit() const; 0204 0205 /** 0206 * This method returns a const reference to the interest split. 0207 * In case none is found, a reference to an empty split will be returned. 0208 */ 0209 MyMoneySplit interestSplit() const; 0210 0211 /** 0212 * returns @a true if this is a stock split transaction 0213 */ 0214 bool isStockSplit() const; 0215 0216 /** 0217 * returns @a true if this is an imported transaction 0218 */ 0219 bool isImported() const; 0220 0221 /** 0222 * Sets the imported state of this transaction to be the value of @a state . 0223 * @p state defaults to @p true. 0224 */ 0225 void setImported(bool state = true); 0226 0227 /** 0228 * This static method returns the id which will be assigned to the 0229 * first split added to a transaction. This ID can be used to figure 0230 * out the split that references the account through which a transaction 0231 * was entered. 0232 * 0233 * @return QString with ID of the first split of transactions 0234 */ 0235 static QString firstSplitID(); 0236 0237 /** 0238 * This method checks if a reference to the given object exists. It returns, 0239 * a @p true if the object is referencing the one requested by the 0240 * parameter @p id. If it does not, this method returns @p false. 0241 * 0242 * @param id id of the object to be checked for references 0243 * @retval true This object references object with id @p id. 0244 * @retval false This object does not reference the object with id @p id. 0245 */ 0246 bool hasReferenceTo(const QString& id) const override; 0247 0248 /** 0249 * Checks whether any split contains an autocalc split. 0250 * 0251 * @retval true at least one split has an autocalc value 0252 * @retval false all splits have fixed values 0253 */ 0254 bool hasAutoCalcSplit() const; 0255 0256 /** 0257 * Returns a signature consisting of the account ids and the 0258 * number of times they occur in the transaction if @a includeSplitCount 0259 * is @a true. The signature is independent from the order of splits. 0260 * 0261 * Example: Having splits referencing the account B, A and B, the returned 0262 * value will be "A-B" if @p includeSplitCount is @p false or A*1-B*2 if it 0263 * is @p true. 0264 * 0265 * The same result will be returned if the list of splits is A, B, B. 0266 * 0267 * @param includeSplitCount if @p true, the string @p *n with @p n being 0268 * the number of splits referencing this account. The default for 0269 * this parameter is @p false. 0270 */ 0271 QString accountSignature(bool includeSplitCount = false) const; 0272 0273 QString uniqueSortKey() const; 0274 0275 /** 0276 * This module implements an algorithm used by P.J. Weinberger 0277 * for fast hashing. Source: COMPILERS by Alfred V. Aho, 0278 * pages 435-437. 0279 * 0280 * It converts the string passed in @p txt into a non-unique 0281 * unsigned long integer value. 0282 * 0283 * @param txt the text to be hashed 0284 * @param h initial hash value (default 0) 0285 * @return non-unique hash value of the text @p txt 0286 */ 0287 static unsigned long hash(const QString& txt, unsigned long h = 0); 0288 0289 /** 0290 * This method replaces all occurrences of id @a oldId with 0291 * @a newId. All other ids are not changed. 0292 * 0293 * @return true if any change has been performed 0294 * @return false if nothing has been modified 0295 */ 0296 bool replaceId(const QString& newId, const QString& oldId); 0297 }; 0298 0299 inline void swap(MyMoneyTransaction& first, MyMoneyTransaction& second) // krazy:exclude=inline 0300 { 0301 using std::swap; 0302 swap(first.MyMoneyObject::d_ptr, second.MyMoneyObject::d_ptr); 0303 swap(first.MyMoneyKeyValueContainer::d_ptr, second.MyMoneyKeyValueContainer::d_ptr); 0304 } 0305 0306 inline MyMoneyTransaction::MyMoneyTransaction(MyMoneyTransaction && other) : MyMoneyTransaction() // krazy:exclude=inline 0307 { 0308 swap(*this, other); 0309 } 0310 0311 inline MyMoneyTransaction & MyMoneyTransaction::operator=(MyMoneyTransaction other) // krazy:exclude=inline 0312 { 0313 swap(*this, other); 0314 return *this; 0315 } 0316 0317 /** 0318 * Make it possible to hold @ref MyMoneyTransaction objects inside @ref QVariant objects. 0319 */ 0320 Q_DECLARE_METATYPE(MyMoneyTransaction) 0321 0322 #endif