File indexing completed on 2024-05-19 05:07:25
0001 /* 0002 SPDX-FileCopyrightText: 2003-2019 Thomas Baumgart <tbaumgart@kde.org> 0003 SPDX-FileCopyrightText: 2004 Ace Jones <acejones@users.sourceforge.net> 0004 SPDX-FileCopyrightText: 2008-2010 Alvaro Soliverez <asoliverez@gmail.com> 0005 SPDX-FileCopyrightText: 2017-2018 Łukasz Wojniłowicz <lukasz.wojnilowicz@gmail.com> 0006 SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 0009 #ifndef MYMONEYTRANSACTIONFILTER_H 0010 #define MYMONEYTRANSACTIONFILTER_H 0011 0012 #include "kmm_mymoney_export.h" 0013 0014 // ---------------------------------------------------------------------------- 0015 // QT Includes 0016 0017 #include <QMetaType> 0018 class QString; 0019 class QDate; 0020 class QRegularExpression; 0021 0022 // ---------------------------------------------------------------------------- 0023 // KDE Includes 0024 0025 // ---------------------------------------------------------------------------- 0026 // Project Includes 0027 0028 template <typename T> class QList; 0029 0030 class MyMoneyMoney; 0031 class MyMoneySplit; 0032 class MyMoneyAccount; 0033 0034 namespace eMyMoney { 0035 namespace TransactionFilter { 0036 enum class Date; 0037 enum class Validity; 0038 } 0039 } 0040 0041 /** 0042 * @author Thomas Baumgart 0043 * @author Łukasz Wojniłowicz 0044 */ 0045 0046 class MyMoneyTransaction; 0047 class MyMoneyTransactionFilterPrivate; 0048 class KMM_MYMONEY_EXPORT MyMoneyTransactionFilter 0049 { 0050 Q_DECLARE_PRIVATE(MyMoneyTransactionFilter) 0051 0052 protected: 0053 MyMoneyTransactionFilterPrivate* d_ptr; // name shouldn't colide with the one in mymoneyreport.h 0054 0055 public: 0056 enum FilterFlags { 0057 textFilterActive = 0x0001, 0058 accountFilterActive = 0x0002, 0059 payeeFilterActive = 0x0004, 0060 tagFilterActive = 0x0008, 0061 categoryFilterActive = 0x0010, 0062 nrFilterActive = 0x0020, 0063 dateFilterActive = 0x0040, 0064 amountFilterActive = 0x0080, 0065 typeFilterActive = 0x0100, 0066 stateFilterActive = 0x0200, 0067 validityFilterActive = 0x0400, 0068 }; 0069 Q_DECLARE_FLAGS(FilterSet, FilterFlags) 0070 0071 /** 0072 * This is the standard constructor for a transaction filter. 0073 * It creates the object and calls setReportAllSplits() to 0074 * report all matching splits as separate entries. Use 0075 * setReportAllSplits() to override this behaviour. 0076 */ 0077 MyMoneyTransactionFilter(); 0078 0079 /** 0080 * This is a convenience constructor to allow construction of 0081 * a simple account filter. It is basically the same as the 0082 * following: 0083 * 0084 * @code 0085 * : 0086 * MyMoneyTransactionFilter filter; 0087 * filter.setReportAllSplits(false); 0088 * filter.addAccount(id); 0089 * : 0090 * @endcode 0091 * 0092 * @param id reference to account id 0093 */ 0094 explicit MyMoneyTransactionFilter(const QString& id); 0095 0096 MyMoneyTransactionFilter(const MyMoneyTransactionFilter & other); 0097 MyMoneyTransactionFilter(MyMoneyTransactionFilter && other); 0098 MyMoneyTransactionFilter & operator=(MyMoneyTransactionFilter other); 0099 friend void swap(MyMoneyTransactionFilter& first, MyMoneyTransactionFilter& second); 0100 0101 virtual ~MyMoneyTransactionFilter(); 0102 0103 /** 0104 * This method is used to clear the filter. All settings will be 0105 * removed. 0106 */ 0107 void clear(); 0108 0109 /** 0110 * This method is used to clear the accounts filter only. 0111 */ 0112 void clearAccountFilter(); 0113 0114 /** 0115 * This method is used to set the regular expression filter to the value specified 0116 * as parameter @p exp. The following text based fields are searched: 0117 * 0118 * - Memo 0119 * - Payee 0120 * - Tag 0121 * - Category 0122 * - Shares / Value 0123 * - Number 0124 * 0125 * @param exp The regular expression that must be found in a transaction 0126 * before it is included in the result set. 0127 * @param isRegExp the user should see a regular expression if true or a wildcard if false 0128 * @param invert If true, value must not be contained in any of the above mentioned fields 0129 * 0130 */ 0131 void setTextFilter(const QRegularExpression& exp, bool isRegExp, bool invert); 0132 0133 /** 0134 * This method will add the account with id @p id to the list of matching accounts. 0135 * If the list is empty, any transaction will match. 0136 * 0137 * @param id internal ID of the account 0138 */ 0139 void addAccount(const QString& id); 0140 0141 /** 0142 * This is a convenience method and behaves exactly like the above 0143 * method but for a list of id's. 0144 */ 0145 void addAccount(const QStringList& ids); 0146 0147 /** 0148 * This method will add the category with id @p id to the list of matching categories. 0149 * If the list is empty, only transaction with a single asset/liability account will match. 0150 * 0151 * @param id internal ID of the account 0152 */ 0153 void addCategory(const QString& id); 0154 0155 /** 0156 * This is a convenience method and behaves exactly like the above 0157 * method but for a list of id's. 0158 */ 0159 void addCategory(const QStringList& ids); 0160 0161 /** 0162 * This method sets the date filter to match only transactions with posting dates in 0163 * the date range specified by @p from and @p to. If @p from equal QDate() 0164 * all transactions with dates prior to @p to match. If @p to equals QDate() 0165 * all transactions with posting dates past @p from match. If @p from and @p to 0166 * are equal QDate() the filter is not activated and all transactions match. 0167 * 0168 * @param from from date 0169 * @param to to date 0170 */ 0171 void setDateFilter(const QDate& from, const QDate& to); 0172 0173 void setDateFilter(eMyMoney::TransactionFilter::Date range); 0174 0175 /** 0176 * This method sets the amount filter to match only transactions with 0177 * an amount in the range specified by @p from and @p to. 0178 * If a specific amount should be searched, @p from and @p to should be 0179 * the same value. 0180 * 0181 * @param from smallest value to match 0182 * @param to largest value to match 0183 */ 0184 void setAmountFilter(const MyMoneyMoney& from, const MyMoneyMoney& to); 0185 0186 /** 0187 * This method will add the payee with id @p id to the list of matching payees. 0188 * If the list is empty, any transaction will match. 0189 * 0190 * @param id internal id of the payee 0191 */ 0192 void addPayee(const QString& id); 0193 0194 /** 0195 * This method will add the tag with id @ta id to the list of matching tags. 0196 * If the list is empty, any transaction will match. 0197 * 0198 * @param id internal id of the tag 0199 */ 0200 void addTag(const QString& id); 0201 0202 /** 0203 */ 0204 void addType(const int type); 0205 0206 /** 0207 */ 0208 void addValidity(const int type); 0209 0210 /** 0211 */ 0212 void addState(const int state); 0213 0214 /** 0215 * This method sets the number filter to match only transactions with 0216 * a number in the range specified by @p from and @p to. 0217 * If a specific number should be searched, @p from and @p to should be 0218 * the same value. 0219 * 0220 * @param from smallest value to match 0221 * @param to largest value to match 0222 * 0223 * @note @p from and @p to can contain alphanumeric text 0224 */ 0225 void setNumberFilter(const QString& from, const QString& to); 0226 0227 /** 0228 * This method is used to check a specific transaction against the filter. 0229 * The transaction will match the whole filter, if all specified filters 0230 * match. If the filter is cleared using the clear() method, any transaction 0231 * matches. Matching splits from the transaction are returned by @ref 0232 * matchingSplits(). 0233 * 0234 * @param transaction A transaction 0235 * 0236 * @retval true The transaction matches the filter set 0237 * @retval false The transaction does not match at least one of 0238 * the filters in the filter set 0239 */ 0240 bool match(const MyMoneyTransaction& transaction); 0241 0242 /** 0243 * This method is used to check a specific split against the 0244 * text filter. The split will match if all specified and 0245 * checked filters match. If the filter is cleared using the clear() 0246 * method, any split matches. 0247 * 0248 * @param sp pointer to the split to be checked 0249 * 0250 * @retval true The split matches the filter set 0251 * @retval false The split does not match at least one of 0252 * the filters in the filter set 0253 */ 0254 bool matchText(const MyMoneySplit& s, const MyMoneyAccount &acc) const; 0255 0256 /** 0257 * This method is used to check a specific split against the 0258 * amount filter. The split will match if all specified and 0259 * checked filters match. If the filter is cleared using the clear() 0260 * method, any split matches. 0261 * 0262 * @param sp const reference to the split to be checked 0263 * 0264 * @retval true The split matches the filter set 0265 * @retval false The split does not match at least one of 0266 * the filters in the filter set 0267 */ 0268 bool matchAmount(const MyMoneySplit& s) const; 0269 0270 /** 0271 * Convenience method which actually returns matchText(sp) && matchAmount(sp). 0272 */ 0273 bool match(const MyMoneySplit& s) const; 0274 0275 /** 0276 * This method is used to switch the amount of splits reported 0277 * by matchingSplits(). If the argument @p report is @p true (the default 0278 * if no argument specified) then matchingSplits() will return all 0279 * matching splits of the transaction. If @p report is set to @p false, 0280 * then only the very first matching split will be returned by 0281 * matchingSplits(). 0282 * 0283 * @param report controls the behaviour of matchingsSplits() as explained above. 0284 */ 0285 void setReportAllSplits(const bool report = true); 0286 0287 /** 0288 * Consider splits in categories 0289 * 0290 * With this setting, splits in categories that are not considered 0291 * by default are taken into account. 0292 * 0293 * @param check check state 0294 */ 0295 void setConsiderCategorySplits(const bool check = true); 0296 0297 /** 0298 * Consider income and expense categories 0299 * 0300 * If the account or category filter is enabled, categories of 0301 * income and expense type are included if enabled with this 0302 * method. 0303 * 0304 * @param check check state 0305 */ 0306 void setConsiderCategory(const bool check = true); 0307 0308 void setTreatTransfersAsIncomeExpense(const bool check = true); 0309 0310 /** 0311 * This method is to avoid returning matching splits list 0312 * if only its count is needed 0313 * @return count of matching splits 0314 */ 0315 uint matchingSplitsCount(const MyMoneyTransaction& transaction); 0316 0317 /** 0318 * This method returns a list of the matching splits for the filter. 0319 * If m_reportAllSplits is set to false, then only the very first 0320 * split will be returned. Use setReportAllSplits() to change the 0321 * behaviour. 0322 * 0323 * @return reference list of MyMoneySplit objects containing the 0324 * matching splits. If multiple splits match, only the first 0325 * one will be returned. 0326 * 0327 * @note an empty list will be returned, if the filter only required 0328 * to check the data contained in the MyMoneyTransaction 0329 * object (e.g. posting-date, state, etc.). 0330 * 0331 * @note The constructors set m_reportAllSplits differently. Please 0332 * see the documentation of the constructors MyMoneyTransactionFilter() 0333 * and MyMoneyTransactionFilter(const QString&) for details. 0334 */ 0335 QVector<MyMoneySplit> matchingSplits(const MyMoneyTransaction& transaction); 0336 0337 /** 0338 * This method returns the from date set in the filter. If 0339 * no value has been set up for this filter, then QDate() is 0340 * returned. 0341 * 0342 * @return returns m_fromDate 0343 */ 0344 QDate fromDate() const; 0345 0346 /** 0347 * This method returns the to date set in the filter. If 0348 * no value has been set up for this filter, then QDate() is 0349 * returned. 0350 * 0351 * @return returns m_toDate 0352 */ 0353 QDate toDate() const; 0354 0355 /** 0356 * This method is used to return information about the 0357 * presence of a specific category in the category filter. 0358 * The category in question is included in the filter set, 0359 * if it has been set or no category filter is set. 0360 * 0361 * @param cat id of category in question 0362 * @return true if category is in filter set, false otherwise 0363 */ 0364 bool includesCategory(const QString& cat) const; 0365 0366 /** 0367 * This method is used to return information about the 0368 * presence of a specific account in the account filter. 0369 * The account in question is included in the filter set, 0370 * if it has been set or no account filter is set. 0371 * 0372 * @param acc id of account in question 0373 * @return true if account is in filter set, false otherwise 0374 */ 0375 bool includesAccount(const QString& acc) const; 0376 0377 /** 0378 * This method is used to return information about the 0379 * presence of a specific payee in the account filter. 0380 * The payee in question is included in the filter set, 0381 * if it has been set or no account filter is set. 0382 * 0383 * @param pye id of payee in question 0384 * @return true if payee is in filter set, false otherwise 0385 */ 0386 bool includesPayee(const QString& pye) const; 0387 0388 /** 0389 * This method is used to return information about the 0390 * presence of a specific tag in the account filter. 0391 * The tag in question is included in the filter set, 0392 * if it has been set or no account filter is set. 0393 * 0394 * @param tag id of tag in question 0395 * @return true if tag is in filter set, false otherwise 0396 */ 0397 bool includesTag(const QString& tag) const; 0398 0399 /** 0400 * This method is used to return information about the 0401 * presence of a date filter. 0402 * 0403 * @param from result value for the beginning of the date range 0404 * @param to result value for the end of the date range 0405 * @return true if a date filter is set 0406 */ 0407 bool dateFilter(QDate& from, QDate& to) const; 0408 0409 /** 0410 * This method is used to return information about the 0411 * presence of an amount filter. 0412 * 0413 * @param from result value for the low end of the amount range 0414 * @param to result value for the high end of the amount range 0415 * @return true if an amount filter is set 0416 */ 0417 bool amountFilter(MyMoneyMoney& from, MyMoneyMoney& to) const; 0418 0419 /** 0420 * This method is used to return information about the 0421 * presence of an number filter. 0422 * 0423 * @param from result value for the low end of the number range 0424 * @param to result value for the high end of the number range 0425 * @return true if a number filter is set 0426 */ 0427 bool numberFilter(QString& from, QString& to) const; 0428 0429 /** 0430 * This method returns whether a payee filter has been set, 0431 * and if so, it returns all the payees set in the filter. 0432 * 0433 * @param list list to append payees into 0434 * @return return true if a payee filter has been set 0435 */ 0436 bool payees(QStringList& list) const; 0437 0438 /** 0439 * This method returns all payees set in the filter. 0440 * 0441 * @return QStringList of payeeIds to match; 0442 */ 0443 QStringList payees() const; 0444 0445 /** 0446 * This method returns whether a tag filter has been set, 0447 * and if so, it returns all the tags set in the filter. 0448 * 0449 * @param list list to append tags into 0450 * @return return true if a tag filter has been set 0451 */ 0452 bool tags(QStringList& list) const; 0453 0454 /** 0455 * This method returns all tag ids that have been 0456 * added to the filter. If no tag filter has been set, 0457 * an empty list is returned. 0458 * 0459 * @returns list of tag ids 0460 */ 0461 QStringList tags() const; 0462 0463 /** 0464 * This method returns whether an account filter has been set, 0465 * and if so, it returns all the accounts set in the filter. 0466 * 0467 * @param list list to append accounts into 0468 * @return return true if an account filter has been set 0469 */ 0470 bool accounts(QStringList& list) const; 0471 0472 /** 0473 * This method returns all accounts set in the filter. 0474 * 0475 * @return QStringList of payeeIds to match; 0476 */ 0477 QStringList accounts() const; 0478 0479 /** 0480 * This method returns whether a category filter has been set, 0481 * and if so, it returns all the categories set in the filter. 0482 * 0483 * @param list list to append categories into 0484 * @return return true if a category filter has been set 0485 */ 0486 bool categories(QStringList& list) const; 0487 0488 /** 0489 * This method returns whether a type filter has been set, 0490 * and if so, it returns the first type in the filter. 0491 * 0492 * @param i int to replace with first type filter, untouched otherwise 0493 * @return return true if a type filter has been set 0494 */ 0495 bool firstType(int& i) const; 0496 0497 bool types(QList<int>& list) const; 0498 0499 /** 0500 * This method returns whether a state filter has been set, 0501 * and if so, it returns the first state in the filter. 0502 * 0503 * @param i reference to int to replace with first state filter, untouched otherwise 0504 * @return return true if a state filter has been set 0505 */ 0506 bool firstState(int& i) const; 0507 0508 bool states(QList<int>& list) const; 0509 0510 /** 0511 * This method returns whether a validity filter has been set, 0512 * and if so, it returns the first validity in the filter. 0513 * 0514 * @param i reference to int to replace with first validity filter, untouched otherwise 0515 * @return return true if a validity filter has been set 0516 */ 0517 bool firstValidity(int& i) const; 0518 0519 bool validities(QList<int>& list) const; 0520 0521 /** 0522 * This method returns whether a text filter has been set, 0523 * and if so, it returns the text filter. 0524 * 0525 * @param text regexp to replace with text filter, or blank if none set 0526 * @param isRegExp reference to bool which will return if @a text should 0527 * be treated as regex (@c true) or wildcard (@c false) 0528 * @return return true if a text filter has been set 0529 */ 0530 bool textFilter(QRegularExpression& text, bool& isRegExp) const; 0531 0532 /** 0533 * This method returns whether the text filter should return 0534 * that DO NOT contain the text 0535 */ 0536 bool isInvertingText() const; 0537 0538 /** 0539 * This method returns whether transfers should be treated as 0540 * income/expense transactions or not 0541 */ 0542 bool treatTransfersAsIncomeExpense() const; 0543 0544 /** 0545 * This method translates a plain-language date range into QDate 0546 * start & end 0547 * 0548 * @param range Plain-language range of dates, e.g. 'CurrentYear' 0549 * @param start QDate will be set to corresponding to the first date in @p range 0550 * @param end QDate will be set to corresponding to the last date in @p range 0551 * @return return true if a range was successfully set, or false if @p range was invalid 0552 */ 0553 static bool translateDateRange(eMyMoney::TransactionFilter::Date range, QDate& start, QDate& end); 0554 0555 static void setFiscalYearStart(int firstMonth, int firstDay); 0556 0557 FilterSet filterSet() const; 0558 0559 /** 0560 * This member removes all references to object identified by @p id. Used 0561 * to remove objects which are about to be removed from the engine. 0562 */ 0563 void removeReference(const QString& id); 0564 0565 private: 0566 /** 0567 * This is a conversion tool from eMyMoney::Split::State 0568 * to MyMoneyTransactionFilter::stateE types 0569 * 0570 * @param split reference to split in question 0571 * 0572 * @return converted reconcile flag of the split passed as parameter 0573 */ 0574 int splitState(const MyMoneySplit& split) const; 0575 0576 /** 0577 * This is a conversion tool from MyMoneySplit::action 0578 * to MyMoneyTransactionFilter::typeE types 0579 * 0580 * @param t reference to transaction 0581 * @param split reference to split in question 0582 * 0583 * @return converted action of the split passed as parameter 0584 */ 0585 int splitType(const MyMoneyTransaction& t, const MyMoneySplit& split, const MyMoneyAccount &acc) const; 0586 0587 /** 0588 * This method checks if a transaction is valid or not. A transaction 0589 * is considered valid, if the sum of all splits is zero, invalid otherwise. 0590 * 0591 * @param transaction reference to transaction to be checked 0592 * @retval valid transaction is valid 0593 * @retval invalid transaction is invalid 0594 */ 0595 eMyMoney::TransactionFilter::Validity validTransaction(const MyMoneyTransaction& transaction) const; 0596 }; 0597 0598 inline void swap(MyMoneyTransactionFilter& first, MyMoneyTransactionFilter& second) // krazy:exclude=inline 0599 { 0600 using std::swap; 0601 swap(first.d_ptr, second.d_ptr); 0602 } 0603 0604 inline MyMoneyTransactionFilter::MyMoneyTransactionFilter(MyMoneyTransactionFilter && other) : MyMoneyTransactionFilter() // krazy:exclude=inline 0605 { 0606 swap(*this, other); 0607 } 0608 0609 inline MyMoneyTransactionFilter & MyMoneyTransactionFilter::operator=(MyMoneyTransactionFilter other) // krazy:exclude=inline 0610 { 0611 swap(*this, other); 0612 return *this; 0613 } 0614 0615 /** 0616 * Make it possible to hold @ref MyMoneyTransactionFilter objects inside @ref QVariant objects. 0617 */ 0618 Q_DECLARE_METATYPE(MyMoneyTransactionFilter) 0619 Q_DECLARE_OPERATORS_FOR_FLAGS(MyMoneyTransactionFilter::FilterSet) 0620 0621 #endif