summaryrefslogtreecommitdiffstats
path: root/kmymoney2/converter/mymoneyqifreader.h
blob: e2f6638dc28f4514d57c948668bfca45b8c441f6 (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
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
/***************************************************************************
                          mymoneyqifreader.h  -  description
                             -------------------
    begin                : Mon Jan 27 2003
    copyright            : (C) 2000-2003 by Michael Edwardes
    email                : mte@users.sourceforge.net
                           Javier Campos Morales <javi_c@users.sourceforge.net>
                           Felix Rodriguez <frodriguez@users.sourceforge.net>
                           John C <thetacoturtle@users.sourceforge.net>
                           Thomas Baumgart <ipwizard@users.sourceforge.net>
                           Kevin Tambascio <ktambascio@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 MYMONEYQIFREADER_H
#define MYMONEYQIFREADER_H

// ----------------------------------------------------------------------------
// QT Headers

#include <tqobject.h>
#include <tqstring.h>
#include <tqstringlist.h>

// ----------------------------------------------------------------------------
// KDE Headers

#include <ktempfile.h>
#include <kprocess.h>
#include <kurl.h>

// ----------------------------------------------------------------------------
// Project Headers

#include "mymoneyqifprofile.h"
#include "../mymoney/mymoneyaccount.h"
#include "../mymoney/mymoneytransaction.h"

class MyMoneyFileTransaction;

/**
  * @author Thomas Baumgart
  */
class MyMoneyQifReader : public TQObject
{
  Q_OBJECT
  
  friend class Private;

private:
  typedef enum {
    EntryUnknown = 0,
    EntryAccount,
    EntryTransaction,
    EntryCategory,
    EntryMemorizedTransaction,
    EntryInvestmentTransaction,
    EntrySecurity,
    EntryPrice,
    EntryPayee,
    EntryClass,
    EntrySkip
  } QifEntryTypeE;

  struct qSplit
  {
    TQString      m_strCategoryName;
    TQString      m_strMemo;
    TQString      m_amount;
  };


public:
  MyMoneyQifReader();
  ~MyMoneyQifReader();

  /**
    * This method is used to store the filename into the object.
    * The file should exist. If it does and an external filter
    * program is specified with the current selected profile,
    * the file is send through this filter and the result
    * is stored in the m_tempFile file.
    *
    * @param url URL of the file to be imported
    */
  void setURL(const KURL& url);

  /**
    * This method is used to store the name of the profile into the object.
    * The selected profile will be loaded if it exists. If an external
    * filter program is specified with the current selected profile,
    * the file is send through this filter and the result
    * is stored in the m_tempFile file.
    *
    * @param name TQString reference to the name of the profile
    */
  void setProfile(const TQString& name);

  /**
    * This method actually starts the import of data from the selected file
    * into the MyMoney engine.
    *
    * This method also starts the user defined import filter program
    * defined in the QIF profile. If none is defined, the file is read
    * as is (actually the UNIX command 'cat -' is used as the filter).
    *
    * If data from the filter program is available, the slot
    * slotReceivedDataFromFilter() will be called.
    *
    * Make sure to connect the signal importFinished() to detect when
    * the import actually ended. Call the method finishImport() to clean
    * things up and get the overall result of the import.
    *
    * @retval true the import was started successfully
    * @retval false the import could not be started.
    */
  bool startImport(void);

  /**
    * This method must be called once the signal importFinished() has
    * been emitted. It will clean up the reader state and determines
    * the actual return code of the import.
    *
    * @retval true Import was successful.
    * @retval false Import failed because the filter program terminated
    *               abnormally or the user aborted the import process.
    */
  bool finishImport(void);

  void setCategoryMapping(bool map);

  const MyMoneyAccount& account() const { return m_account; };

  void setProgressCallback(void(*callback)(int, int, const TQString&));

private:
  /**
    * This method is used to update the progress information. It
    * checks if an appropriate function is known and calls it.
    *
    * For a parameter description see KMyMoneyView::progressCallback().
    */
  void signalProgress(int current, int total, const TQString& = "");

  /**
    * This method scans a transaction contained in
    * a QIF file formatted as an account record. This
    * format is used by MS-Money. If the specific data
    * is not found, then the data in the entry is treated
    * as a transaction. In this case, the user will be asked to
    * specify the account to which the transactions should be imported.
    * The entry data is found in m_qifEntry.
    *
    * @param accountType see MyMoneyAccount() for details. Defaults to MyMoneyAccount::Checkings
    */
  void processMSAccountEntry(const MyMoneyAccount::accountTypeE accountType = MyMoneyAccount::Checkings);

  /**
   * This method scans the m_qifEntry object as a payee record specified by Quicken
   */
  void processPayeeEntry(void);

  /**
    * This method scans the m_qifEntry object as an account record specified
    * by Quicken. In case @p resetAccountId is @p true (the default), the
    * global account id will be reset.
    *
    * The id of the account will be returned.
    */
  TQString processAccountEntry(bool resetAccountId = true);

  /**
    * This method scans the m_qifEntry object as a category record specified
    * by Quicken.
    */
  void processCategoryEntry(void);

  /**
    * This method scans the m_qifEntry object as a transaction record specified
    * by Quicken.
    */
  void processTransactionEntry(void);

  /**
    * This method scans the m_qifEntry object as an investment transaction
    * record specified by Quicken.
    */
  void processInvestmentTransactionEntry(void);

  /**
    * This method scans the m_qifEntry object as a price record specified
    * by Quicken.
    */
  void processPriceEntry(void);

  /**
    * This method scans the m_qifEntry object as a security record specified
    * by Quicken.
    */
  void processSecurityEntry(void);

  /**
    * This method processes the lines previously collected in
    * the member variable m_qifEntry. If further information
    * by the user is required to process the entry it will
    * be collected.
    */
  void processQifEntry(void);

  /**
   * This method process a line starting with an exclamation mark
   */
  void processQifSpecial(const TQString& _line);

  /**
    * This method is used to get the account id of the split for
    * a transaction from the text found in the QIF $ or L record.
    * If an account with the name is not found, the user is asked
    * if it should be created.
    *
    * @param name name of account as found in the QIF file
    * @param value value found in the T record
    * @param value2 value found in the $ record for splitted transactions
    *
    * @return id of the account for the split. If no name is specified
    *            or the account was not found and not created the
    *            return value will be "".
    */
  TQString checkCategory(const TQString& name, const MyMoneyMoney value, const MyMoneyMoney value2);

  /**
    * This method extracts the line beginning with the letter @p id
    * from the lines contained in the TQStringList object @p m_qifEntry.
    * An empty TQString is returned, if the line is not found.
    *
    * @param id TQChar containing the letter to be found
    * @param cnt return cnt'th of occurance of id in lines. cnt defaults to 1.
    *
    * @return TQString with the remainder of the line or empty if
    *         @p id is not found in @p lines
    */
  const TQString extractLine(const TQChar id, int cnt = 1);

  /**
    * This method examines each line in the TQStringList object @p m_qifEntry,
    * searching for split entries, which it extracts into a struct qSplit and
    * stores all splits found in @p listqSplits .
    */
  void extractSplits(TQValueList<qSplit>& listqSplits) const;

  enum SelectCreateMode {
    Create = 0,
    Select
  };
  /**
    * This method is used to find an account using the account's name
    * stored in @p account in the current MyMoneyFile object. If it does not
    * exist, the user has the chance to create it or to skip processing
    * of this account.
    *
    * If an account has been selected, account will be set to contain it's data.
    * If the skip operation was requested, account will be empty.
    *
    * Depending on @p mode the bahaviour of this method is slightly different.
    * The following table shows the dependencies:
    *
    * @code
    * case                              mode            operation
    * -----------------------------------------------------------------------------
    * account with same name exists     Create          returns immediately
    *                                                   m_account contains data
    *                                                   of existing account
    *
    * account does not exist            Create          immediately calls dialog
    *                                                   to create account
    *
    * account with same name exists     Select          User will be asked if
    *                                                   he wants to use the existing
    *                                                   account or create a new one
    *
    * account does not exist            Select          User will be asked to
    *                                                   select a different account
    *                                                   or create a new one
    *
    * @endcode
    *
    * @param mode Is either Create or Select depending on the above table
    * @param account Reference to MyMoneyAccount object
    */

  void selectOrCreateAccount(const SelectCreateMode mode, MyMoneyAccount& account, const MyMoneyMoney& openingBalance = MyMoneyMoney());

  /**
    * This method looks up the @p searchname account by name and returns its id
    * if it was found.  If it was not found, it creates a new income account using
    * @p searchname as a name, and returns the id if the newly created account
    *
    * @param searchname The name of the account to find or create
    * @return TQString id of the found or created account
    */
  static const TQString findOrCreateIncomeAccount(const TQString& searchname);

  /**
    * This method looks up the @p searchname account by name and returns its id
    * if it was found.  If it was not found, it creates a new expense account using
    * @p searchname as a name, and returns the id if the newly created account
    *
    * @param searchname The name of the account to find or create
    * @return TQString id of the found or created account
    */
  static const TQString findOrCreateExpenseAccount(const TQString& searchname);

  /**
   * This method returns the account id for a given account @a name. In
   * case @a name references an investment account and @a useBrokerage is @a true
   * (the default), the id of the corresponding brokerage account will be
   * returned. In case an account is not existant, it will be created.
   */
  TQString transferAccount(TQString name, bool useBrokerage = true);

  // void processQifLine(void);
  void createOpeningBalance(MyMoneyAccount::_accountTypeE accType = MyMoneyAccount::Checkings);

signals:
  /**
    * This signal will be emitted when the import is finished.
    */
  void importFinished(void);

private slots:
  void slotSendDataToFilter(void);
  void slotReceivedDataFromFilter(TDEProcess* /* proc */, char *buff, int len);
  void slotReceivedErrorFromFilter(TDEProcess* /* proc */, char *buff, int len);
  // void slotReceivedDataFromFilter(void);
  // void slotReceivedErrorFromFilter(void);
  void slotProcessData(void);

  /**
    * This slot is used to be informed about the end of the filtering process.
    * It emits the signal importFinished()
    */
  void slotImportFinished(void);


private:
  /// \internal d-pointer class.
  class Private;
  /// \internal d-pointer instance.
  Private* const d;

  TDEProcess                m_filter;
  TQString                 m_filename;
  KURL                    m_url;
  MyMoneyQifProfile       m_qifProfile;
  MyMoneyAccount          m_account;
  unsigned long           m_transactionsSkipped;
  unsigned long           m_transactionsProcessed;
  TQStringList             m_dontAskAgain;
  TQMap<TQString, TQString>  m_accountTranslation;
  TQMap<TQString, TQString>  m_investmentMap;
  TQFile                   *m_file;
  char                    m_buffer[1024];
  TQCString                m_lineBuffer;
  TQStringList             m_qifEntry;
  int                     m_extractedLine;
  TQString                 m_qifLine;
  TQStringList             m_qifLines;
  QifEntryTypeE           m_entryType;
  bool                    m_skipAccount;
  bool                    m_processingData;
  bool                    m_userAbort;
  bool                    m_autoCreatePayee;
  unsigned long           m_pos;
  unsigned                m_linenumber;
  bool                    m_warnedInvestment;
  bool                    m_warnedSecurity;
  bool                    m_warnedPrice;
  TQValueList<MyMoneyTransaction> m_transactionCache;

  TQValueList<TQByteArray>  m_data;

  void (*m_progressCallback)(int, int, const TQString&);

  MyMoneyFileTransaction* m_ft;
};

#endif