File indexing completed on 2024-05-12 16:41:58
0001 /* 0002 KMyMoney transaction importing module - base class for searching for a matching transaction 0003 0004 SPDX-FileCopyrightText: 2012 Lukasz Maszczynski <lukasz@maszczynski.net> 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 #ifndef TRANSACTIONMATCHFINDER_H 0009 #define TRANSACTIONMATCHFINDER_H 0010 0011 #include <QScopedPointer> 0012 0013 #include "mymoneysplit.h" 0014 #include "mymoneytransaction.h" 0015 #include "mymoneyschedule.h" 0016 0017 /** The class provides an interface for finding a MyMoneyTransaction match with the one being imported 0018 */ 0019 class TransactionMatchFinder 0020 { 0021 public: 0022 /// enumerates possible match results 0023 typedef enum { 0024 MatchNotFound, ///< no matching transaction found 0025 MatchImprecise, ///< matching transaction found 0026 MatchPrecise, ///< matching transaction found with exactly the same parameters 0027 MatchDuplicate, ///< found transaction duplicate 0028 } MatchResult; 0029 0030 /** Initializes the match finder. 0031 * @param matchWindow max number of days the transactions may vary and still be considered to be matching 0032 */ 0033 explicit TransactionMatchFinder(int m_matchWindow); 0034 virtual ~TransactionMatchFinder(); 0035 0036 /** Searches for a matching transaction. See derived classes to learn where the transaction is looked for. 0037 * 0038 * @param transactionToMatch the imported transaction we want to match 0039 * @param splitToMatch the split of that transaction referencing the account we import into 0040 * @return the search result. There are several possible results: 0041 * - @ref MatchNotFound means that the imported transaction does not match any other transaction 0042 * - @ref MatchDuplicate means that the imported transaction is a duplicate of another transaction, 0043 * - @ref MatchImprecise means that the imported transaction matches another transaction, but the match 0044 * is not precise (e.g. transaction dates are not equal, but within matchWindow range) 0045 * - @ref MatchPrecise means that the imported transaction matches another transaction precisely 0046 */ 0047 TransactionMatchFinder::MatchResult findMatch(const MyMoneyTransaction& transactionToMatch, const MyMoneySplit& splitToMatch); 0048 0049 /** Returns the matched split. 0050 * 0051 * @throws MyMoneyException if no match is found 0052 */ 0053 MyMoneySplit getMatchedSplit() const; 0054 0055 /** Returns the matched transaction 0056 * 0057 * @throws MyMoneyException if no transaction was matched 0058 */ 0059 MyMoneyTransaction getMatchedTransaction() const; 0060 0061 /** Returns the matched schedule 0062 * 0063 * @throws MyMoneyException if no schedule was matched 0064 */ 0065 MyMoneySchedule getMatchedSchedule() const; 0066 0067 protected: 0068 int m_matchWindow; 0069 0070 MyMoneyTransaction importedTransaction; //!< the imported transaction that is being matched 0071 MyMoneySplit m_importedSplit; //!< the imported transaction's split that is being matched 0072 0073 MatchResult matchResult; //!< match result 0074 QScopedPointer<MyMoneyTransaction> matchedTransaction; //!< the transaction that matches the imported one 0075 QScopedPointer<MyMoneySchedule> matchedSchedule; //!< the schedule that matches the imported transaction 0076 QScopedPointer<MyMoneySplit> matchedSplit; //!< the split that matches the imported one 0077 0078 /** Prepares a list of match candidates for further processing, must be implemented in subclass 0079 */ 0080 virtual void createListOfMatchCandidates() = 0; 0081 0082 /** Searches the list of match candidates for a real match, must be implemented in subclass 0083 */ 0084 virtual void findMatchInMatchCandidatesList() = 0; 0085 0086 /** Checks whether one split is a duplicate of the other 0087 * @param split1 the first split 0088 * @param split2 the second split 0089 * @param amountVariation the max number of percent the amounts may differ and still be considered matching 0090 * @return true, if split2 is a duplicate of split1 (and vice-versa); false otherwise 0091 * 0092 * Splits are considered duplicates if both have the same (non-empty) bankId assigned and same amounts. 0093 */ 0094 bool splitsAreDuplicates(const MyMoneySplit & split1, const MyMoneySplit & split2, int amountVariation = 0) const; 0095 0096 /** Checks whether one split matches the other 0097 * @param importedSplit the split being imported 0098 * @param existingSplit the existing split 0099 * @param amountVariation the max number of percent the amounts may differ and still be considered matching 0100 * @return true, if importedSplit matches existingSplit (not necessarily the other way around); false otherwise 0101 * 0102 * Splits are considered a match if both of them: 0103 * - reference the same account 0104 * - have matching bankID-s 0105 * - have matching amounts 0106 * - have empty or matching payees 0107 * - are not marked as matched already 0108 */ 0109 bool splitsMatch(const MyMoneySplit & m_importedSplit, const MyMoneySplit & existingSplit, int amountVariation = 0) const; 0110 0111 /** Checks whether splits reference the same account 0112 * @param split1 the first split 0113 * @param split2 the second split 0114 * @return true, if the same account is referenced by the splits; false otherwise 0115 */ 0116 bool splitsAccountsMatch(const MyMoneySplit & split1, const MyMoneySplit & split2) const; 0117 0118 /** Checks whether splits amounts match 0119 * @param split1 the first split 0120 * @param split2 the second split 0121 * @param amountVariation the max number of percent the amounts may differ and still be considered matching 0122 * @return true, if amounts match; false otherwise 0123 */ 0124 bool splitsAmountsMatch(const MyMoneySplit & split1, const MyMoneySplit & split2, int amountVariation = 0) const; 0125 0126 /** Checks whether the splits' bankId-s match 0127 * @param importedSplit the imported split 0128 * @param existingSplit the existing split 0129 * @return true, if bank ids match; false otherwise 0130 * 0131 * BankID-s match if any of the two occurs: 0132 * - they are equal 0133 * - bankId of existing split is empty 0134 */ 0135 bool splitsBankIdsMatch(const MyMoneySplit & m_importedSplit, const MyMoneySplit & existingSplit) const; 0136 0137 /** Checks whether the splits' bankId-s are duplicated 0138 * @param split1 the first split 0139 * @param split2 the second split 0140 * @return true, if bank ids are equal and non-empty; false otherwise 0141 */ 0142 bool splitsBankIdsDuplicated(const MyMoneySplit & split1, const MyMoneySplit & split2) const; 0143 0144 /** Checks whether payees of both splits match each other or at least one of them is empty 0145 * @param split1 the first split 0146 * @param split2 the second split 0147 * @return true, if splits reference the same payee or at least one payee is empty; false otherwise 0148 */ 0149 bool splitsPayeesMatchOrEmpty(const MyMoneySplit & split1, const MyMoneySplit & split2) const; 0150 0151 /** Searches for a split in the transaction which matches imported transaction's split 0152 * @param transaction the transaction to look for the split in 0153 * @param amountVariation the max number of percent the split amounts may differ and still be considered matching 0154 */ 0155 void findMatchingSplit(const MyMoneyTransaction & transaction, int amountVariation); 0156 }; 0157 0158 #endif // TRANSACTIONMATCHFINDER_H