File indexing completed on 2024-05-12 05:06:45
0001 /* 0002 SPDX-FileCopyrightText: 2000-2002 Michael Edwardes <mte@users.sourceforge.net> 0003 SPDX-FileCopyrightText: 2001-2019 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 #include <QStringList> 0019 0020 // ---------------------------------------------------------------------------- 0021 // Project Includes 0022 0023 #include "mymoneykeyvaluecontainer.h" 0024 #include "mymoneyobject.h" 0025 #include "kmm_mymoney_export.h" 0026 #include "mymoneyunittestable.h" 0027 0028 class QString; 0029 class QDate; 0030 0031 class MyMoneyMoney; 0032 class MyMoneySplit; 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 uint splitCountWithValue() const; 0083 0084 QString commodity() const; 0085 void setCommodity(const QString& commodityId); 0086 0087 QString bankID() const; 0088 void setBankID(const QString& bankID); 0089 0090 bool operator == (const MyMoneyTransaction& right) const; 0091 bool operator != (const MyMoneyTransaction& r) const; 0092 bool operator < (const MyMoneyTransaction& r) const; 0093 bool operator <= (const MyMoneyTransaction& r) const; 0094 bool operator > (const MyMoneyTransaction& r) const; 0095 0096 /** 0097 * This method is used to extract a split for a given accountId 0098 * from a transaction. A parameter controls, whether the accountId 0099 * should match or not. In case of 'not match', the first not-matching 0100 * split is returned. 0101 * 0102 * @param accountId the account to look for 0103 * @param match if true, the account Id must match 0104 * if false, the account Id must not match 0105 * 0106 * @return reference to split within the transaction is returned 0107 */ 0108 MyMoneySplit splitByAccount(const QString& accountId, const bool match = true) const; 0109 0110 /** 0111 * This method is essentially the same as the previous method, except that 0112 * takes a list of accounts instead of just one. 0113 * 0114 * @param accountIds the list of accounts to look for 0115 * @param match if true, the account Id must match 0116 * if false, the account Id must not match 0117 * 0118 * @return reference to split within the transaction is returned 0119 */ 0120 MyMoneySplit splitByAccount(const QStringList& accountIds, const bool match = true) const; 0121 0122 /** 0123 * This method is used to extract a split from a transaction. 0124 * 0125 * @param splitId the split to look for 0126 * 0127 * @return reference to split within the transaction is returned 0128 */ 0129 MyMoneySplit splitById(const QString& splitId) const; 0130 0131 /** 0132 * This method is used to extract a split for a given payeeId 0133 * from a transaction. 0134 * 0135 * @param payeeId the payee to look for 0136 * 0137 * @return reference to split within the transaction is returned 0138 */ 0139 MyMoneySplit splitByPayee(const QString& payeeId) const; 0140 0141 /** 0142 * This method is used to check if the given account is used 0143 * in any of the splits of this transaction 0144 * 0145 * @param id account id that should be checked for usage 0146 */ 0147 bool accountReferenced(const QString& id) const; 0148 0149 /** 0150 * This method is used to add a split to the transaction. The split 0151 * will be assigned an id. The id member must be empty and the 0152 * accountId member must be filled. 0153 * 0154 * @param split reference to the split that should be added 0155 * 0156 */ 0157 void addSplit(MyMoneySplit &split); 0158 0159 /** 0160 * This method is used to modify a split in a transaction 0161 */ 0162 void modifySplit(const MyMoneySplit& split); 0163 0164 /** 0165 * This method is used to remove a split from a transaction 0166 */ 0167 void removeSplit(const MyMoneySplit& split); 0168 0169 /** 0170 * This method is used to remove all splits from a transaction 0171 */ 0172 void removeSplits(); 0173 0174 /** 0175 * This method is used to return the sum of all splits of this transaction 0176 * 0177 * @return MyMoneyMoney value of sum of all splits 0178 */ 0179 MyMoneyMoney splitSum() const; 0180 0181 /** 0182 * This method is used to reverse a transaction by reversing the values of each split 0183 */ 0184 void reverse(); 0185 0186 /** 0187 * This method returns information if the transaction 0188 * contains information of a loan payment or not. 0189 * Loan payment transactions have at least one 0190 * split that is identified with a MyMoneySplit::action() of type 0191 * MyMoneySplit::actionName(eMyMoney::Split::Action::Amortization). 0192 * 0193 * @retval false transaction is no loan payment transaction 0194 * @retval true transaction is a loan payment transaction 0195 * 0196 * @note Upon internal failures, the return value @p false will be used. 0197 */ 0198 bool isLoanPayment() const; 0199 0200 /** 0201 * This method returns a const reference to the amortization split. 0202 * In case none is found, a reference to an empty split will be returned. 0203 */ 0204 MyMoneySplit amortizationSplit() const; 0205 0206 /** 0207 * This method returns a const reference to the interest split. 0208 * In case none is found, a reference to an empty split will be returned. 0209 */ 0210 MyMoneySplit interestSplit() const; 0211 0212 /** 0213 * returns @a true if this is a stock split transaction 0214 */ 0215 bool isStockSplit() const; 0216 0217 /** 0218 * returns @a true if this is an imported transaction 0219 */ 0220 bool isImported() const; 0221 0222 /** 0223 * Sets the imported state of this transaction to be the value of @a state . 0224 * @p state defaults to @p true. 0225 */ 0226 void setImported(bool state = true); 0227 0228 /** 0229 * This static method returns the id which will be assigned to the 0230 * first split added to a transaction. This ID can be used to figure 0231 * out the split that references the account through which a transaction 0232 * was entered. 0233 * 0234 * @return QString with ID of the first split of transactions 0235 */ 0236 static QString firstSplitID(); 0237 0238 /** 0239 * Checks whether any split contains an autocalc split. 0240 * 0241 * @retval true at least one split has an autocalc value 0242 * @retval false all splits have fixed values 0243 */ 0244 bool hasAutoCalcSplit() const; 0245 0246 /** 0247 * Returns a signature consisting of the account ids and the 0248 * number of times they occur in the transaction if @a includeSplitCount 0249 * is @a true. The signature is independent from the order of splits. 0250 * 0251 * Example: Having splits referencing the account B, A and B, the returned 0252 * value will be "A-B" if @p includeSplitCount is @p false or A*1-B*2 if it 0253 * is @p true. 0254 * 0255 * The same result will be returned if the list of splits is A, B, B. 0256 * 0257 * @param includeSplitCount if @p true, the string @p *n with @p n being 0258 * the number of splits referencing this account. The default for 0259 * this parameter is @p false. 0260 */ 0261 QString accountSignature(bool includeSplitCount = false) const; 0262 0263 QString uniqueSortKey() const; 0264 static QString uniqueSortKey(const QDate& date, const QString& id); 0265 0266 /** 0267 * This module implements an algorithm used by P.J. Weinberger 0268 * for fast hashing. Source: COMPILERS by Alfred V. Aho, 0269 * pages 435-437. 0270 * 0271 * It converts the string passed in @p txt into a non-unique 0272 * unsigned long integer value. 0273 * 0274 * @param txt the text to be hashed 0275 * @param h initial hash value (default 0) 0276 * @return non-unique hash value of the text @p txt 0277 */ 0278 static unsigned long hash(const QString& txt, unsigned long h = 0); 0279 0280 /** 0281 * This method replaces all occurrences of id @a oldId with 0282 * @a newId. All other ids are not changed. 0283 * 0284 * @return true if any change has been performed 0285 * @return false if nothing has been modified 0286 */ 0287 bool replaceId(const QString& newId, const QString& oldId); 0288 }; 0289 0290 inline void swap(MyMoneyTransaction& first, MyMoneyTransaction& second) // krazy:exclude=inline 0291 { 0292 using std::swap; 0293 swap(first.MyMoneyObject::d_ptr, second.MyMoneyObject::d_ptr); 0294 swap(first.MyMoneyKeyValueContainer::d_ptr, second.MyMoneyKeyValueContainer::d_ptr); 0295 } 0296 0297 inline MyMoneyTransaction::MyMoneyTransaction(MyMoneyTransaction && other) : MyMoneyTransaction() // krazy:exclude=inline 0298 { 0299 swap(*this, other); 0300 } 0301 0302 inline MyMoneyTransaction & MyMoneyTransaction::operator=(MyMoneyTransaction other) // krazy:exclude=inline 0303 { 0304 swap(*this, other); 0305 return *this; 0306 } 0307 0308 /** 0309 * Make it possible to hold @ref MyMoneyTransaction objects inside @ref QVariant objects. 0310 */ 0311 Q_DECLARE_METATYPE(MyMoneyTransaction) 0312 0313 #endif