summaryrefslogtreecommitdiffstats
path: root/kmymoney2/mymoney/mymoneytransaction.h
blob: 6787c1d1d9232acc1f79ec11c3aa3db3911abf43 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
/***************************************************************************
                          mymoneytransaction.h
                             -------------------
    copyright            : (C) 2000 by Michael Edwardes
                           (C) 2002 by Thomas Baumgart
    email                : mte@users.sourceforge.net
                           ipwizard@users.sourceforge.net
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#ifndef MYMONEYTRANSACTION_H
#define MYMONEYTRANSACTION_H

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

// ----------------------------------------------------------------------------
// QT Includes

#include <tqstring.h>
#include <tqdatetime.h>
#include <tqptrlist.h>
#include <tqstringlist.h>

// ----------------------------------------------------------------------------
// Project Includes

#include "mymoneyutils.h"
#include "mymoneymoney.h"
#include "mymoneykeyvaluecontainer.h"
#include "mymoneysplit.h"
#include <kmymoney/export.h>

/**
  * This class represents a transaction within the MyMoneyEngine. A transaction
  * contains none, one or more splits of type MyMoneySplit. They are stored in
  * a TQValueList<MyMoneySplit> within this object. A transaction containing only
  * a single split with an amount not equal to 0 is an unbalanced transaction. It
  * is tolerated by the engine, but in general not a good idea as it is financially
  * wrong.
  */
class KMYMONEY_EXPORT MyMoneyTransaction : public MyMoneyObject, public MyMoneyKeyValueContainer
{
public:
  MyMoneyTransaction();
  MyMoneyTransaction(const TQString id,
                             const MyMoneyTransaction& transaction);
  /**
    * @param node reference to TQDomNode
    * @param forceId see MyMoneyObject(const TQDomElement&, const bool)
    */
  MyMoneyTransaction(const TQDomElement& node, const bool forceId = true);
  ~MyMoneyTransaction();

public:
  friend TQDataStream &operator<<(TQDataStream &, MyMoneyTransaction &);
  friend TQDataStream &operator>>(TQDataStream &, MyMoneyTransaction &);

  // Simple get operations
  const TQDate& entryDate(void) const { return m_entryDate; };
  const TQDate& postDate(void) const { return m_postDate; };
  const TQString& memo(void) const { return m_memo; };
  const TQValueList<MyMoneySplit>& splits(void) const { return m_splits; };
  TQValueList<MyMoneySplit>& splits(void) { return m_splits; };
  unsigned int splitCount(void) const { return m_splits.count(); };
  const TQString& commodity(void) const { return m_commodity; };
  const TQString& bankID(void) const /*__attribute__ ((deprecated))*/ { return m_bankID; };

  // Simple set operations
  void setPostDate(const TQDate& date);
  void setEntryDate(const TQDate& date);
  void setMemo(const TQString& memo);
  void setCommodity(const TQString& commodityId) { m_commodity = commodityId; };
  void setBankID(const TQString& bankID) /*__attribute__ ((deprecated))*/ { m_bankID = bankID; };

  bool operator == (const MyMoneyTransaction&) const;
  inline bool operator != (const MyMoneyTransaction& r) const { return !(*this == r); };
  bool operator< (const MyMoneyTransaction& r) const { return postDate() < r.postDate(); };
  bool operator<= (const MyMoneyTransaction& r) const { return postDate() <= r.postDate(); };
  bool operator> (const MyMoneyTransaction& r) const { return postDate() > r.postDate(); };

  /**
    * This method is used to extract a split for a given accountId
    * from a transaction. A parameter controls, whether the accountId
    * should match or not. In case of 'not match', the first not-matching
    * split is returned.
    *
    * @param accountId the account to look for
    * @param match if true, the account Id must match
    *              if false, the account Id must not match
    *
    * @return reference to split within the transaction is returned
    */
  const MyMoneySplit& splitByAccount(const TQString& accountId, const bool match = true) const;

  /**
    * This method is essentially the same as the previous method, except that
    * takes a list of accounts instead of just one.
    *
    * @param accountIds the list of accounts to look for
    * @param match if true, the account Id must match
    *              if false, the account Id must not match
    *
    * @return reference to split within the transaction is returned
    */
  const MyMoneySplit& splitByAccount(const TQStringList& accountIds, const bool match = true) const;

  /**
    * This method is used to extract a split from a transaction.
    *
    * @param splitId the split to look for
    *
    * @return reference to split within the transaction is returned
    */
  const MyMoneySplit& splitById(const TQString& splitId) const;

  /**
    * This method is used to extract a split for a given payeeId
    * from a transaction.
    *
    * @param payeeId the payee to look for
    *
    * @return reference to split within the transaction is returned
    */
  const MyMoneySplit& splitByPayee(const TQString& payeeId) const;

  /**
    * This method is used to check if the given account is used
    * in any of the splits of this transation
    *
    * @param id account id that should be checked for usage
    */
  bool accountReferenced(const TQString& id) const;

  /**
    * This method is used to add a split to the transaction. The split
    * will be assigned an id. The id member must be empty and the
    * accountId member must be filled.
    *
    * @param split reference to the split that should be added
    *
    */
  void addSplit(MyMoneySplit& split);

  /**
    * This method is used to modify a split in a transaction
    */
  void modifySplit(MyMoneySplit& split);

  /**
    * This method is used to remove a split from a transaction
    */
  void removeSplit(const MyMoneySplit& split);

  /**
    * This method is used to remove all splits from a transaction
    */
  void removeSplits(void);

  /**
    * This method is used to return the sum of all splits of this transaction
    *
    * @return MyMoneyMoney value of sum of all splits
    */
  const MyMoneyMoney splitSum(void) const;

  /**
    * This method returns information if the transaction
    * contains information of a loan payment or not.
    * Loan payment transactions have at least one
    * split that is identified with a MyMoneySplit::action() of type
    * MyMoneySplit::ActionAmortization.
    *
    * @retval false transaction is no loan payment transaction
    * @retval true  transaction is a loan payment transaction
    *
    * @note Upon internal failures, the return value @p false will be used.
    */
  bool isLoanPayment(void) const;

  /**
    * This method returns a const reference to the amortization split.
    * In case none is found, a reference to an empty split will be returned.
    */
  const MyMoneySplit& amortizationSplit(void) const;

  /**
   * This method returns a const reference to the interest split.
   * In case none is found, a reference to an empty split will be returned.
   */
  const MyMoneySplit& interestSplit(void) const;

  /**
    * This method is used to check if two transactions are identical.
    * Identical transactions have:
    *
    * - the same number of splits
    * - reference the same accounts
    * - have the same values in the splits
    * - have a postDate wihtin 3 days
    *
    * @param transaction reference to the transaction to be checked
    *                    against this transaction
    * @retval true transactions are identical
    * @retval false transactions are not identical
    */
  bool isDuplicate(const MyMoneyTransaction& transaction) const;

  /**
    * returns @a true if this is a stock split transaction
    */
  bool isStockSplit(void) const;

  /**
    * returns @a true if this is an imported transaction
    */
  bool isImported(void) const;

  /**
   * Sets the imported state of this transaction to be the value of @a state .
   * @p state defaults to @p true.
   */
  void setImported(bool state = true);

  /**
    * This static method returns the id which will be assigned to the
    * first split added to a transaction. This ID can be used to figure
    * out the split that references the account through which a transaction
    * was entered.
    *
    * @return TQString with ID of the first split of transactions
    */
  static const TQString firstSplitID(void);

  void writeXML(TQDomDocument& document, TQDomElement& parent) const;

  /**
    * This method checks if a reference to the given object exists. It returns,
    * a @p true if the object is referencing the one requested by the
    * parameter @p id. If it does not, this method returns @p false.
    *
    * @param id id of the object to be checked for references
    * @retval true This object references object with id @p id.
    * @retval false This object does not reference the object with id @p id.
    */
  virtual bool hasReferenceTo(const TQString& id) const;

  /**
    * Checks whether any split contains an autocalc split.
    *
    * @retval true at least one split has an autocalc value
    * @retval false all splits have fixed values
    */
  bool hasAutoCalcSplit(void) const;

  /**
    * Returns a signature consisting of the account ids and the
    * number of times they occur in the transaction if @a includeSplitCount
    * is @a true. The signature is independant from the order of splits.
    *
    * Example: Having splits referencing the account B, A and B, the returned
    * value will be "A-B" if @p includeSplitCount is @p false or A*1-B*2 if it
    * is @p true.
    *
    * The same result will be returned if the list of splits is A, B, B.
    *
    * @param includeSplitCount if @p true, the string @p *n with @p n being
    *        the number of splits referencing this account. The default for
    *        this parameter is @p false.
    */
  TQString accountSignature(bool includeSplitCount = false) const;

  TQString uniqueSortKey(void) const;

  /**
   * This module implements an algorithm used by P.J. Weinberger
   * for fast hashing. Source: COMPILERS by Alfred V. Aho,
   * pages 435-437.
   *
   * It converts the string passed in @p txt into a non-unique
   * unsigned long integer value.
   *
   * @param txt the text to be hashed
   * @param h initial hash value (default 0)
   * @return non-unique hash value of the text @p txt
   */
  static unsigned long hash(const TQString& txt, unsigned long h = 0);

private:
  /**
    * This method returns the next id to be used for a split
    */
  const TQString nextSplitID(void);

private:
  static const int SPLIT_ID_SIZE = 4;

  /**
    * This member contains the date when the transaction was entered
    * into the engine
    */
  TQDate m_entryDate;

  /**
    * This member contains the date the transaction was posted
    */
  TQDate m_postDate;

  /**
    * This member keeps the memo text associated with this transaction
    */
  TQString m_memo;

  /**
    * This member contains the splits for this transaction
    */
  TQValueList<MyMoneySplit> m_splits;

  /**
    * This member keeps the unique numbers of splits within this
    * transaction. Upon creation of a MyMoneyTransaction object this
    * value will be set to 1.
    */
  unsigned int m_nextSplitID;

  /**
    * This member keeps the base commodity (e.g. currency) for this transaction
    */
  TQString  m_commodity;

  /**
    * This member keeps the bank's unique ID for the transaction, so we can
    * avoid duplicates.  This is only used for electronic statement downloads.
    *
    * Note this is now deprecated!  Bank ID's should be set on splits, not transactions.
    */
  TQString m_bankID;

  /** constants for unique sort key */
  static const int YEAR_SIZE = 4;
  static const int MONTH_SIZE = 2;
  static const int DAY_SIZE = 2;
};
#endif