00001
00002
00003
00004
00005
00006
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <iostream>
00031 #include <iomanip>
00032 #include <string>
00033 #include "libofx.h"
00034 #include <stdio.h>
00035 #include <config.h>
00036 #include <errno.h>
00037
00038 #include "cmdline.h"
00039
00040 using namespace std;
00041
00042
00043 int ofx_proc_security_cb(struct OfxSecurityData data, void * security_data)
00044 {
00045 char dest_string[255];
00046 cout<<"ofx_proc_security():\n";
00047 if(data.unique_id_valid==true){
00048 cout<<" Unique ID of the security being traded: "<<data.unique_id<<"\n";
00049 }
00050 if(data.unique_id_type_valid==true){
00051 cout<<" Format of the Unique ID: "<<data.unique_id_type<<"\n";
00052 }
00053 if(data.secname_valid==true){
00054 cout<<" Name of the security: "<<data.secname<<"\n";
00055 }
00056 if(data.ticker_valid==true){
00057 cout<<" Ticker symbol: "<<data.ticker<<"\n";
00058 }
00059 if(data.unitprice_valid==true){
00060 cout<<" Price of each unit of the security: "<<data.unitprice<<"\n";
00061 }
00062 if(data.date_unitprice_valid==true){
00063 strftime(dest_string,sizeof(dest_string),"%c %Z",localtime(&(data.date_unitprice)));
00064 cout<<" Date as of which the unitprice is valid: "<<dest_string<<"\n";
00065 }
00066 if(data.currency_valid==true){
00067 cout<<" Currency of the unitprice: "<<data.currency<<"\n";
00068 }
00069 if(data.memo_valid==true){
00070 cout<<" Extra transaction information (memo): "<<data.memo<<"\n";
00071 }
00072 cout<<"\n";
00073 return 0;
00074 }
00075
00076 int ofx_proc_transaction_cb(struct OfxTransactionData data, void * transaction_data)
00077 {
00078 char dest_string[255];
00079 cout<<"ofx_proc_transaction():\n";
00080
00081 if(data.account_id_valid==true){
00082 cout<<" Account ID : "<<data.account_id<<"\n";
00083 }
00084
00085 if(data.transactiontype_valid==true)
00086 {
00087 if(data.transactiontype==OFX_CREDIT)
00088 strncpy(dest_string, "CREDIT: Generic credit", sizeof(dest_string));
00089 else if (data.transactiontype==OFX_DEBIT)
00090 strncpy(dest_string, "DEBIT: Generic debit", sizeof(dest_string));
00091 else if (data.transactiontype==OFX_INT)
00092 strncpy(dest_string, "INT: Interest earned or paid (Note: Depends on signage of amount)", sizeof(dest_string));
00093 else if (data.transactiontype==OFX_DIV)
00094 strncpy(dest_string, "DIV: Dividend", sizeof(dest_string));
00095 else if (data.transactiontype==OFX_FEE)
00096 strncpy(dest_string, "FEE: FI fee", sizeof(dest_string));
00097 else if (data.transactiontype==OFX_SRVCHG)
00098 strncpy(dest_string, "SRVCHG: Service charge", sizeof(dest_string));
00099 else if (data.transactiontype==OFX_DEP)
00100 strncpy(dest_string, "DEP: Deposit", sizeof(dest_string));
00101 else if (data.transactiontype==OFX_ATM)
00102 strncpy(dest_string, "ATM: ATM debit or credit (Note: Depends on signage of amount)", sizeof(dest_string));
00103 else if (data.transactiontype==OFX_POS)
00104 strncpy(dest_string, "POS: Point of sale debit or credit (Note: Depends on signage of amount)", sizeof(dest_string));
00105 else if (data.transactiontype==OFX_XFER)
00106 strncpy(dest_string, "XFER: Transfer", sizeof(dest_string));
00107 else if (data.transactiontype==OFX_CHECK)
00108 strncpy(dest_string, "CHECK: Check", sizeof(dest_string));
00109 else if (data.transactiontype==OFX_PAYMENT)
00110 strncpy(dest_string, "PAYMENT: Electronic payment", sizeof(dest_string));
00111 else if (data.transactiontype==OFX_CASH)
00112 strncpy(dest_string, "CASH: Cash withdrawal", sizeof(dest_string));
00113 else if (data.transactiontype==OFX_DIRECTDEP)
00114 strncpy(dest_string, "DIRECTDEP: Direct deposit", sizeof(dest_string));
00115 else if (data.transactiontype==OFX_DIRECTDEBIT)
00116 strncpy(dest_string, "DIRECTDEBIT: Merchant initiated debit", sizeof(dest_string));
00117 else if (data.transactiontype==OFX_REPEATPMT)
00118 strncpy(dest_string, "REPEATPMT: Repeating payment/standing order", sizeof(dest_string));
00119 else if (data.transactiontype==OFX_OTHER)
00120 strncpy(dest_string, "OTHER: Other", sizeof(dest_string));
00121 else
00122 strncpy(dest_string, "Unknown transaction type", sizeof(dest_string));
00123 cout<<" Transaction type: "<<dest_string<<"\n";
00124 }
00125
00126
00127 if(data.date_initiated_valid==true){
00128 strftime(dest_string,sizeof(dest_string),"%c %Z",localtime(&(data.date_initiated)));
00129 cout<<" Date initiated: "<<dest_string<<"\n";
00130 }
00131 if(data.date_posted_valid==true){
00132 strftime(dest_string,sizeof(dest_string),"%c %Z",localtime(&(data.date_posted)));
00133 cout<<" Date posted: "<<dest_string<<"\n";
00134 }
00135 if(data.date_funds_available_valid==true){
00136 strftime(dest_string,sizeof(dest_string),"%c %Z",localtime(&(data.date_funds_available)));
00137 cout<<" Date funds are available: "<<dest_string<<"\n";
00138 }
00139 if(data.amount_valid==true){
00140 cout<<" Total money amount: "<<setiosflags(ios::fixed)<<setiosflags(ios::showpoint)<<setprecision(2)<<data.amount<<"\n";
00141 }
00142 if(data.units_valid==true){
00143 cout<<" # of units: "<<setiosflags(ios::fixed)<<setiosflags(ios::showpoint)<<setprecision(2)<<data.units<<"\n";
00144 }
00145 if(data.oldunits_valid==true){
00146 cout<<" # of units before split: "<<setiosflags(ios::fixed)<<setiosflags(ios::showpoint)<<setprecision(2)<<data.oldunits<<"\n";
00147 }
00148 if(data.newunits_valid==true){
00149 cout<<" # of units after split: "<<setiosflags(ios::fixed)<<setiosflags(ios::showpoint)<<setprecision(2)<<data.newunits<<"\n";
00150 }
00151 if(data.unitprice_valid==true){
00152 cout<<" Unit price: "<<setiosflags(ios::fixed)<<setiosflags(ios::showpoint)<<setprecision(2)<<data.unitprice<<"\n";
00153 }
00154 if(data.fees_valid==true){
00155 cout<<" Fees: "<<setiosflags(ios::fixed)<<setiosflags(ios::showpoint)<<setprecision(2)<<data.fees<<"\n";
00156 }
00157 if(data.commission_valid==true){
00158 cout<<" Commission: "<<setiosflags(ios::fixed)<<setiosflags(ios::showpoint)<<setprecision(2)<<data.commission<<"\n";
00159 }
00160 if(data.fi_id_valid==true){
00161 cout<<" Financial institution's ID for this transaction: "<<data.fi_id<<"\n";
00162 }
00163 if(data.fi_id_corrected_valid==true){
00164 cout<<" Financial institution ID replaced or corrected by this transaction: "<<data.fi_id_corrected<<"\n";
00165 }
00166 if(data.fi_id_correction_action_valid==true){
00167 cout<<" Action to take on the corrected transaction: ";
00168 if (data.fi_id_correction_action==DELETE)
00169 cout<<"DELETE\n";
00170 else if (data.fi_id_correction_action==REPLACE)
00171 cout<<"REPLACE\n";
00172 else
00173 cout<<"ofx_proc_transaction(): This should not happen!\n";
00174 }
00175 if(data.invtransactiontype_valid==true){
00176 cout<<" Investment transaction type: ";
00177 if (data.invtransactiontype==OFX_BUYDEBT)
00178 strncpy(dest_string, "BUYDEBT (Buy debt security)", sizeof(dest_string));
00179 else if (data.invtransactiontype==OFX_BUYMF)
00180 strncpy(dest_string, "BUYMF (Buy mutual fund)", sizeof(dest_string));
00181 else if (data.invtransactiontype==OFX_BUYOPT)
00182 strncpy(dest_string, "BUYOPT (Buy option)", sizeof(dest_string));
00183 else if (data.invtransactiontype==OFX_BUYOTHER)
00184 strncpy(dest_string, "BUYOTHER (Buy other security type)", sizeof(dest_string));
00185 else if (data.invtransactiontype==OFX_BUYSTOCK)
00186 strncpy(dest_string, "BUYSTOCK (Buy stock))", sizeof(dest_string));
00187 else if (data.invtransactiontype==OFX_CLOSUREOPT)
00188 strncpy(dest_string, "CLOSUREOPT (Close a position for an option)", sizeof(dest_string));
00189 else if (data.invtransactiontype==OFX_INCOME)
00190 strncpy(dest_string, "INCOME (Investment income is realized as cash into the investment account)", sizeof(dest_string));
00191 else if (data.invtransactiontype==OFX_INVEXPENSE)
00192 strncpy(dest_string, "INVEXPENSE (Misc investment expense that is associated with a specific security)", sizeof(dest_string));
00193 else if (data.invtransactiontype==OFX_JRNLFUND)
00194 strncpy(dest_string, "JRNLFUND (Journaling cash holdings between subaccounts within the same investment account)", sizeof(dest_string));
00195 else if (data.invtransactiontype==OFX_MARGININTEREST)
00196 strncpy(dest_string, "MARGININTEREST (Margin interest expense)", sizeof(dest_string));
00197 else if (data.invtransactiontype==OFX_REINVEST)
00198 strncpy(dest_string, "REINVEST (Reinvestment of income)", sizeof(dest_string));
00199 else if (data.invtransactiontype==OFX_RETOFCAP)
00200 strncpy(dest_string, "RETOFCAP (Return of capital)", sizeof(dest_string));
00201 else if (data.invtransactiontype==OFX_SELLDEBT)
00202 strncpy(dest_string, "SELLDEBT (Sell debt security. Used when debt is sold, called, or reached maturity)", sizeof(dest_string));
00203 else if (data.invtransactiontype==OFX_SELLMF)
00204 strncpy(dest_string, "SELLMF (Sell mutual fund)", sizeof(dest_string));
00205 else if (data.invtransactiontype==OFX_SELLOPT)
00206 strncpy(dest_string, "SELLOPT (Sell option)", sizeof(dest_string));
00207 else if (data.invtransactiontype==OFX_SELLOTHER)
00208 strncpy(dest_string, "SELLOTHER (Sell other type of security)", sizeof(dest_string));
00209 else if (data.invtransactiontype==OFX_SELLSTOCK)
00210 strncpy(dest_string, "SELLSTOCK (Sell stock)", sizeof(dest_string));
00211 else if (data.invtransactiontype==OFX_SPLIT)
00212 strncpy(dest_string, "SPLIT (Stock or mutial fund split)", sizeof(dest_string));
00213 else if (data.invtransactiontype==OFX_TRANSFER)
00214 strncpy(dest_string, "TRANSFER (Transfer holdings in and out of the investment account)", sizeof(dest_string));
00215 else
00216 strncpy(dest_string, "ERROR, this investment transaction type is unknown. This is a bug in ofxdump", sizeof(dest_string));
00217
00218 cout<<dest_string<<"\n";
00219 }
00220 if(data.unique_id_valid==true){
00221 cout<<" Unique ID of the security being traded: "<<data.unique_id<<"\n";
00222 }
00223 if(data.unique_id_type_valid==true){
00224 cout<<" Format of the Unique ID: "<<data.unique_id_type<<"\n";
00225 }
00226 if(data.security_data_valid==true){
00227 ofx_proc_security_cb(*(data.security_data_ptr), NULL );
00228 }
00229
00230 if(data.server_transaction_id_valid==true){
00231 cout<<" Server's transaction ID (confirmation number): "<<data.server_transaction_id<<"\n";
00232 }
00233 if(data.check_number_valid==true){
00234 cout<<" Check number: "<<data.check_number<<"\n";
00235 }
00236 if(data.reference_number_valid==true){
00237 cout<<" Reference number: "<<data.reference_number<<"\n";
00238 }
00239 if(data.standard_industrial_code_valid==true){
00240 cout<<" Standard Industrial Code: "<<data.standard_industrial_code<<"\n";
00241 }
00242 if(data.payee_id_valid==true){
00243 cout<<" Payee_id: "<<data.payee_id<<"\n";
00244 }
00245 if(data.name_valid==true){
00246 cout<<" Name of payee or transaction description: "<<data.name<<"\n";
00247 }
00248 if(data.memo_valid==true){
00249 cout<<" Extra transaction information (memo): "<<data.memo<<"\n";
00250 }
00251 cout<<"\n";
00252 return 0;
00253 }
00254
00255 int ofx_proc_statement_cb(struct OfxStatementData data, void * statement_data)
00256 {
00257 char dest_string[255];
00258 cout<<"ofx_proc_statement():\n";
00259 if(data.currency_valid==true){
00260 cout<<" Currency: "<<data.currency<<"\n";
00261 }
00262 if(data.account_id_valid==true){
00263 cout<<" Account ID: "<<data.account_id<<"\n";
00264 }
00265 if(data.date_start_valid==true){
00266 strftime(dest_string,sizeof(dest_string),"%c %Z",localtime(&(data.date_start)));
00267 cout<<" Start date of this statement: "<<dest_string<<"\n";
00268 }
00269 if(data.date_end_valid==true){
00270 strftime(dest_string,sizeof(dest_string),"%c %Z",localtime(&(data.date_end)));
00271 cout<<" End date of this statement: "<<dest_string<<"\n";
00272 }
00273 if(data.ledger_balance_valid==true){
00274 cout<<" Ledger balance: "<<setiosflags(ios::fixed)<<setiosflags(ios::showpoint)<<setprecision(2)<<data.ledger_balance<<"\n";
00275 }
00276 if(data.ledger_balance_date_valid==true){
00277 strftime(dest_string,sizeof(dest_string),"%c %Z",localtime(&(data.ledger_balance_date)));
00278 cout<<" Ledger balance date: "<<dest_string<<"\n";
00279 }
00280 if(data.available_balance_valid==true){
00281 cout<<" Available balance: "<<setiosflags(ios::fixed)<<setiosflags(ios::showpoint)<<setprecision(2)<<data.available_balance<<"\n";
00282 }
00283 if(data.available_balance_date_valid==true){
00284 strftime(dest_string,sizeof(dest_string),"%c %Z",localtime(&(data.available_balance_date)));
00285 cout<<" Ledger balance date: "<<dest_string<<"\n";
00286 }
00287 if(data.marketing_info_valid==true){
00288 cout<<" Marketing information: "<<data.marketing_info<<"\n";
00289 }
00290 cout<<"\n";
00291 return 0;
00292 }
00293
00294 int ofx_proc_account_cb(struct OfxAccountData data, void * account_data)
00295 {
00296 cout<<"ofx_proc_account():\n";
00297 if(data.account_id_valid==true){
00298 cout<<" Account ID: "<<data.account_id<<"\n";
00299 cout<<" Account name: "<<data.account_name<<"\n";
00300 }
00301 if(data.account_type_valid==true){
00302 cout<<" Account type: ";
00303 switch(data.account_type){
00304 case OfxAccountData::OFX_CHECKING : cout<<"CHECKING\n";
00305 break;
00306 case OfxAccountData::OFX_SAVINGS : cout<<"SAVINGS\n";
00307 break;
00308 case OfxAccountData::OFX_MONEYMRKT : cout<<"MONEYMRKT\n";
00309 break;
00310 case OfxAccountData::OFX_CREDITLINE : cout<<"CREDITLINE\n";
00311 break;
00312 case OfxAccountData::OFX_CMA : cout<<"CMA\n";
00313 break;
00314 case OfxAccountData::OFX_CREDITCARD : cout<<"CREDITCARD\n";
00315 break;
00316 case OfxAccountData::OFX_INVESTMENT : cout<<"INVESTMENT\n";
00317 break;
00318 default: cout<<"ofx_proc_account() WRITEME: This is an unknown account type!";
00319 }
00320 }
00321 if(data.currency_valid==true){
00322 cout<<" Currency: "<<data.currency<<"\n";
00323 }
00324
00325 if (data.bank_id_valid)
00326 cout<<" Bank ID: "<<data.bank_id << endl;;
00327
00328 if (data.branch_id_valid)
00329 cout<<" Branch ID: "<<data.branch_id << endl;
00330
00331 if (data.account_number_valid)
00332 cout<<" Account #: "<<data.account_number << endl;
00333
00334 cout<<"\n";
00335 return 0;
00336 }
00337
00338
00339
00340 int ofx_proc_status_cb(struct OfxStatusData data, void * status_data)
00341 {
00342 cout<<"ofx_proc_status():\n";
00343 if(data.ofx_element_name_valid==true){
00344 cout<<" Ofx entity this status is relevent to: "<< data.ofx_element_name<<" \n";
00345 }
00346 if(data.severity_valid==true){
00347 cout<<" Severity: ";
00348 switch(data.severity){
00349 case OfxStatusData::INFO : cout<<"INFO\n";
00350 break;
00351 case OfxStatusData::WARN : cout<<"WARN\n";
00352 break;
00353 case OfxStatusData::ERROR : cout<<"ERROR\n";
00354 break;
00355 default: cout<<"WRITEME: Unknown status severity!\n";
00356 }
00357 }
00358 if(data.code_valid==true){
00359 cout<<" Code: "<<data.code<<", name: "<<data.name<<"\n Description: "<<data.description<<"\n";
00360 }
00361 if(data.server_message_valid==true){
00362 cout<<" Server Message: "<<data.server_message<<"\n";
00363 }
00364 cout<<"\n";
00365 return 0;
00366 }
00367
00368
00369 int main (int argc, char *argv[])
00370 {
00372 extern int ofx_PARSER_msg;
00373 extern int ofx_DEBUG_msg;
00374 extern int ofx_WARNING_msg;
00375 extern int ofx_ERROR_msg;
00376 extern int ofx_INFO_msg;
00377 extern int ofx_STATUS_msg;
00378
00379 gengetopt_args_info args_info;
00380
00381
00382 if (cmdline_parser (argc, argv, &args_info) != 0)
00383 exit(1) ;
00384
00385
00386
00387
00388
00389
00390 args_info.msg_parser_flag ? ofx_PARSER_msg = true : ofx_PARSER_msg = false;
00391 args_info.msg_debug_flag ? ofx_DEBUG_msg = true : ofx_DEBUG_msg = false;
00392 args_info.msg_warning_flag ? ofx_WARNING_msg = true : ofx_WARNING_msg = false;
00393 args_info.msg_error_flag ? ofx_ERROR_msg = true : ofx_ERROR_msg = false;
00394 args_info.msg_info_flag ? ofx_INFO_msg = true : ofx_INFO_msg = false;
00395 args_info.msg_status_flag ? ofx_STATUS_msg = true : ofx_STATUS_msg;
00396
00397 bool skiphelp = false;
00398
00399 if(args_info.list_import_formats_given)
00400 {
00401 skiphelp = true;
00402 cout <<"The supported file formats for the 'input-file-format' argument are:"<<endl;
00403 for(int i=0; LibofxImportFormatList[i].format!=LAST; i++)
00404 {
00405 cout <<" "<<LibofxImportFormatList[i].description<<endl;
00406 }
00407 }
00408
00409 LibofxContextPtr libofx_context = libofx_get_new_context();
00410
00411
00412
00413 if (args_info.inputs_num > 0)
00414 {
00415 const char* filename = args_info.inputs[0];
00416
00417
00418 ofx_set_statement_cb(libofx_context, ofx_proc_statement_cb, 0);
00419 ofx_set_account_cb(libofx_context, ofx_proc_account_cb, 0);
00420 ofx_set_transaction_cb(libofx_context, ofx_proc_transaction_cb, 0);
00421 ofx_set_security_cb(libofx_context, ofx_proc_security_cb, 0);
00422 ofx_set_status_cb(libofx_context, ofx_proc_status_cb, 0);
00423
00424 enum LibofxFileFormat file_format = libofx_get_file_format_from_str(LibofxImportFormatList, args_info.import_format_arg);
00426 if(args_info.inputs_num > 1)
00427 {
00428 cout << "Sorry, currently, only the first file is processed as the library can't deal with more right now. The following files were ignored:"<<endl;
00429 for ( unsigned i = 1 ; i < args_info.inputs_num ; ++i )
00430 {
00431 cout << "file: " << args_info.inputs[i] << endl ;
00432 }
00433 }
00434 libofx_proc_file(libofx_context, args_info.inputs[0], file_format);
00435 }
00436 else
00437 {
00438 if ( !skiphelp )
00439 cmdline_parser_print_help();
00440 }
00441 return 0;
00442 }