LibOFX
ofx_container_transaction.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  ofx_container_account.cpp
3  -------------------
4  copyright : (C) 2002 by Benoit Gr�goire
5  email : benoitg@coeus.ca
6 ***************************************************************************/
11 /***************************************************************************
12  * *
13  * This program is free software; you can redistribute it and/or modify *
14  * it under the terms of the GNU General Public License as published by *
15  * the Free Software Foundation; either version 2 of the License, or *
16  * (at your option) any later version. *
17  * *
18  ***************************************************************************/
19 
20 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23 
24 #include <cstdlib>
25 #include <string>
26 #include "messages.hh"
27 #include "libofx.h"
28 #include "ofx_containers.hh"
29 #include "ofx_utilities.hh"
30 
31 extern OfxMainContainer * MainContainer;
32 
33 /***************************************************************************
34  * OfxTransactionContainer *
35  ***************************************************************************/
36 
37 OfxTransactionContainer::OfxTransactionContainer(LibofxContext *p_libofx_context, OfxGenericContainer *para_parentcontainer, string para_tag_identifier):
38  OfxGenericContainer(p_libofx_context, para_parentcontainer, para_tag_identifier)
39 {
40  OfxGenericContainer * tmp_parentcontainer = parentcontainer;
41 
42  memset(&data, 0, sizeof(data));
43  type = "TRANSACTION";
44  /* Find the parent statement container*/
45  while (tmp_parentcontainer != NULL && tmp_parentcontainer->type != "STATEMENT")
46  {
47  tmp_parentcontainer = tmp_parentcontainer->parentcontainer;
48  }
49  if (tmp_parentcontainer != NULL)
50  {
51  parent_statement = (OfxStatementContainer*)tmp_parentcontainer;
52  }
53  else
54  {
55  parent_statement = NULL;
56  message_out(ERROR, "Unable to find the enclosing statement container this transaction");
57  }
58  if (parent_statement != NULL && parent_statement->data.account_id_valid == true)
59  {
60  strncpy(data.account_id, parent_statement->data.account_id, OFX_ACCOUNT_ID_LENGTH);
61  data.account_id_valid = true;
62  }
63 }
64 OfxTransactionContainer::~OfxTransactionContainer()
65 {
66 
67 }
68 
70 {
71  if (data.unique_id_valid == true && MainContainer != NULL)
72  {
73  data.security_data_ptr = MainContainer->find_security(data.unique_id);
74  if (data.security_data_ptr != NULL)
75  {
76  data.security_data_valid = true;
77  }
78  }
79  libofx_context->transactionCallback(data);
80  return true;
81 }
82 
84 {
85 
86  if (MainContainer != NULL)
87  {
88  return MainContainer->add_container(this);
89  }
90  else
91  {
92  return false;
93  }
94 }
95 
96 
97 void OfxTransactionContainer::add_attribute(const string identifier, const string value)
98 {
99 
100  if (identifier == "DTPOSTED")
101  {
102  data.date_posted = ofxdate_to_time_t(value);
103  data.date_posted_valid = true;
104  }
105  else if (identifier == "DTUSER")
106  {
107  data.date_initiated = ofxdate_to_time_t(value);
108  data.date_initiated_valid = true;
109  }
110  else if (identifier == "DTAVAIL")
111  {
113  data.date_funds_available_valid = true;
114  }
115  else if (identifier == "FITID")
116  {
117  strncpy(data.fi_id, value.c_str(), sizeof(data.fi_id));
118  data.fi_id_valid = true;
119  }
120  else if (identifier == "CORRECTFITID")
121  {
122  strncpy(data.fi_id_corrected, value.c_str(), sizeof(data.fi_id));
123  data.fi_id_corrected_valid = true;
124  }
125  else if (identifier == "CORRECTACTION")
126  {
127  data.fi_id_correction_action_valid = true;
128  if (value == "REPLACE")
129  {
131  }
132  else if (value == "DELETE")
133  {
135  }
136  else
137  {
138  data.fi_id_correction_action_valid = false;
139  }
140  }
141  else if ((identifier == "SRVRTID") || (identifier == "SRVRTID2"))
142  {
143  strncpy(data.server_transaction_id, value.c_str(), sizeof(data.server_transaction_id));
144  data.server_transaction_id_valid = true;
145  }
146  else if (identifier == "MEMO" || identifier == "MEMO2")
147  {
148  strncpy(data.memo, value.c_str(), sizeof(data.memo));
149  data.memo_valid = true;
150  }
151  else
152  {
153  /* Redirect unknown identifiers to the base class */
154  OfxGenericContainer::add_attribute(identifier, value);
155  }
156 }// end OfxTransactionContainer::add_attribute()
157 
158 void OfxTransactionContainer::add_account(OfxAccountData * account_data)
159 {
160  if (account_data->account_id_valid == true)
161  {
162  data.account_ptr = account_data;
163  strncpy(data.account_id, account_data->account_id, OFX_ACCOUNT_ID_LENGTH);
164  data.account_id_valid = true;
165  }
166 }
167 
168 /***************************************************************************
169  * OfxBankTransactionContainer *
170  ***************************************************************************/
171 
172 OfxBankTransactionContainer::OfxBankTransactionContainer(LibofxContext *p_libofx_context, OfxGenericContainer *para_parentcontainer, string para_tag_identifier):
173  OfxTransactionContainer(p_libofx_context, para_parentcontainer, para_tag_identifier)
174 {
175  ;
176 }
177 void OfxBankTransactionContainer::add_attribute(const string identifier, const string value)
178 {
179  if ( identifier == "TRNTYPE")
180  {
181  data.transactiontype_valid = true;
182  if (value == "CREDIT")
183  {
184  data.transactiontype = OFX_CREDIT;
185  }
186  else if (value == "DEBIT")
187  {
188  data.transactiontype = OFX_DEBIT;
189  }
190  else if (value == "INT")
191  {
192  data.transactiontype = OFX_INT;
193  }
194  else if (value == "DIV")
195  {
196  data.transactiontype = OFX_DIV;
197  }
198  else if (value == "FEE")
199  {
200  data.transactiontype = OFX_FEE;
201  }
202  else if (value == "SRVCHG")
203  {
204  data.transactiontype = OFX_SRVCHG;
205  }
206  else if (value == "DEP")
207  {
208  data.transactiontype = OFX_DEP;
209  }
210  else if (value == "ATM")
211  {
212  data.transactiontype = OFX_ATM;
213  }
214  else if (value == "POS")
215  {
216  data.transactiontype = OFX_POS;
217  }
218  else if (value == "XFER")
219  {
220  data.transactiontype = OFX_XFER;
221  }
222  else if (value == "CHECK")
223  {
224  data.transactiontype = OFX_CHECK;
225  }
226  else if (value == "PAYMENT")
227  {
228  data.transactiontype = OFX_PAYMENT;
229  }
230  else if (value == "CASH")
231  {
232  data.transactiontype = OFX_CASH;
233  }
234  else if (value == "DIRECTDEP")
235  {
236  data.transactiontype = OFX_DIRECTDEP;
237  }
238  else if (value == "DIRECTDEBIT")
239  {
240  data.transactiontype = OFX_DIRECTDEBIT;
241  }
242  else if (value == "REPEATPMT")
243  {
244  data.transactiontype = OFX_REPEATPMT;
245  }
246  else if (value == "OTHER")
247  {
248  data.transactiontype = OFX_OTHER;
249  }
250  else
251  {
252  data.transactiontype_valid = false;
253  }
254  }//end TRANSTYPE
255  else if (identifier == "TRNAMT")
256  {
257  data.amount = ofxamount_to_double(value);
258  data.amount_valid = true;
259  data.units = -data.amount;
260  data.units_valid = true;
261  data.unitprice = 1.00;
262  data.unitprice_valid = true;
263  }
264  else if (identifier == "CHECKNUM")
265  {
266  strncpy(data.check_number, value.c_str(), sizeof(data.check_number));
267  data.check_number_valid = true;
268  }
269  else if (identifier == "REFNUM")
270  {
271  strncpy(data.reference_number, value.c_str(), sizeof(data.reference_number));
272  data.reference_number_valid = true;
273  }
274  else if (identifier == "SIC")
275  {
276  data.standard_industrial_code = atoi(value.c_str());
277  data.standard_industrial_code_valid = true;
278  }
279  else if ((identifier == "PAYEEID") || (identifier == "PAYEEID2"))
280  {
281  strncpy(data.payee_id, value.c_str(), sizeof(data.payee_id));
282  data.payee_id_valid = true;
283  }
284  else if (identifier == "NAME")
285  {
286  strncpy(data.name, value.c_str(), sizeof(data.name));
287  data.name_valid = true;
288  }
289  else
290  {
291  /* Redirect unknown identifiers to base class */
292  OfxTransactionContainer::add_attribute(identifier, value);
293  }
294 }//end OfxBankTransactionContainer::add_attribute
295 
296 
297 /***************************************************************************
298  * OfxInvestmentTransactionContainer *
299  ***************************************************************************/
300 
301 OfxInvestmentTransactionContainer::OfxInvestmentTransactionContainer(LibofxContext *p_libofx_context, OfxGenericContainer *para_parentcontainer, string para_tag_identifier):
302  OfxTransactionContainer(p_libofx_context, para_parentcontainer, para_tag_identifier)
303 {
304  type = "INVESTMENT";
305  data.transactiontype = OFX_OTHER;
306  data.transactiontype_valid = true;
307 
308  data.invtransactiontype_valid = true;
309  if (para_tag_identifier == "BUYDEBT")
310  {
311  data.invtransactiontype = OFX_BUYDEBT;
312  }
313  else if (para_tag_identifier == "BUYMF")
314  {
315  data.invtransactiontype = OFX_BUYMF;
316  }
317  else if (para_tag_identifier == "BUYOPT")
318  {
319  data.invtransactiontype = OFX_BUYOPT;
320  }
321  else if (para_tag_identifier == "BUYOTHER")
322  {
323  data.invtransactiontype = OFX_BUYOTHER;
324  }
325  else if (para_tag_identifier == "BUYSTOCK")
326  {
327  data.invtransactiontype = OFX_BUYSTOCK;
328  }
329  else if (para_tag_identifier == "CLOSUREOPT")
330  {
331  data.invtransactiontype = OFX_CLOSUREOPT;
332  }
333  else if (para_tag_identifier == "INCOME")
334  {
335  data.invtransactiontype = OFX_INCOME;
336  }
337  else if (para_tag_identifier == "INVEXPENSE")
338  {
339  data.invtransactiontype = OFX_INVEXPENSE;
340  }
341  else if (para_tag_identifier == "JRNLFUND")
342  {
343  data.invtransactiontype = OFX_JRNLFUND;
344  }
345  else if (para_tag_identifier == "JRNLSEC")
346  {
347  data.invtransactiontype = OFX_JRNLSEC;
348  }
349  else if (para_tag_identifier == "MARGININTEREST")
350  {
351  data.invtransactiontype = OFX_MARGININTEREST;
352  }
353  else if (para_tag_identifier == "REINVEST")
354  {
355  data.invtransactiontype = OFX_REINVEST;
356  }
357  else if (para_tag_identifier == "RETOFCAP")
358  {
359  data.invtransactiontype = OFX_RETOFCAP;
360  }
361  else if (para_tag_identifier == "SELLDEBT")
362  {
363  data.invtransactiontype = OFX_SELLDEBT;
364  }
365  else if (para_tag_identifier == "SELLMF")
366  {
367  data.invtransactiontype = OFX_SELLMF;
368  }
369  else if (para_tag_identifier == "SELLOPT")
370  {
371  data.invtransactiontype = OFX_SELLOPT;
372  }
373  else if (para_tag_identifier == "SELLOTHER")
374  {
375  data.invtransactiontype = OFX_SELLOTHER;
376  }
377  else if (para_tag_identifier == "SELLSTOCK")
378  {
379  data.invtransactiontype = OFX_SELLSTOCK;
380  }
381  else if (para_tag_identifier == "SPLIT")
382  {
383  data.invtransactiontype = OFX_SPLIT;
384  }
385  else if (para_tag_identifier == "TRANSFER")
386  {
387  data.invtransactiontype = OFX_TRANSFER;
388  }
389  else
390  {
391  message_out(ERROR, "This should not happen, " + para_tag_identifier + " is an unknown investment transaction type");
392  data.invtransactiontype_valid = false;
393  }
394 }
395 
396 void OfxInvestmentTransactionContainer::add_attribute(const string identifier, const string value)
397 {
398  if (identifier == "UNIQUEID")
399  {
400  strncpy(data.unique_id, value.c_str(), sizeof(data.unique_id));
401  data.unique_id_valid = true;
402  }
403  else if (identifier == "UNIQUEIDTYPE")
404  {
405  strncpy(data.unique_id_type, value.c_str(), sizeof(data.unique_id_type));
406  data.unique_id_type_valid = true;
407  }
408  else if (identifier == "UNITS")
409  {
410  data.units = ofxamount_to_double(value);
411  data.units_valid = true;
412  }
413  else if (identifier == "UNITPRICE")
414  {
415  data.unitprice = ofxamount_to_double(value);
416  data.unitprice_valid = true;
417  }
418  else if (identifier == "MKTVAL")
419  {
420  message_out(DEBUG, "MKTVAL of " + value + " ignored since MKTVAL should always be UNITS*UNITPRICE");
421  }
422  else if (identifier == "TOTAL")
423  {
424  data.amount = ofxamount_to_double(value);
425  data.amount_valid = true;
426  }
427  else if (identifier == "DTSETTLE")
428  {
429  data.date_posted = ofxdate_to_time_t(value);
430  data.date_posted_valid = true;
431  }
432  else if (identifier == "DTTRADE")
433  {
434  data.date_initiated = ofxdate_to_time_t(value);
435  data.date_initiated_valid = true;
436  }
437  else if (identifier == "COMMISSION")
438  {
439  data.commission = ofxamount_to_double(value);
440  data.commission_valid = true;
441  }
442  else if (identifier == "FEES")
443  {
444  data.fees = ofxamount_to_double(value);
445  data.fees_valid = true;
446  }
447  else if (identifier == "OLDUNITS")
448  {
449  data.oldunits = ofxamount_to_double(value);
450  data.oldunits_valid = true;
451  }
452  else if (identifier == "NEWUNITS")
453  {
454  data.newunits = ofxamount_to_double(value);
455  data.newunits_valid = true;
456  }
457  else
458  {
459  /* Redirect unknown identifiers to the base class */
460  OfxTransactionContainer::add_attribute(identifier, value);
461  }
462 }//end OfxInvestmentTransactionContainer::add_attribute
463 
An abstraction of an account.
Definition: inc/libofx.h:271
virtual int add_to_main_tree()
Add this container to the main tree.
char reference_number[OFX_REFERENCE_NUMBER_LENGTH]
Definition: inc/libofx.h:584
A generic container for an OFX SGML element. Every container inherits from OfxGenericContainer.
char unique_id[OFX_UNIQUE_ID_LENGTH]
Definition: inc/libofx.h:531
char account_id[OFX_ACCOUNT_ID_LENGTH]
Definition: inc/libofx.h:285
Represents a generic transaction.
char fi_id_corrected[256]
Definition: inc/libofx.h:563
char check_number[OFX_CHECK_NUMBER_LENGTH]
Definition: inc/libofx.h:579
virtual void add_attribute(const string identifier, const string value)
Add data to a container object.
char name[OFX_TRANSACTION_NAME_LENGTH]
Definition: inc/libofx.h:594
char memo[OFX_MEMO2_LENGTH]
Definition: inc/libofx.h:598
FiIdCorrectionAction fi_id_correction_action
Definition: inc/libofx.h:568
virtual void add_attribute(const string identifier, const string value)
Add data to a container object.
long int standard_industrial_code
Definition: inc/libofx.h:587
char account_id[OFX_ACCOUNT_ID_LENGTH]
Definition: inc/libofx.h:650
int message_out(OfxMsgType error_type, const string message)
Message output function.
Definition: messages.cpp:60
char account_id[OFX_ACCOUNT_ID_LENGTH]
Definition: inc/libofx.h:483
void add_attribute(const string identifier, const string value)
Add data to a container object.
time_t ofxdate_to_time_t(const string ofxdate)
Convert a C++ string containing a time in OFX format to a C time_t.
double ofxamount_to_double(const string ofxamount)
Convert OFX amount of money to double float.
struct OfxAccountData * account_ptr
Definition: inc/libofx.h:486
char server_transaction_id[OFX_SVRTID2_LENGTH]
Definition: inc/libofx.h:573
void add_attribute(const string identifier, const string value)
Add data to a container object.
Various simple functions for type conversion & al.
Represents a statement for either a bank account or a credit card account.
char payee_id[OFX_SVRTID2_LENGTH]
Definition: inc/libofx.h:591
LibOFX internal object code.
time_t date_funds_available
Definition: inc/libofx.h:555
Message IO functionality.
char unique_id_type[OFX_UNIQUE_ID_TYPE_LENGTH]
Definition: inc/libofx.h:533
The root container. Created by the <OFX> OFX element or by the export functions.
virtual int gen_event()
Generate libofx.h events.