Odyssey
hcuDownload.prg
1 <?php
2 
3 /*
4  * File: hcuDownload
5  * Purpose: Handle the transaction download operations. Either will download a file or show a screen
6  * where the user can select the account and date range.
7  *
8  * NOTE: Update the webconnect cookie to "remember" the last download date
9  *
10  * Call this script with the following parameters
11  * action - what the client side is requesting.
12  *
13  * NOTE: OFX output format is based on specs found at www.ofx.net
14  *
15  */
16 try {
17  // ** SET HOMECU FLAGS
18  $serviceShowInfo = true;
19  $serviceLoadMenu = true;
20  $serviceShowMenu = true;
21  $serviceAllowReadonly = true;
22 
23  // ** INCLUDE MAIN GLOBAL SCRIPT -- Handles security / global variable values
24  require_once('hcuService.i');
25 
26  /*
27  * ** CHECK USER FEATURE PERMISSIONS **
28  * NOTE: DOES NOT RETURN ON FAILURE
29  */
30  PermCheckFeatureScreen($dbh, $HB_ENV, $MC, FEATURE_DOWNLOAD_HISTORY);
31 
32 
33  // ** IMPORT FORM VALUES
34  $string= array("filter" => FILTER_SANITIZE_STRING);
35  $dms_ok = array("action"=>$string, 'downfmt' => $string,
36  'start' => $string, 'end' => $string,
37  'selacct' => $string );
38 
39  HCU_ImportVars($HB_ENV, "HCUPOST", $dms_ok);
40 
41  //get the database connection
42  // $dbh is set up
43 
44  if (!$dbh) {
45  // The connection was not made to the database
46  // unresolved: return an error??
47  }
48 
49  if (HCU_array_key_exists("action", $HB_ENV['HCUPOST'])) {
50  if ( $HB_ENV["HCUPOST"]["action"] == "download" ||
51  $HB_ENV["HCUPOST"]["action"] == "download_txns" ) {
52  // handle the request as if it was a download request
53 
54  /*
55  * The user can select multiple accounts, but only one date range.
56  * QIF can only handle one account.
57  */
58  # validate parameters
59  //startdate
60  //enddate
61  //selected account(s)
62  //filters
63  //
64  # validate entries
65  $start = (empty($HB_ENV["HCUPOST"]["start"]) ? "" : $HB_ENV["HCUPOST"]["start"]);
66  $end = (empty($HB_ENV["HCUPOST"]["end"]) ? mdydate() : $HB_ENV["HCUPOST"]["end"]);
67  $sqlend = sqldate($end);
68  $aryErrors = array();
69  if ( $start == "" ) {
70  $aryErrors[] = $MC->msg('Please provide a Start Date', HCU_DISPLAY_AS_RAW);
71  }
72  if (!sqldate($start)) {
73  $aryErrors[] = "[$start] " . $MC->msg('is not a valid date', HCU_DISPLAY_AS_RAW);
74  } else {
75  $sqlstart = sqldate($start);
76  }
77  if ( $end == "" ) {
78  $aryErrors[] = $MC->msg('Please provide an End Date', HCU_DISPLAY_AS_RAW);
79  }
80  if (!sqldate($end)) {
81  $aryErrors[] = "[$end] " . $MC->msg('is not a valid date', HCU_DISPLAY_AS_RAW);
82  }
83 
84  if ( !count( $aryErrors ) ) {
85  $datalist = array();
86  $sql = "select trim(fid), trim(rt), trim(orgname) from cuadmin where cu='{$HB_ENV['Cu']}'";
87  $sth = db_query($sql, $dbh);
88  list ($Cfid, $Crt, $Corgname) = db_fetch_array($sth, 0);
89  $datalist['cuinfo']['fid'] = $Cfid;
90  $datalist['cuinfo']['rt'] = $Crt;
91  $datalist['cuinfo']['orgname'] = $Corgname;
92  // put the start and end dates here for the data output functions to use
93  $datalist["cuinfo"]["sqlstart"] = $sqlstart;
94  $datalist["cuinfo"]["sqlend"] = $sqlend;
95 
96  $aryBalances = Get_Balances($dbh, $HB_ENV);
97 
98  if ($aryBalances['status']['code'] != '000') {
99  for ( $i = 0; $i < count( $aryBalances["status"]["errors"] ); $i++ ) {
100  $aryErrors[] = $aryBalances["status"]["errors"][$i];
101  }
102  } else {
103  // For now (01/27/2014) the only filter is the date range
104 
105  // there can be one or more accounts
106  $selAccts = explode( ";", $HB_ENV['HCUPOST']['selacct'] );
107  for ( $i = 0; $i < count( $selAccts ); $i++ ) {
108  // NOTE: It is hashed.
109  $selAcct = hcu_decrypturl($selAccts[$i], $HB_ENV['historyHash']);
110  $selAcctParts = explode("|", $selAcct);
111  switch ($selAcctParts[0]) {
112  case "D":
113  $tbl = 'dp';
114  break;
115  case "L":
116  $tbl = 'ln';
117  break;
118  case "C":
119  $tbl = 'cc';
120  break;
121  }
122 
123  $accountId = $aryBalances[$tbl][$selAcct];
124  $datalist['balances'][$tbl][$selAcct] = $accountId;
125 
126  // get the txns for the specified account
127  $aryTxns = Get_History($dbh, $HB_ENV, $selAcct, $sqlstart, $sqlend);
128 
129  if ($aryTxns['status']['code'] != '000') {
130  for ( $i = 0; $i < count( $aryTxns["status"]["errors"] ); $i++ ) {
131  $aryErrors[] = $aryTxns["status"]["errors"][$i];
132  }
133  } else {
134  if ($aryTxns['status']['code'] == '000') {
135  $datalist['txns'][$selAcct] = array_key_exists($selAcct, $aryTxns) ?
136  $aryTxns[$selAcct] :
137  array();
138  }
139  }
140  }
141  }
142 
143  if ( !count( $aryErrors ) ) {
144  # so now we have datalist holding balances and transactions as requested - pass it off to the appropriate download routine
145  #
146  if ( $HB_ENV["HCUPOST"]["action"] == "download_txns" ) {
147  $now = time();
148  $expires = mktime(date("H"), date("i"), date("s"), date("m") + 3, date("d"), date("Y"));
149 
150  setcookie("webconnect", "time=$now&user={$HB_ENV['cu']}:{$HB_ENV['Cn']}&laststart=$start&lastend=$end&fmt={$HB_ENV["HCUPOST"]['downfmt']}", $expires, "/", ".homecu.net", 1);
151  }
152  //
153  // build download string using requested format
154  switch ($HB_ENV["HCUPOST"]["downfmt"]) {
155  case "csv":
156  $outString = CSVDown($HB_ENV, $MC, $datalist);
157  header("Content-length: " . strlen($outString));
158  header("Content-type: application/octetstream");
159  header("Content-disposition: inline; filename=\"{$HB_ENV['Cu']}_txns.csv\"");
160  print ( $outString);
161  break;
162  case "qif":
163  $outString = QIFDown($HB_ENV, $datalist);
164  header("Content-length: " . strlen($outString));
165  header("Content-type: application/octetstream");
166  header("Content-disposition: inline; filename=\"{$HB_ENV['Cu']}_txns.qif\"");
167  print ( $outString);
168  break;
169  case "qfx":
170  $outString = OFXDown2($HB_ENV, $datalist); # OFX 211 format, with conditional for QFX even though Intuit says it is unsupported
171  if ($HB_ENV['HCUPOST']['downfmt'] == 'qfx') {
172  header("Content-type: application/vnd.intu.QFX");
173  header("Content-disposition: inline; filename=\"{$HB_ENV['Cu']}_txns.qfx\"");
174  } else {
175  header("Content-Type: application/x-ofx");
176  header("Content-disposition: inline; filename=\"{$HB_ENV['Cu']}_txns.ofx\"");
177  }
178  $outCount = strlen( $outString );
179  header("Content-length: $outCount");
180  print $outString;
181  break;
182  case "mny":
183  // MS Money will not support past OFX 2.0.3 so just use OFX 1
184  case "ofx1":
185  $outString = OFXDown1($HB_ENV, $datalist, $HB_ENV["HCUPOST"]["downfmt"]); # OFX 100 format
186  if ($HB_ENV['HCUPOST']['downfmt'] == 'qfx') {
187  header("Content-type: application/vnd.intu.QFX");
188  header("Content-disposition: inline; filename=\"{$HB_ENV['Cu']}_txns.qfx\"");
189  } else {
190  header("Content-Type: application/x-ofx");
191  header("Content-disposition: inline; filename=\"{$HB_ENV['Cu']}_txns.ofx\"");
192  }
193  $outCount = strlen( $outString );
194  header("Content-length: $outCount");
195  print $outString;
196  break;
197  case "qkn":
198  $outString = QknDown($HB_ENV, $datalist);
199  header("Content-type: application/vnd.intu.QFX");
200  header("Content-disposition: inline; filename=\"{$HB_ENV['Cu']}_txns.qfx\"");
201  $outCount = strlen( $outString );
202  header("Content-length: $outCount");
203  print $outString;
204  break;
205  case "qb":
206  $outString = QknDown($HB_ENV, $datalist);
207  header("Content-type: application/vnd.intu.QBO");
208  header("Content-disposition: inline; filename=\"{$HB_ENV['Cu']}_txns.qbo\"");
209  $outCount = strlen( $outString );
210  header("Content-length: $outCount");
211  print $outString;
212  break;
213  default:
214  # error, unexpected format
215  $aryErrors[] = "Unexpected format: {$HB_ENV["HCUPOST"]["downfmt"]}";
216  }
217  }
218 
219  if ( count( $aryErrors ) ) {
220  throw new Exception(HCU_JsonEncode($aryErrors));
221  } else {
222  // exit since the above code did a download
223  exit;
224  }
225  }
226  }
227  }
228 
229  // ** INCLUDE PRE CONTENT SCRIPT
230  require_once('hcuPreContent.i');
231 
232  $Flang = (trim($Flang) == "" ? "en_US" : trim($Flang));
233 
234  if ( $HB_ENV['offline'] != "N" ) {
235  $thisPageErrors = $HB_ENV["offlinemsg"];
236  throw new Exception( HCU_JsonEncode($thisPageErrors) );
237  }
238 
239  // ** Retrieve the notice for downloads
240  $noticesAry = Get_NoticeInfo($dbh, $HB_ENV, $MC, "D", "TxnDownloadHelp", true);
241 
242  $hasNoticeDNL = false;
243  $hasNoticePopupDNL = false;
244  $noticeURLDNL = "";
245  $noticeLinkDisplayDNL = "";
246  $noticeURLNoticeOnlyDNL = "";
247 
248  if ( $noticesAry["status"]["code"] == "000" && HCU_array_key_exists('0', $noticesAry['notice'])) {
249  if ($noticesAry["notice"][0]["notice_id"] ) {
250  $hasNoticeDNL = true;
251  $noticeLinkDisplayDNL = $noticesAry["notice"][0]["notice_linkdisplay"];
252 
253  $noticeOption = $noticesAry['notice'][0];
254 
255  $noticeOptions = Array (
256  'docsid' => $noticeOption['notice_id'],
257  'docstype' => $noticeOption['notice_type'],
258  'device' => 'D',
259  'noticeOnly' => '0',
260  'expireTime' => mktime() + 86400
261  );
262 
263  $encryptedDocDetails= HCU_PayloadEncode($HB_ENV['Cu'], $noticeOptions);
264 
265  $noticeOptions['noticeOnly'] = 1;
266 
267  $encryptedDocDetailsNoticeOnly= HCU_PayloadEncode($HB_ENV['Cu'], $noticeOptions);
268 
269  // build the url encoded string
270  // * For the popup terms
271  $noticeURLDNL = $HB_ENV['homebankingpath'] . '/hcuViewNotice.prg?cu=' . $HB_ENV['cu'] . '&x=' . urlencode($encryptedDocDetails);
272 
273  // * For the regular Button
274  $noticeURLNoticeOnlyDNL = $HB_ENV['homebankingpath'] . '/hcuViewNotice.prg?cu=' . $HB_ENV['cu'] . '&x=' . urlencode($encryptedDocDetailsNoticeOnly);
275 
276  // see if there is a popup notice
277  $hasNoticePopupDNL = $noticeOption["notice_popup"] ? true : false;
278  }
279  }
280 
281  // get the accounts
282  // NOTE: Using Get_Balances but it does extra work. If end up with simpler function, match code in hcuHistory.
283  // types to show a drop down of options to the member
284  $acctTypes = Array("dp", "ln", "cc");
285  $acctListAry = Array();
286  $GetBalancesAry = Get_Balances($dbh, $HB_ENV);
287 
288  if ( $GetBalancesAry['status']['code'] == '000' ) {
289  foreach ( $acctTypes as $acctType ) {
290  if ( HCU_array_key_exists($acctType, $GetBalancesAry ) ){
291  // ** The Member has accounts of this type.
292  // SO we start/end the table
293  if ( is_array( $GetBalancesAry[$acctType] ) === true ) {
294  // ** There are accounts of this type
295  foreach ( $GetBalancesAry[$acctType] as $acctID => $acctRow ) {
296 
297  // VARIABLES FOR ARRAY
298  $acctText = $acctRow['displaydesc'];
299  $acctValue = hcu_encrypturl($acctID, $HB_ENV['historyHash']);
300 
301  // BUILD ARRAY
302  if ( $acctType == "ln" ) {
303  // only show credit card if does NOT have hisinfo since that means we have the data (not external)
304  if (HCU_array_key_exists("hisinfo", $GetBalancesAry["ln"][$acctID])) {
305  if ( strlen(trim($GetBalancesAry["ln"][$acctID]["hisinfo"])) == 0 ) {
306  $acctListAry[] = Array( "acctValue" => $acctValue, "acctText" => $acctText, "type" => $acctType );
307  }
308  }
309  } else if ( $acctType == "cc" ) {
310  // only show credit card if has "homecu" since that means we have the data (not external)
311  if (HCU_array_key_exists("hisinfo", $GetBalancesAry["cc"][$acctID])) {
312  if ( strtolower(trim($GetBalancesAry["cc"][$acctID]["hisinfo"])) == "homecu" ) {
313  $acctListAry[] = Array( "acctValue" => $acctValue, "acctText" => $acctText, "type" => $acctType );
314  }
315  }
316  } else {
317  $acctListAry[] = Array( "acctValue" => $acctValue, "acctText" => $acctText, "type" => $acctType );
318  }
319  }
320  }
321  }
322  }
323  }
324 
325  // get the output formats
326  $Fset = $HB_ENV["Fset"];
327  $formatListAry = array();
328  if (($Fset & GetFlagsetValue("CU_MNYDOWN")) == GetFlagsetValue("CU_MNYDOWN") ) {
329  $formatListAry[] = array( "text" => $MC->msg('Money Active Statement', HCU_DISPLAY_AS_RAW), "value" => "mny", "type" => "dp|ln|cc" );
330  }
331  if (($Fset & GetFlagsetValue("CU_QKNDOWN")) == GetFlagsetValue("CU_QKNDOWN") ) {
332  $formatListAry[] = array( "text" => $MC->msg('Quicken WebConnect', HCU_DISPLAY_AS_RAW), "value" => "qkn", "type" => "dp" );
333  }
334 
335  if (($HB_ENV["Fset3"] & GetFlagsetValue("CU3_QBDOWN")) !== 0 ) {
336  $formatListAry[] = array( "text" => $MC->msg('QuickBooks WebConnect', HCU_DISPLAY_AS_RAW), "value" => "qb", "type" => "dp" );
337  }
338  if (($Fset & GetFlagsetValue("CU_QIFDOWN")) == GetFlagsetValue("CU_QIFDOWN") ) {
339  $formatListAry[] = array( "text" => $MC->msg('QIF File', HCU_DISPLAY_AS_RAW), "value" => "qif", "type" => "dp|ln|cc" );
340  }
341 
342  // everyone gets CSV
343  $formatListAry[] = array( "text" => $MC->msg('CSV File', HCU_DISPLAY_AS_RAW), "value" => "csv", "type" => "dp|ln|cc" );
344 
345  $lastend = date( "m/d/Y", time() - 30 * 24 * 3600 );
346  $lastendParts = explode( "/", $lastend );
347  $end = date( "m/d/Y" );
348  $endParts = explode( "/", $end );
349 ?>
350  <script>
351  var acctListAry = <?php echo HCU_JsonEncode( $acctListAry ); ?>;
352  var formatListAry = <?php echo HCU_JsonEncode( $formatListAry ); ?>;
353 
354  $(document).ready(function() {
355 
356  homecuTooltip.reset();
357  $(".detailsTip").each(function() {
358  homecuTooltip.custom.content = $(this).attr("title");
359  $(this).kendoTooltip(homecuTooltip.custom);
360  })
361 
362  $("#helpButton").click( function() {
363  ShowNotice( "<?php echo $noticeURLNoticeOnlyDNL; ?>", "<?php echo $MC->msg( "Download", HCU_DISPLAY_AS_JS ); ?>" );
364  });
365 
366  // setup validator
367  $.homecuValidator.setup({
368  formValidate:'formDownload'
369  });
370 
371  // use cookie start date if it exists, and today as end date
372  var date = new Date();
373  var endDate = date.setFullYear(<?php echo $endParts[2]; ?>,<?php echo ($endParts[0] - 1); ?>,<?php echo $endParts[1]; ?>);
374  var startDate = date.setFullYear(<?php echo $lastendParts[2]; ?>,<?php echo ($lastendParts[0] - 1); ?>,<?php echo $lastendParts[1]; ?>); //
375 
376  $('#histStartDate').kendoDatePicker({format: "MM/dd/yyyy"});
377  $('#histEndDate').kendoDatePicker({format: "MM/dd/yyyy"});
378  $('#histStartDate').data('kendoDatePicker').value(kendo.toString(new Date(startDate), 'MM/dd/yyyy'));
379  $('#histEndDate').data('kendoDatePicker').value(kendo.toString(new Date(endDate), 'MM/dd/yyyy'));
380 
381  // create DropDownList from input HTML element
382  $("#acctList").kendoMultiSelect({
383  dataTextField: "acctText",
384  dataValueField: "acctValue",
385  dataSource: thisAcctChoiceAry,
386  autoClose: false,
387  placeholder: "<?php echo $MC->msg('Select account', HCU_DISPLAY_AS_JS) ?>",
388  template: "#= acctText #", <?php // Do not encode ?>
389  tagTemplate: "#= acctText #"
390  });
391 
392  // create download format DropDownList from input HTML element
393  $("#formatList").kendoDropDownList({
394  dataTextField: "text",
395  dataValueField: "value",
396  dataSource: formatListAry,
397  value: formatListAry[0],
398  change: UpdateAccountChoices
399  });
400 
401  $("#btnDownload").on("click", function() {
402  if ($.homecuValidator.validate()) {
403  var multiselect = $("#acctList").data("kendoMultiSelect");
404  var selectTest = multiselect.value();
405  var selectAccts = "";
406 
407  for (i=0; i < selectTest.length; i++) {
408  if ( selectAccts.length > 0 ) {
409  selectAccts += ";";
410  }
411  selectAccts += selectTest[i];
412  }
413 
414  document.formDownload.selacct.value = selectAccts;
415  document.formDownload.submit();
416  }
417  });
418  var thisAcctChoiceAry;
419 
420  // update the list accounts that can download to this format
421  function UpdateAccountChoices() {
422  // get the download format choice
423  var formatChoice = $("#formatList").data("kendoDropDownList").value( );
424 
425  var typesSupported = "";
426  for ( var i = 0; i < formatListAry.length; i++ ) {
427  if ( formatListAry[i].value === formatChoice ) {
428  typesSupported = formatListAry[i].type;
429  break;
430  }
431  }
432 
433  // only allow accounts for this type
434  thisAcctChoiceAry = [];
435  for ( var i = 0; i < acctListAry.length; i++ ) {
436  test = typesSupported.indexOf( acctListAry[i].type );
437  if ( test >= 0 ) {
438  thisAcctChoiceAry.push( acctListAry[i] );
439  }
440  }
441 
442  var acctList = $("#acctList").data("kendoMultiSelect");
443  acctList.setDataSource( thisAcctChoiceAry );
444 
445  // if QIF format, only allow one account
446  if ( formatChoice === "qif" ) {
447  acctList.options.maxSelectedItems = 1;
448  } else {
449  acctList.options.maxSelectedItems = acctListAry.length;
450  }
451 
452  // now, empty the account list
453  acctList.value([]);
454  }
455 
456  // update the download choices
457  function updateOutputChoices( ) {
458  var acctList = $("#acctList").data('kendoMultiSelect');
459  var choices = acctList.value();
460 
461  // get all the types from all the selected items
462  var typeList = [];
463  for ( var i = 0; i < acctListAry.length; i++ ) {
464  var oneChoice = acctListAry[i].acctValue;
465  for ( var c = 0; c < choices.length; c++ ) {
466  if ( choices[c] === oneChoice ) {
467  var thisType = acctListAry[i].type;
468  var test = typeList.indexOf( thisType );
469  if ( test < 0 ) {
470  typeList.push( thisType );
471  }
472  // go to the next choice
473  break;
474  }
475  }
476  }
477 
478  var thisAcctFormatListAry = [];
479  for ( var i = 0; i < formatListAry.length; i++ ) {
480  var thisType = formatListAry[i].type;
481  for ( var t = 0; t < typeList.length; t++ ) {
482  var oneType = typeList[t];
483  var test = thisType.indexOf( oneType );
484  if ( test >= 0 ) {
485  // make sure not already in list
486  var found = false;
487  for ( var f = 0; f < thisAcctFormatListAry.length; f++ ) {
488  if ( thisAcctFormatListAry[f] === formatListAry[i] ) {
489  found = true;
490  break;
491  }
492  }
493  if ( !found ) {
494  thisAcctFormatListAry.push( formatListAry[i] );
495  }
496  }
497  }
498  }
499 
500  $("#formatList").data("kendoDropDownList").setDataSource( thisAcctFormatListAry );
501  }
502 
503  // set up the initial list
504  UpdateAccountChoices();
505 
506  <?php // if have an output format already chosen, use that ?>
507  <?php if ( array_key_exists("downfmt", $HB_ENV['HCUPOST']) && strlen( $HB_ENV["HCUPOST"]["downfmt"] ) > 0 ) { ?>
508  $("#formatList").data("kendoDropDownList").value( "<?php echo $HB_ENV["HCUPOST"]["downfmt"]; ?>" )
509  <?php } ?>
510 
511  <?php // auto open downlod notice ?>
512  <?php if ( $hasNoticeDNL && $hasNoticePopupDNL ) { ?>
513  ShowNotice('<?php echo $noticeURLDNL; ?>');
514  <?php } ?>
515  });
516 
517  </script>
518 <!-- HTML STYLING -->
519 <style type="text/css">
520 .hcuDownload {
521  min-width: 300px;
522  max-width: 700px;
523  margin-left: 0px;
524  margin-top: 15px;
525 }
526 
527 .hcu-info-margin, .hcu-error-margin {
528  margin: 15px 0;
529 }
530 
531 .hcu-info-padding, .hcu-error-padding {
532  padding: 15px;
533 }
534 
535 .hcu-full-width {
536  width: 100%;
537 }
538 
539 /* top-bottom margin */
540 .hcu-container-margin {
541  margin: 15px 0;
542 }
543 
544 .hcu-no-padding {
545  padding: 0;
546 }
547 </style>
548 
549 <!-- HTML CONTENT -->
550 <div class="container-fluid hcuDownload">
551  <div class="well well-sm">
552 
553  <!-- HEADER -->
554  <div>
555  <h3><?php echo $MC->msg('Download', HCU_DISPLAY_AS_HTML); ?></h3>
556  </div>
557 
558  <!-- FORM CONTENT -->
559  <form id="formDownload" name="formDownload" method="post">
560  <fieldset>
561  <input type="hidden" name="action" value="download_txns">
562  </fieldset>
563 
564  <fieldset>
565  <div class="col-xs-12 col-md-6 hcu-container-margin">
566  <label for="start">
567  <span><?php echo $MC->msg('Transaction Date Range', HCU_DISPLAY_AS_HTML); ?>: </span>
568  <span class="fa fa-question-circle-o detailsTip" title="<?php echo $MC->msg('Enter dates', HCU_DISPLAY_AS_HTML) ?>"></span>
569  </label>
570 
571  <input type="text" name='start' id='histStartDate' class="hcu-full-width"
572  homecu-match="date"
573  data-homecuCustomMatch-msg="
574  <?php echo $MC->msg('Transaction Date Range', HCU_DISPLAY_AS_HTML); ?>:
575  <?php echo $MC->msg('is not a valid date', HCU_DISPLAY_AS_HTML) ?>"
576  data-required-msg="
577  <?php echo $MC->msg('Transaction Date Range', HCU_DISPLAY_AS_HTML); ?>:
578  <?php echo $MC->msg('is not a valid date', HCU_DISPLAY_AS_HTML) ?>"
579  required >
580  </div>
581 
582  <div class="col-xs-12 col-md-6 hcu-container-margin">
583  <label for="end">
584  <span><?php echo $MC->msg('To', HCU_DISPLAY_AS_HTML) ?>:</span>
585  </label>
586 
587  <input type="text" name='end' id='histEndDate' class="hcu-full-width"
588  homecu-match="date"
589  data-homecuCustomMatch-msg="
590  <?php echo $MC->msg('To', HCU_DISPLAY_AS_HTML); ?>:
591  <?php echo $MC->msg('is not a valid date', HCU_DISPLAY_AS_HTML) ?>"
592  data-required-msg="
593  <?php echo $MC->msg('To', HCU_DISPLAY_AS_HTML); ?>:
594  <?php echo $MC->msg('is not a valid date', HCU_DISPLAY_AS_HTML) ?>"
595  required >
596  </div>
597 
598  </fieldset>
599 
600  <fieldset>
601  <div class="col-xs-12 col-md-6 hcu-container-margin">
602  <label for="account">
603  <span><?php echo $MC->msg('Format', HCU_DISPLAY_AS_HTML); ?>: </span>
604  <span class="fa fa-question-circle-o detailsTip" title="<?php echo $MC->msg('Select a download format', HCU_DISPLAY_AS_HTML) ?>"></span>
605  </label>
606 
607  <input id='formatList' name="downfmt" class="hcu-full-width"/>
608  </div>
609 
610  <div class="col-xs-12 hcu-container-margin">
611  <label for="account">
612  <span><?php echo $MC->msg('Account', HCU_DISPLAY_AS_HTML); ?>: </span>
613  <span class="fa fa-question-circle-o detailsTip" title="<?php echo $MC->msg('Transactions will be downloaded', HCU_DISPLAY_AS_HTML) ?>"></span>
614  </label>
615 
616  <input type="hidden" name="selacct" value="" />
617  <select id='acctList' name="acctList" multiple="multiple" class="hcu-full-width"
618  data-required-msg="<?php echo $MC->msg('Please select an account', HCU_DISPLAY_AS_HTML) ?>"
619  required></select>
620  </div>
621  </fieldset>
622 
623  <fieldset>
624  <div class="col-xs-12 col-md-6 hcu-container-margin">
625  <button id="btnDownload" name='btnDownload' type="button" class="k-button k-primary">
626  <span class="fa fa-download">&nbsp;</span>
627  <span><?php print $MC->msg('Download', HCU_DISPLAY_AS_HTML); ?></span>
628  </button>
629  </div>
630 
631  <div class="col-xs-12 col-md-12">
632  <a href="#" id="helpButton" class="hcu-full-width">
633  <span><?php echo $noticeLinkDisplayDNL ?></span>
634  </a>
635  </div>
636  </fieldset>
637  </form>
638  </div>
639 </div>
640 <?php
641 } catch (Exception $ex) {
642  //Return error message
643  $thisPageErrors = HCU_JsonDecode($ex->getMessage());
644 
645  // ** Handle Errors on this screen
646  $serviceErrorCode = '917';
647  $serviceErrorMsgs = $thisPageErrors;
648 
649  require_once('hcuErrorPage.i');
650  // drop through to close the page
651 }
652 
653  // ** INCLUDE POST CONTENT SCRIPT
654  require_once('hcuPostContent.i');
655 
656 
657 /* * *********** Functions ************* */
658 
659 # OFX / Quicken download
660 // This is based on the OFX 2.0 spec.
661 function OFXDown2($HB_ENV,$datalist) {
662 /*
663  * per Intuit documentation
664  * reviewed online 12/13/13 at https://fi.intuit.com/ofximplementation/wcsteps/index.cfm?view=wcdevelop
665  * All versions of Quicken and QuickBooks which support Web Connect are coded to work with OFX version 1.0.3.
666  * OFX 2.0 is not officially supported and is not recommended for use with Web Connect implementations.
667  * This is coded to pass OFX 2 in case it works. See QKNDown for legacy QFX format
668  */
669 
670  $now = ofxdate();
671  $sqlStart = $datalist["cuinfo"]["sqlstart"];
672  $sqlEnd = $datalist["cuinfo"]["sqlend"];
673  $ofxString = "";
674 
675  $ofxString .= <<<EOF
676 <?xml version="1.0" encoding="US-ASCII"?>
677 <?OFX OFXHEADER="200" VERSION="211" SECURITY="NONE" OLDFILEUID="NONE" NEWFILEUID="NONE"?>
678 <OFX>
679 <SIGNONMSGSRSV1>
680 <SONRS>
681 <STATUS>
682 <CODE>0</CODE>
683 <SEVERITY>INFO</SEVERITY>
684 </STATUS>
685 <DTSERVER>{$now}</DTSERVER>
686 <LANGUAGE>ENG</LANGUAGE>
687 <DTACCTUP>19900101000000</DTACCTUP>
688 <FI>
689 <ORG>{$datalist['cuinfo']['orgname']}</ORG>
690 <FID>{$datalist['cuinfo']['fid']}</FID>
691 </FI>
692 EOF;
693 
694  // if "qfx" type, don't use a closing tag since Intuit is expecting it unbalanced.
695  if ($HB_ENV['HCUPOST']['downfmt'] == 'qfx') {
696  $ofxString .= "\n<INTU.BID>{$datalist['cuinfo']['fid']}\n<INTU.USERID>{$HB_ENV['Cn']}";
697  }
698 
699  $ofxString .= "</SONRS>\n</SIGNONMSGSRSV1>\n";
700 
701  if (HCU_array_key_exists("dp", $datalist['balances']) && sizeof($datalist['balances']['dp'])) {
702  $ofxString .= "<BANKMSGSRSV1>\n";
703 
704  foreach ($datalist['balances']['dp'] as $balkey => $balinfo) {
705 
706 # for each $balances[dp] Get_History & print
707  $cert = $balinfo['certnumber'];
708  $type = $balinfo['accounttype'];
709  $desc = $balinfo['description'];
710  $desc = hcu_displayHtml( $desc, ENT_NOQUOTES );
711  $displaydesc = $balinfo['displaydesc'];
712  $displaydesc = hcu_displayHtml( $displaydesc, ENT_NOQUOTES );
713  $type = ("$cert" == "0" ? $type : "${type}_${cert}");
714  $type = hcu_displayHtml( trim($type), ENT_NOQUOTES );
715 
716  switch ($balinfo['deposittype']) {
717  case "Y":
718  $acttype = "CHECKING";
719  break;
720  /*case "C": # Certificates
721  $acttype = "INVESTMENT";
722  break;*/
723  case "I": # IRA accounts
724  $acttype = "RETIREMENT";
725  break;
726  case "C":
727  case "N":
728  case "S":
729  $acttype = "SAVINGS";
730  break;
731  }
732 # opening tags for account info
733 
734  $ofxString .= "<STMTTRNRS>\n";
735  $ofxString .= "<TRNUID>0</TRNUID>\n";
736  $ofxString .= "<STATUS>\n";
737  $ofxString .= "<CODE>0</CODE>\n";
738  $ofxString .= "<SEVERITY>INFO</SEVERITY>\n";
739  $ofxString .= "</STATUS>\n";
740  $ofxString .= "<STMTRS>\n";
741  $ofxString .= "<CURDEF>USD</CURDEF>\n";
742  $ofxString .= "<BANKACCTFROM>\n";
743  $ofxString .= "<BANKID>{$datalist['cuinfo']['rt']}</BANKID>\n";
744  $ofxString .= "<ACCTID>$type</ACCTID>\n";
745  $ofxString .= "<ACCTTYPE>$acttype</ACCTTYPE>\n";
746  $ofxString .= "<DESCRIPTION>$desc</DESCRIPTION>\n";
747  if ("$displaydesc" > '') {
748  $ofxString .= "<DISPLAYDESC>$displaydesc</DISPLAYDESC>\n";
749  }
750  $ofxString .= "</BANKACCTFROM>\n";
751 
752  $ofxString .= "<BANKTRANLIST>\n";
753  $ofxString .= "<DTSTART>{$sqlStart}000000</DTSTART>\n";
754  $ofxString .= "<DTEND>$now</DTEND>\n";
755 
756  if (sizeof($datalist['txns'][$balkey])) {
757  foreach ($datalist['txns'][$balkey] as $tnum => $detl) {
758  $tranamount = $detl['amount'];
759  $tranamount = str_replace(",", "", str_replace("$", "", $tranamount));
760  $tranamount = sprintf("%.2f", $tranamount);
761  $trbal = $detl['balance'];
762  $trbal = str_replace(",", "", str_replace("$", "", $trbal));
763  $trbal = sprintf("%.2f", $trbal);
764  $check = HCU_array_key_exists("checkno", $detl) ? $detl['checkno'] : 0;
765  $trandesc = $detl['description'];
766  if ($trandesc < " " && $check != 0) {
767  $trandesc = "CHK";
768  }
769  $trandesc = (preg_replace("/<BR>/", " ", $trandesc));
770  $trandesc = (preg_replace("/&nbsp;/", " ", $trandesc));
771  $longdesc = htmlentities($trandesc,ENT_NOQUOTES,'UTF-8',FALSE);
772  $shortdesc = substr(htmlentities($trandesc,ENT_NOQUOTES,'UTF-8',FALSE), 0, 31);
773  $shortdesc = preg_replace('/&[^;]*$/', '', $shortdesc);
774  $shortdesc = (trim($shortdesc) == '' ? '.' : $shortdesc);
775 
776  $ofxString .= "<STMTTRN>\n";
777  if ($tranamount < 0) {
778  if ($balinfo['deposittype'] == 'Y' && $check != 0) {
779  $ofxString .= "<TRNTYPE>CHECK</TRNTYPE>\n";
780  } else {
781  $ofxString .= "<TRNTYPE>DEBIT</TRNTYPE>\n";
782  }
783  } else {
784  $ofxString .= "<TRNTYPE>CREDIT</TRNTYPE>\n";
785  }
786  // history data date is in the format CCYY-MM-DD
787  $date = str_replace("-", "", $detl["date"]);
788  $ofxString .= "<DTPOSTED>$date</DTPOSTED>\n";
789 # DTUSER not needed for 211?
790  $ofxString .= "<DTUSER>$date</DTUSER>\n";
791  $ofxString .= "<TRNAMT>$tranamount</TRNAMT>\n";
792  $ofxString .= "<FITID>" . $detl['traceno'] . "</FITID>\n";
793  if ($balinfo['deposittype'] == 'Y' && $check != 0) {
794  $ofxString .= "<CHECKNUM>$check</CHECKNUM>\n";
795  }
796  $ofxString .= "<NAME>$shortdesc</NAME>\n";
797  if (strlen( trim( $longdesc ) ) > 32) {
798  $ofxString .= "<MEMO>$longdesc</MEMO>\n";
799  }
800  $ofxString .= "</STMTTRN>\n";
801  }
802  }
803 
804 # closing tags for transaction list
805  $ofxString .= "</BANKTRANLIST>\n";
806  $ofxString .= "<LEDGERBAL>\n";
807  $ofxString .= "<BALAMT>" . $balinfo["currentbal"] . "</BALAMT>\n";
808  $ofxString .= "<DTASOF>$now</DTASOF>\n";
809  $ofxString .= "</LEDGERBAL>\n";
810  if (($HB_ENV['Fset'] & GetFlagsetValue("CU_SHOWAVAILABLE")) == GetFlagsetValue("CU_SHOWAVAILABLE")) {
811  $ofxString .= "<AVAILBAL>\n<BALAMT>" . $balinfo["availablebal"] . "</BALAMT>\n <DTASOF>$now</DTASOF>\n</AVAILBAL>\n";
812  }
813 
814 # closing tags for account info
815  $ofxString .= "</STMTRS>\n</STMTTRNRS>\n";
816  } # end of foreach(balances['dp']
817 
818  $ofxString .= "</BANKMSGSRSV1>\n";
819  }
820 
821  if (HCU_array_key_exists("cc", $datalist['balances']) && count($datalist['balances']['cc'])) {
822  $ofxString .= "<CREDITCARDMSGSRSV1>\n";
823 
824  foreach ($datalist['balances']['cc'] as $balkey => $balinfo) {
825  $ofxString .= "<CCSTMTTRNRS>\n";
826 
827  $stmntbal = $balinfo['payoff'];
828  $paymentamount = $balinfo['paymentamount'];
829  $nextduedate = $balinfo['nextduedate'];
830  $interestrate = $balinfo['interestrate'];
831  $creditlimit = $balinfo['creditlimit'];
832 
833  $desc = $balinfo['description'];
834  $desc = hcu_displayHtml( $desc, ENT_NOQUOTES );
835  $displaydesc = $balinfo['displaydesc'];
836  $displaydesc = hcu_displayHtml( $displaydesc, ENT_NOQUOTES );
837  $loan = $balinfo['loan'];
838  $balance = $balinfo['currentbal'];
839  $available = $creditlimit - $balance;
840  $available = ($available < 0 ? "" : $available);
841 
842  # open new loan set
843  $ofxString .= "<CCSTMTRS>\n";
844  $ofxString .= "<CURDEF>USD</CURDEF>\n";
845  $ofxString .= "<CCACCTFROM>\n";
846  $ofxString .= "<ACCTID>$loan</ACCTID>\n";
847  $ofxString .= "<DESCRIPTION>$desc</DESCRIPTION>\n";
848  if ("$displaydesc" > '') {
849  $ofxString .= "<DISPLAYDESC>$displaydesc</DISPLAYDESC>\n";
850  }
851  $ofxString .= "</CCACCTFROM>\n";
852  $ofxString .= "<BANKTRANLIST>\n";
853  $ofxString .= "<DTSTART>{$sqlStart}000000</DTSTART>\n";
854  $ofxString .= "<DTEND>$now</DTEND>\n";
855 
856  $cur_avail = (($HB_ENV['Fset2'] & GetFlagsetValue("CU2_CALL_CCAVAIL")) == GetFlagsetValue("CU2_CALL_CCAVAIL") ?
857  "Call" : $available);
858 
859  // NOTE: if cc info not known to HomeCU then the account transactions wouldn't be here
860  if (sizeof($datalist['txns'][$balkey])) {
861  foreach ($datalist['txns'][$balkey] as $tnum => $detl) {
862 
863  $hisbal = $detl['balance'];
864  $principle = $detl['principal'];
865  $interest = $detl['interest'];
866 
867  if ($principle < 0) {
868  $trntype = "DEBIT";
869  } else {
870  $trntype = "CREDIT";
871  }
872 
873  $totalpay = $detl['totalpay'];
874  $trdesc = $detl['description'];
875  // history data date is in the format CCYY-MM-DD; we want CCYYMMDD
876  $date = str_replace("-", "", $detl["date"]);
877  $traceno = $detl['traceno'];
878  $longdesc = htmlentities($trdesc,ENT_NOQUOTES,'UTF-8',FALSE);
879  $shortdesc = substr(htmlentities($trdesc,ENT_NOQUOTES,'UTF-8',FALSE), 0, 31);
880  $shortdesc = preg_replace('/&[^;]*$/', '', $shortdesc);
881  $shortdesc = (trim($shortdesc) == '' ? '.' : $shortdesc);
882 
883 # transaction data row
884  $ofxString .= "<STMTTRN>\n";
885  $ofxString .= "<TRNTYPE>$trntype</TRNTYPE>\n";
886  $ofxString .= "<DTPOSTED>$date</DTPOSTED>\n";
887  $ofxString .= "<TRNAMT>$totalpay</TRNAMT>\n";
888  $ofxString .= "<FITID>$traceno</FITID>\n";
889  if (($HB_ENV['Fset'] & GetFlagsetValue("CU_SHOWLNTXNDESC")) == GetFlagsetValue("CU_SHOWLNTXNDESC")) {
890  $ofxString .= "<NAME>$shortdesc</NAME>\n";
891  if ( strlen( trim( $longdesc ) ) > 32 ) {
892  $ofxString .= "<MEMO>$longdesc</MEMO>\n";
893  }
894  }
895  $ofxString .= "</STMTTRN>\n";
896  }
897  }
898  $ofxString .= "</BANKTRANLIST>\n";
899  $ofxString .= "<LEDGERBAL>\n";
900  $ofxString .= "<BALAMT>$balance</BALAMT>\n";
901  $ofxString .= "<DTASOF>$now</DTASOF>\n";
902  $ofxString .= "</LEDGERBAL>\n";
903  if ($cur_avail > 0) {
904  $ofxString .= "<AVAILBAL>\n";
905  $ofxString .= "<BALAMT>$cur_avail</BALAMT>\n";
906  $ofxString .= "<DTASOF>$now</DTASOF>\n";
907  $ofxString .= "</AVAILBAL>\n";
908  }
909 #
910  $ofxString .= "</CCSTMTRS>\n";
911  $ofxString .= "</CCSTMTTRNRS>\n";
912  }
913  $ofxString .= "</CREDITCARDMSGSRSV1>\n";
914  }
915 
916  if (HCU_array_key_exists("ln", $datalist['balances']) && sizeof($datalist['balances']['ln'])) {
917 
918  $ofxString .= "<LOANMSGSRSV1>\n";
919 
920  foreach ($datalist['balances']['ln'] as $balkey => $balinfo) {
921 
922  $ofxString .= "<LOANSTMTTRNRS>\n";
923 
924  $balance = $balinfo['currentbal'];
925  $loan = $balinfo['loan'];
926  $desc = $balinfo['description'];
927  $desc = hcu_displayHtml( $desc, ENT_NOQUOTES );
928  $displaydesc = $balinfo['displaydesc'];
929  $displaydesc = hcu_displayHtml( $displaydesc, ENT_NOQUOTES );
930  $payoff = $balinfo['payoff'];
931  $paymentamount = $balinfo['paymentamount'];
932  $nextduedate = $balinfo['nextduedate'];
933  $interestrate = $balinfo['interestrate'];
934  $creditlimit = $balinfo['creditlimit'];
935 
936  # open new loan set
937  $ofxString .= "<LOANSTMTRS>\n";
938  $ofxString .= "<CURDEF>USD</CURDEF>\n";
939  $ofxString .= "<LOANACCTFROM>\n";
940  $ofxString .= "<LOANACCTID>$loan</LOANACCTID>\n";
941  $ofxString .= "<LOANACCTTYPE>CONSUMER</LOANACCTTYPE>\n";
942  $ofxString .= "<DESCRIPTION>$desc</DESCRIPTION>\n";
943  if ("$displaydesc" > '') {
944  $ofxString .= "<DISPLAYDESC>$displaydesc</DISPLAYDESC>\n";
945  }
946  $ofxString .= "</LOANACCTFROM>\n";
947  $ofxString .= "<LOANTRANLIST>\n";
948  $ofxString .= "<DTSTART>{$sqlStart}000000</DTSTART>\n";
949  $ofxString .= "<DTEND>$now</DTEND>\n";
950 
951  if (sizeof($datalist['txns'][$balkey])) {
952  foreach ($datalist['txns'][$balkey] as $tnum => $detl) {
953 
954  $hisbal = $detl['balance'];
955  $principle = $detl['principal'];
956  $interest = $detl['interest'];
957  $totalpay = $detl['totalpay'];
958  $traceno = $detl['traceno'];
959  $trdesc = $detl['description'];
960 
961  if ($principle < 0) {
962  $trntype = "PAYMENT";
963  } else {
964  $trntype = "ADVANCE";
965  }
966 
967  $longdesc = htmlentities($trdesc,ENT_NOQUOTES,'UTF-8',FALSE);
968  $shortdesc = substr(htmlentities($trdesc,ENT_NOQUOTES,'UTF-8',FALSE), 0, 31);
969  $shortdesc = preg_replace('/&[^;]*$/', '', $shortdesc);
970  $shortdesc = (trim($shortdesc) == '' ? '.' : $shortdesc);
971 
972 # transaction data row
973  // history data date is in the format CCYY-MM-DD
974  $date = str_replace("-", "", $detl["date"]);
975  $ofxString .= "<LOANSTMTTRN>\n";
976  $ofxString .= "<LOANTRNTYPE>$trntype</LOANTRNTYPE>\n";
977  $ofxString .= "<DTPOSTED>$date</DTPOSTED>\n";
978  if (($HB_ENV['Fset'] & GetFlagsetValue("CU_SHOWLNTXNSPLIT")) == GetFlagsetValue("CU_SHOWLNTXNSPLIT")) {
979  $ofxString .= "<TRNAMT>$totalpay</TRNAMT>\n";
980  $ofxString .= "<LOANTRNAMT>\n";
981  $ofxString .= "<PRINAMT>$principle</PRINAMT>\n";
982  $ofxString .= "<INTAMT>$interest</INTAMT>\n";
983  $ofxString .= "</LOANTRNAMT>\n";
984  } else {
985  $ofxString .= "<TRNAMT>$principle</TRNAMT>\n";
986  }
987  $ofxString .= "<FITID>$traceno</FITID>\n";
988  if (($HB_ENV['Fset'] & GetFlagsetValue("CU_SHOWLNTXNDESC")) == GetFlagsetValue("CU_SHOWLNTXNDESC")) {
989  $ofxString .= "<NAME>$shortdesc</NAME>\n";
990  if ( strlen( trim( $longdesc ) ) > 32 ) {
991  $ofxString .= "<MEMO>$longdesc</MEMO>\n";
992  }
993  }
994  $ofxString .= "</LOANSTMTTRN>\n";
995  }
996  }
997  $ofxString .= "</LOANTRANLIST>\n";
998  $ofxString .= "<PRINBAL>\n";
999  $ofxString .= "<BALAMT>$balance</BALAMT>\n";
1000  $ofxString .= "<DTASOF>$now</DTASOF>\n";
1001  $ofxString .= "</PRINBAL>\n";
1002 
1003  $ofxString .= "</LOANSTMTRS>\n";
1004  $ofxString .= "</LOANSTMTTRNRS>\n";
1005  }
1006  $ofxString .= "</LOANMSGSRSV1>\n";
1007  }
1008 
1009 
1010  $ofxString .= "</OFX>\n";
1011 
1012  return $ofxString;
1013 }
1014 # Quicken download
1015 function QknDown($HB_ENV,$datalist) {
1016 /*
1017  * per Intuit documentation
1018  * reviewed online 12/13/13 at https://fi.intuit.com/ofximplementation/wcsteps/index.cfm?view=wcdevelop
1019  * All versions of Quicken and QuickBooks which support Web Connect are coded to work with OFX version 1.0.3.
1020  * OFX 2.0 is not officially supported and is not recommended for use with Web Connect implementations.
1021  * This is the legacy format, in case OFXDown2 won't work.
1022  */
1023  $now = ofxdate();
1024  $sqlStart = $datalist["cuinfo"]["sqlstart"];
1025  $sqlEnd = $datalist["cuinfo"]["sqlend"];
1026  $ofxString = "";
1027 
1028  $ofxString .= <<<EOF
1029 OFXHEADER: 100
1030 DATA: OFXSGML
1031 VERSION: 102
1032 SECURITY: NONE
1033 ENCODING: USASCII
1034 CHARSET: 1252
1035 COMPRESSION: NONE
1036 OLDFILEUID: NONE
1037 NEWFILEUID: NONE
1038 
1039 <OFX>
1040 <SIGNONMSGSRSV1>
1041 <SONRS>
1042 <STATUS>
1043 <CODE>0
1044 <SEVERITY>INFO
1045 </STATUS>
1046 <DTSERVER>$now
1047 <LANGUAGE>ENG
1048 <DTACCTUP>19900101000000
1049 <FI>
1050 <ORG>{$datalist['cuinfo']['orgname']}
1051 <FID>{$datalist['cuinfo']['fid']}
1052 </FI>
1053 <INTU.BID>{$datalist['cuinfo']['fid']}
1054 <INTU.USERID>{$HB_ENV['Cn']}
1055 </SONRS>
1056 </SIGNONMSGSRSV1>
1057 EOF;
1058 
1059 
1060  if (HCU_array_key_exists("dp", $datalist['balances']) && sizeof($datalist['balances']['dp'])) {
1061  $ofxString .= "<BANKMSGSRSV1>\n";
1062 
1063  // get member list and user member in acctid id flag
1064  $userAccts = Get_UserAccounts( $HB_ENV['dbh'], $HB_ENV["cu"], $HB_ENV["Uid"] );
1065  $useMemAcctFlag = (($HB_ENV['flagset2'] & GetFlagsetValue("CU2_OFX_MEMACCTID")) == GetFlagsetValue("CU2_OFX_MEMACCTID"));
1066  $useMemAcctID = (count($userAccts['data']) > 1);
1067  $useMemAcct = ($useMemAcctID || $useMemAcctFlag);
1068 
1069  foreach ($datalist['balances']['dp'] as $balkey => $balinfo) {
1070 
1071 # for each $balances[dp] Get_History & print
1072  $acct = $balinfo['accountnumber'];
1073  $cert = $balinfo['certnumber'];
1074  $type = $balinfo['accounttype'];
1075  $desc = $balinfo['description'];
1076  $desc = hcu_displayHtml( $desc, ENT_NOQUOTES );
1077  $displaydesc = $balinfo['displaydesc'];
1078  $displaydesc = hcu_displayHtml( $displaydesc, ENT_NOQUOTES );
1079  $type = ("$cert" == "0" ? $type : "${type}_${cert}");
1080  $type = ($useMemAcct ? "$acct/$type" : $type);
1081  $type = hcu_displayHtml( trim($type), ENT_NOQUOTES );
1082 
1083  switch ($balinfo['deposittype']) {
1084  case "Y":
1085  $acttype = "CHECKING";
1086  break;
1087  case "I": # IRA accounts
1088  $acttype = "RETIREMENT";
1089  break;
1090  case "C":
1091  case "N":
1092  case "S":
1093  $acttype = "SAVINGS";
1094  break;
1095  }
1096 # opening tags for account info
1097 
1098  $ofxString .= "<STMTTRNRS>\n";
1099  $ofxString .= "<TRNUID>0\n";
1100  $ofxString .= "<STATUS>\n";
1101  $ofxString .= "<CODE>0\n";
1102  $ofxString .= "<SEVERITY>INFO\n";
1103  $ofxString .= "</STATUS>\n";
1104  $ofxString .= "<STMTRS>\n";
1105  $ofxString .= "<CURDEF>USD\n";
1106  $ofxString .= "<BANKACCTFROM>\n";
1107  $ofxString .= "<BANKID>{$datalist['cuinfo']['rt']}\n";
1108  $ofxString .= "<ACCTID>$type\n";
1109  $ofxString .= "<ACCTTYPE>$acttype\n";
1110  $ofxString .= "</BANKACCTFROM>\n";
1111 
1112  $ofxString .= "<BANKTRANLIST>\n";
1113  $ofxString .= "<DTSTART>{$sqlStart}000000\n";
1114  $ofxString .= "<DTEND>$now\n";
1115 
1116  if (sizeof($datalist['txns'][$balkey])) {
1117  foreach ($datalist["txns"][$balkey] as $tnum => $detl) {
1118 
1119  $tranamount = $detl['amount'];
1120  $tranamount = str_replace(",", "", str_replace("$", "", $tranamount));
1121  $tranamount = sprintf("%.2f", $tranamount);
1122  $trbal = $detl['balance'];
1123  $trbal = str_replace(",", "", str_replace("$", "", $trbal));
1124  $trbal = sprintf("%.2f", $trbal);
1125  $check = HCU_array_key_exists("checkno", $detl) ? $detl['checkno'] : 0;
1126  $trandesc = $detl['description'];
1127  if ($trandesc < " " && $check != 0) {
1128  $trandesc = "CHK";
1129  }
1130  $trandesc = (preg_replace("/<BR>/", " ", $trandesc));
1131  $trandesc = (preg_replace("/&nbsp;/", " ", $trandesc));
1132  $longdesc = htmlentities($trandesc,ENT_NOQUOTES,'UTF-8',FALSE);
1133  $shortdesc = substr(htmlentities($trandesc,ENT_NOQUOTES,'UTF-8',FALSE), 0, 31);
1134  $shortdesc = preg_replace('/&[^;]*$/', '', $shortdesc);
1135  $shortdesc = (trim($shortdesc) == '' ? '.' : $shortdesc);
1136 
1137  $ofxString .= "<STMTTRN>\n";
1138  if ($tranamount < 0) {
1139  if ($balinfo['deposittype'] == 'Y' && $check != 0) {
1140  $ofxString .= "<TRNTYPE>CHECK\n";
1141  } else {
1142  $ofxString .= "<TRNTYPE>DEBIT\n";
1143  }
1144  } else {
1145  $ofxString .= "<TRNTYPE>CREDIT\n";
1146  }
1147  $date = str_replace("-", "", $detl["date"]);
1148  $ofxString .= "<DTPOSTED>$date\n";
1149 # DTUSER not needed for 211?
1150  $ofxString .= "<DTUSER>$date\n";
1151  $ofxString .= "<TRNAMT>$tranamount\n";
1152  $ofxString .= "<FITID>{$detl['traceno']}\n";
1153  if ($balinfo['deposittype'] == 'Y' && $check != 0) {
1154  $ofxString .= "<CHECKNUM>$check\n";
1155  }
1156  $ofxString .= "<NAME>$shortdesc\n";
1157  if (strlen($longdesc) > 32) {
1158  $ofxString .= "<MEMO>$longdesc\n";
1159  }
1160  $ofxString .= "</STMTTRN>\n";
1161  }
1162  }
1163 # closing tags for transaction list
1164 
1165  $ofxString .= "</BANKTRANLIST>\n";
1166  $ofxString .= "<LEDGERBAL>\n";
1167  $ofxString .= "<BALAMT>{$balinfo['currentbal']}\n";
1168  $ofxString .= "<DTASOF>$now\n";
1169  $ofxString .= "</LEDGERBAL>\n";
1170 
1171 # closing tags for account info
1172  $ofxString .= "</STMTRS>\n</STMTTRNRS>\n";
1173  } # end of foreach(balances['dp']
1174 
1175  $ofxString .= "</BANKMSGSRSV1>\n";
1176  }
1177 
1178  $ofxString .= "</OFX>\n";
1179 
1180  return $ofxString;
1181 }
1182 
1183 // This is the original OFX 1.0 spec download.
1184 // NOTES: The XML is unbalanced on purpose, and the header is non-XML.
1185 function OFXDown1($HB_ENV, $datalist, $format) {
1186  $now = ofxdate();
1187  $sqlStart = $datalist["cuinfo"]["sqlstart"];
1188  $sqlEnd = $datalist["cuinfo"]["sqlend"];
1189  $ofxString = "";
1190  if ( $format == "mny" ) {
1191  $ofxString .= <<<EOF
1192 OFXHEADER:100
1193 DATA:OFXSGML
1194 VERSION:102
1195 SECURITY:NONE
1196 ENCODING:USASCII
1197 CHARSET:1252
1198 COMPRESSION:NONE
1199 OLDFILEUID:NONE
1200 NEWFILEUID:NONE
1201 EOF;
1202  } else {
1203  $ofxString .= <<<EOF
1204 OFXHEADER: 100
1205 DATA: OFXSGML
1206 VERSION: 102
1207 SECURITY: NONE
1208 ENCODING: USASCII
1209 CHARSET: 1252
1210 COMPRESSION: NONE
1211 OLDFILEUID: NONE
1212 NEWFILEUID: NONE
1213 EOF;
1214  }
1215 
1216  $ofxString .= <<< EOF
1217 
1218 <OFX>
1219  <SIGNONMSGSRSV1>
1220  <SONRS>
1221  <STATUS>
1222  <CODE>0
1223  <SEVERITY>INFO
1224  </STATUS>
1225  <DTSERVER>$now
1226  <LANGUAGE>ENG
1227  <DTACCTUP>19900101000000
1228  <FI>
1229  <ORG>{$datalist['cuinfo']['orgname']}
1230  <FID>{$datalist['cuinfo']['fid']}
1231  </FI>
1232 EOF;
1233 
1234  if ($HB_ENV['HCUPOST']['downfmt'] == 'qfx') {
1235  $ofxString .= "\n<INTU.BID>{$datalist['cuinfo']['fid']}\n<INTU.USERID>{$HB_ENV['Cn']}";
1236  }
1237 
1238  $ofxString .= "\n </SONRS>\n </SIGNONMSGSRSV1>\n";
1239 
1240  $ofxString .= " <BANKMSGSRSV1>\n";
1241 
1242  if (HCU_array_key_exists("dp", $datalist['balances']) && sizeof($datalist['balances']["dp"])) {
1243  foreach ($datalist['balances']["dp"] as $balkey => $acctdetls) {
1244  $tbl = substr($balkey, 0, 1);
1245  switch ($tbl) {
1246  case "D":
1247 
1248 #
1249  $desc = "{$acctdetls['description']} - {$acctdetls['accounttype']} {$acctdetls['certnumber']}";
1250  $desc = hcu_displayHtml( $desc, ENT_NOQUOTES );
1251  $type = ($acctdetls['certnumber'] == "0" ? $acctdetls['accounttype'] : "{$acctdetls['accounttype']}_{$acctdetls['certnumber']}");
1252  if (($HB_ENV['Fset2'] & GetFlagsetValue("CU2_OFX_MEMACCTID")) == GetFlagsetValue("CU2_OFX_MEMACCTID")) {
1253  $acctid = "{$HB_ENV['Cn']}-{$type}";
1254  } else {
1255  $acctid = $type;
1256  }
1257  $acctid = hcu_displayHtml( $acctid, ENT_NOQUOTES );
1258  $trbal = $acctdetls["availablebal"];
1259 
1260  switch ($acctdetls['deposittype']) {
1261  case "Y":
1262  $accttype = "CHECKING";
1263  break;
1264  case "C": # Certificates
1265  $accttype = "INVESTMENT";
1266  break;
1267  case "I": # IRA accounts
1268  $accttype = "RETIREMENT";
1269  break;
1270  case "N":
1271  case "S":
1272  $accttype = "SAVINGS";
1273  break;
1274  }
1275 
1276  break;
1277  case "L":
1278  // currently (01/31/2014) not supported
1279  break;
1280  case "C":
1281  // currently (01/31/2014) not supported
1282  break;
1283  default:
1284  # error - unknown table type
1285  }
1286 
1287  // set up the actual response for the account
1288  $ofxString .= <<< EOF
1289  <STMTTRNRS>
1290  <TRNUID>0
1291  <STATUS>
1292  <CODE>0
1293  <SEVERITY>INFO
1294  </STATUS>
1295  <STMTRS>
1296  <CURDEF>USD
1297  <BANKACCTFROM>
1298  <BANKID>{$datalist['cuinfo']['rt']}
1299  <ACCTID>$acctid
1300  <ACCTTYPE>$accttype
1301  </BANKACCTFROM>
1302 EOF;
1303  // start the list of statement transactions
1304  $ofxString .= "\n";
1305  $ofxString .= <<< EOF
1306  <BANKTRANLIST>
1307  <DTSTART>{$sqlStart}120000
1308  <DTEND>$now
1309 EOF;
1310 
1311  $ofxString .= "\n";
1312 
1313  // loop through the transactions
1314  if (sizeof($datalist['txns'][$balkey])) {
1315  foreach ($datalist['txns'][$balkey] as $txn => $drow) {
1316  $check = HCU_array_key_exists("checkno", $drow) ? $drow['checkno'] : 0;
1317  $tranDesc = trim( $drow["description"] );
1318  $tranDesc = ($tranDesc == '' ? '.' : $tranDesc);
1319  if ($tranDesc < " " && $check != 0) {
1320  $tranDesc = "CHK";
1321  }
1322  $tranDesc = (preg_replace("/<BR>/", " ", $tranDesc));
1323  $tranDesc = (preg_replace("/&nbsp;/", "", $tranDesc));
1324 
1325  $tranAmount = sprintf("%.2f", $drow["amount"]);
1326 
1327  $trace = trim( $drow["traceno"] );
1328 
1329  // the date comes in as CCYY-MM-DD
1330  $txnDate = str_replace( "-" , "", $drow["date"] );
1331  $ofxString .= " <STMTTRN>\n";
1332  if ($tranAmount < 0) {
1333  if ($accttype == 'Y' and $check != 0) {
1334  $ofxString .= " <TRNTYPE>CHECK\n";
1335  $ofxString .= " <CHECKNUM>$check\n";
1336  } else {
1337  $ofxString .= " <TRNTYPE>DEBIT\n";
1338  }
1339  } else {
1340  $ofxString .= " <TRNTYPE>CREDIT\n";
1341  }
1342  $ofxString .= " <DTPOSTED>{$txnDate}120000\n";
1343  $ofxString .= " <DTUSER>{$txnDate}120000\n";
1344  $ofxString .= " <TRNAMT>$tranAmount\n";
1345  $ofxString .= " <FITID>$trace\n";
1346 
1347  $longDesc = htmlentities(html_entity_decode($tranDesc, ENT_NOQUOTES), ENT_NOQUOTES);
1348  $shortDesc = substr(htmlentities(html_entity_decode($tranDesc, ENT_NOQUOTES), ENT_NOQUOTES), 0, 31);
1349  $shortDesc = preg_replace('/&[^;]*$/', '', $shortDesc);
1350  $shortDesc = (trim($shortDesc) == '' ? '.' : $shortDesc);
1351  $ofxString .= " <NAME>$shortDesc\n";
1352 
1353  if (strlen($longDesc) > 32) {
1354  $ofxString .= " <MEMO>$longDesc\n";
1355  }
1356  $ofxString .= " </STMTTRN>\n";
1357  }
1358  }
1359  }
1360  } else {
1361  // loan/cc not supported, set trbal to 0 to avoid console warning
1362  $trbal = 0;
1363  }
1364 
1365  $olbal=sprintf("%.2f",$trbal);
1366  $ofxString .= <<< EOF
1367  </BANKTRANLIST>
1368  <LEDGERBAL>
1369  <BALAMT>$olbal
1370  <DTASOF>$now
1371  </LEDGERBAL>
1372  </STMTRS>
1373  </STMTTRNRS>
1374  </BANKMSGSRSV1>
1375 </OFX>
1376 EOF;
1377 # end download data
1378 
1379  return $ofxString;
1380 }
1381 
1382 #
1383 
1384 /*
1385  * Because CSV has different headers for different account types, only one account type at a time.
1386  */
1387 function CSVDown($HB_ENV, $MC, $datalist) {
1388  $ostring = "";
1389  $multipleAccounts = false;
1390  if ( count( $datalist["txns"] ) > 1 ) {
1391  $ostring .= "\"Account\",\"Date\",\"Check\",\"Description\",\"Amount\"\r\n";
1392  $multipleAccounts = true;
1393  }
1394 
1395  if (HCU_array_key_exists("dp", $datalist['balances']) && sizeof($datalist['balances']['dp'])) {
1396  foreach ($datalist['balances']['dp'] as $acctid => $acctdetls) {
1397  if ( !$multipleAccounts ) {
1398  $ostring .= "\"{$MC->msg('Account', HCU_DISPLAY_AS_RAW)}\",\"{$MC->msg('Date', HCU_DISPLAY_AS_RAW)}\",";
1399  if ($acctdetls['deposittype'] == 'Y') {
1400  $ostring .= "\"{$MC->msg('Check', HCU_DISPLAY_AS_RAW)}\",";
1401  }
1402  $ostring .= "\"{$MC->msg('Description', HCU_DISPLAY_AS_RAW)}\",\"{$MC->msg('Amount', HCU_DISPLAY_AS_RAW)}\",\"{$MC->msg('Balance', HCU_DISPLAY_AS_RAW)}\"\r\n";
1403  }
1404 
1405  if (sizeof($datalist['txns'][$acctid])) {
1406  $baldesc = trim( $acctdetls['description'] );
1407  if ( strlen( trim( $acctdetls['accounttype'] . $acctdetls['certnumber'] ) ) > 0 ) {
1408  $baldesc .= " - {$acctdetls['accounttype']} {$acctdetls['certnumber']}";
1409  }
1410 
1411  // IF CUSTOMIZED ACCOUNT NAME EXISTS, USE IT
1412  if (strlen($acctdetls['displayname']) > 0) {
1413  $baldesc = $acctdetls['displayname'];
1414  }
1415 
1416  foreach ($datalist['txns'][$acctid] as $key => $drow) {
1417  $drow['description'] = (str_replace("<BR>", " ", $drow['description']));
1418  $drow['description'] = (str_replace("&nbsp;", " ", $drow['description']));
1419  $check = HCU_array_key_exists("checkno", $drow) ? $drow['checkno'] : 0;
1420  if ( $multipleAccounts ) {
1421  // output as just the single header showed
1422  $tranamount = str_replace( ",", "", str_replace( "$", "", $drow['amount'] ) );
1423  $tranamount = sprintf( "%.2f", $tranamount );
1424  $check = HCU_array_key_exists("checkno", $drow) ? $drow['checkno'] : 0;
1425  $ostring .= "\"$baldesc\",\"{$drow['date']}\",\"$check\",\"{$drow['description']}\",\"$tranamount\"\r\n";
1426  } else {
1427  // output to match the header determined above
1428  $ostring .= "\"$baldesc\",\"{$drow['date']}\",";
1429  if ($acctdetls['deposittype'] == 'Y') {
1430  $check = HCU_array_key_exists("checkno", $drow) ? $drow['checkno'] : 0;
1431  $ostring .= "\"$check\",";
1432  }
1433  $ostring .= "\"{$drow['description']}\",\"{$drow['amount']}\",\"{$drow['balance']}\"\r\n";
1434  }
1435  }
1436  }
1437  }
1438  }
1439  if (HCU_array_key_exists("ln", $datalist['balances']) && sizeof($datalist['balances']['ln'])) {
1440  // if have multiple accounts, using the single header from earlier (less columns)
1441  if ( !$multipleAccounts ) {
1442  $ostring .= "\"{$MC->msg('Account', HCU_DISPLAY_AS_RAW)}\",\"{$MC->msg('Date', HCU_DISPLAY_AS_RAW)}\"";
1443  }
1444 
1445  // need to prepend a comma because don't know which fields are included, if any
1446  foreach ($datalist['balances']['ln'] as $acctid => $acctdetls) {
1447  $baldesc = trim( $acctdetls['description'] );
1448  if ( strlen( trim( $acctdetls['loan'] ) ) > 0 ) {
1449  $baldesc .= " - {$acctdetls['loan']}";
1450  }
1451 
1452  // IF CUSTOMIZED ACCOUNT NAME EXISTS, USE IT
1453  if (strlen($acctdetls['displayname']) > 0) {
1454  $baldesc = $acctdetls['displayname'];
1455  }
1456 
1457  if ( sizeof( $datalist["txns"][$acctid] ) ) {
1458  if ( !$multipleAccounts ) {
1459  // get a list of fields from first txn to see what is being outputted
1460  $txnIds = array_keys($datalist['txns'][$acctid]);
1461  $fldlist = array_keys($datalist['txns'][$acctid][$txnIds[0]]);
1462 
1463  if (in_array("description", $fldlist)) {
1464  $ostring .= ",\"{$MC->msg('Description', HCU_DISPLAY_AS_RAW)}\"";
1465  }
1466  if (in_array("escrow", $fldlist)) {
1467  $ostring .= ",\"{$MC->msg('Escrow', HCU_DISPLAY_AS_RAW)}\"";
1468  }
1469  if (in_array("fee", $fldlist)) {
1470  $ostring .= ",\"{$MC->msg('Fees', HCU_DISPLAY_AS_RAW)}\"";
1471  }
1472  if (in_array("principal", $fldlist)) {
1473  $ostring .= ",\"{$MC->msg('Principal', HCU_DISPLAY_AS_RAW)}\"";
1474  $ostring .= ",\"{$MC->msg('Interest', HCU_DISPLAY_AS_RAW)}\"";
1475  $ostring .= ",\"{$MC->msg('Amount', HCU_DISPLAY_AS_RAW)}\"";
1476  } else {
1477  $ostring .= ",\"{$MC->msg('Payment', HCU_DISPLAY_AS_RAW)}\"";
1478  }
1479  if (in_array("balance", $fldlist)) {
1480  $ostring .= ",\"{$MC->msg('Balance', HCU_DISPLAY_AS_RAW)}\"";
1481  }
1482  $ostring .= "\r\n";
1483  }
1484  // now show all the data
1485  if (sizeof($datalist['txns'][$acctid])) {
1486  foreach ($datalist['txns'][$acctid] as $key => $drow) {
1487  $drow['description'] = (str_replace("<BR>", " ", $drow['description']));
1488  $drow['description'] = (str_replace("&nbsp;", " ", $drow['description']));
1489  $check = HCU_array_key_exists("checkno", $drow) ? $drow['checkno'] : 0;
1490  if ( $multipleAccounts ) {
1491  $check = HCU_array_key_exists("checkno", $drow) ? $drow['checkno'] : 0;
1492  $ostring .= "\"$baldesc\",\"{$drow['date']}\",\"$check\",\"{$drow['description']}\",\"{$drow['totalpay']}\"\r\n";
1493  } else {
1494  $ostring .= "\"$baldesc\",\"{$drow['date']}\"";
1495  if (in_array("description", $fldlist)) {
1496  $ostring .= ",\"{$drow['description']}\"";
1497  }
1498  if (in_array("escrow", $fldlist)) {
1499  $ostring .= ",\"{$drow['escrow']}\"";
1500  }
1501  if (in_array("fee", $fldlist)) {
1502  $ostring .= ",\"{$drow['fee']}\"";
1503  }
1504  if (in_array("principal", $fldlist)) {
1505  $ostring .= ",\"{$drow['principal']}\"";
1506  $ostring .= ",\"{$drow['interest']}\"";
1507  }
1508  $ostring .= ",\"{$drow['totalpay']}\"";
1509  if (in_array("balance", $fldlist)) {
1510  $ostring .= ",\"{$drow['balance']}\"";
1511  }
1512 
1513  $ostring .= "\r\n";
1514  }
1515  }
1516  }
1517  }
1518  }
1519  }
1520 
1521  if (HCU_array_key_exists("cc", $datalist['balances']) && sizeof($datalist['balances']['cc'])) {
1522  // if have multiple accounts, using the single header from earlier (less columns)
1523  if ( !$multipleAccounts ) {
1524  $ostring .= "\"{$MC->msg('Account', HCU_DISPLAY_AS_RAW)}\",\"{$MC->msg('Date', HCU_DISPLAY_AS_RAW)}\"";
1525  }
1526 
1527  foreach ($datalist['balances']['cc'] as $acctid => $acctdetls) {
1528  $baldesc = trim( $acctdetls['description'] );
1529  if ( strlen( trim( $acctdetls['accounttype'] . $acctdetls['certnumber'] ) ) > 0 ) {
1530  $baldesc .= " - {$acctdetls['accounttype']} {$acctdetls['certnumber']}";
1531  }
1532 
1533  // IF CUSTOMIZED ACCOUNT NAME EXISTS, USE IT
1534  if (strlen($acctdetls['displayname']) > 0) {
1535  $baldesc = $acctdetls['displayname'];
1536  }
1537 
1538  if ( sizeof( $datalist["txns"][$acctid] ) ) {
1539  if ( !$multipleAccounts ) {
1540  // get a list of fields from first txn to see what is being outputted
1541  $txnIds = array_keys($datalist['txns'][$acctid]);
1542  $fldlist = array_keys($datalist['txns'][$acctid][$txnIds[0]]);
1543  if (in_array("description", $fldlist)) {
1544  $ostring .= ",\"{$MC->msg('Description', HCU_DISPLAY_AS_RAW)}\"";
1545  }
1546  if (in_array("fee", $fldlist)) {
1547  $ostring .= ",\"{$MC->msg('Fees', HCU_DISPLAY_AS_RAW)}\"";
1548  }
1549  if (in_array("principal", $fldlist)) {
1550  $ostring .= ",\"{$MC->msg('Principal', HCU_DISPLAY_AS_RAW)}\"";
1551  $ostring .= ",\"{$MC->msg('Interest', HCU_DISPLAY_AS_RAW)}\"";
1552  }
1553  $ostring .= ",\"{$MC->msg('Amount', HCU_DISPLAY_AS_RAW)}\"";
1554  if (in_array("balance", $fldlist)) {
1555  $ostring .= ",\"{$MC->msg('Balance', HCU_DISPLAY_AS_RAW)}\"";
1556  }
1557  $ostring .= "\r\n";
1558  }
1559 
1560  // now show all the data
1561  if (sizeof($datalist['txns'][$acctid])) {
1562  foreach ($datalist['txns'][$acctid] as $key => $drow) {
1563  $drow['description'] = (str_replace("<BR>", " ", $drow['description']));
1564  $drow['description'] = (str_replace("&nbsp;", " ", $drow['description']));
1565  $check = HCU_array_key_exists("checkno", $drow) ? $drow['checkno'] : 0;
1566 
1567  if ( $multipleAccounts ) {
1568  $check = HCU_array_key_exists("checkno", $drow) ? $drow['checkno'] : 0;
1569  $ostring .= "\"$baldesc\",\"{$drow['date']}\",\"$check\",\"{$drow['description']}\",\"{$drow['totalpay']}\"\r\n";
1570  } else {
1571  $ostring .= "\"$baldesc\",\"{$drow['date']}\"";
1572  if (in_array("description", $fldlist)) {
1573  $ostring .= ",\"{$drow['description']}\"";
1574  }
1575  if (in_array("fee", $fldlist)) {
1576  $ostring .= ",\"{$drow['fee']}\"";
1577  }
1578  if (in_array("principal", $fldlist)) {
1579  $ostring .= ",\"{$drow['principal']}\"";
1580  $ostring .= ",\"{$drow['interest']}\"";
1581  }
1582  $ostring .= ",\"{$drow['totalpay']}\"";
1583  if (in_array("balance", $fldlist)) {
1584  $ostring .= ",\"{$drow['balance']}\"";
1585  }
1586 
1587  $ostring .= "\r\n";
1588  }
1589  }
1590  }
1591  }
1592  }
1593  }
1594 
1595  return $ostring;
1596 }
1597 
1598 function QIFDown($HB_ENV, $datalist) {
1599  # only one account at a time for QIF
1600 
1601  $ostring = "";
1602  if (HCU_array_key_exists("dp", $datalist['balances']) && sizeof($datalist['balances']['dp'])) {
1603 
1604  foreach ($datalist['balances']['dp'] as $acctid => $acctdetls) {
1605  $baldesc = "{$acctdetls['description']} - {$acctdetls['accounttype']} {$acctdetls['certnumber']}";
1606 
1607  // IF CUSTOMIZED ACCOUNT NAME EXISTS, USE IT
1608  if (strlen($acctdetls['displayname']) > 0) {
1609  $baldesc = $acctdetls['displayname'];
1610  }
1611 
1612  $ostring .="!Account\r\nTBank\r\nN$baldesc\r\n^\r\n";
1613  $ostring .="!Type:Bank\r\n";
1614  if (sizeof($datalist['txns'][$acctid])) {
1615  foreach ($datalist['txns'][$acctid] as $key => $drow) {
1616 
1617  $drow['description'] = (str_replace("<BR>", " ", $drow['description']));
1618  $drow['description'] = (str_replace("&nbsp;", " ", $drow['description']));
1619  $check = HCU_array_key_exists("checkno", $drow) ? $drow['checkno'] : 0;
1620  $date = $drow['date'];
1621  $date = (substr($date, 5, 2) . "/" . substr($date, 8, 2) . "/" . substr($date, 0, 4));
1622  $check = HCU_array_key_exists("checkno", $drow) ? $drow['checkno'] : 0;
1623  $ostring .= "D$date\r\nN$check\r\nP{$drow['description']}\r\nCC\r\nT{$drow['amount']}\r\n^\r\n";
1624  }
1625  }
1626  }
1627  }
1628  if (HCU_array_key_exists("ln", $datalist['balances']) && sizeof($datalist['balances']['ln'])) {
1629 
1630  foreach ($datalist['balances']['ln'] as $acctid => $acctdetls) {
1631  $baldesc = "{$acctdetls['description']} - {$acctdetls['loan']}";
1632 
1633  // IF CUSTOMIZED ACCOUNT NAME EXISTS, USE IT
1634  if (strlen($acctdetls['displayname']) > 0) {
1635  $baldesc = $acctdetls['displayname'];
1636  }
1637 
1638  $ostring .="!Account\r\nTOth L\r\nN$baldesc\r\n^\r\n";
1639  $ostring .="!Type:Oth L\r\n";
1640 
1641  if (sizeof($datalist['txns'][$acctid])) {
1642  foreach ($datalist['txns'][$acctid] as $key => $drow) {
1643  $date = $drow['date'];
1644  $date = (substr($date, 5, 2) . "/" . substr($date, 8, 2) . "/" . substr($date, 0, 4));
1645  $ostring .= "D$date\r\n";
1646  if (trim($drow['description']) != '') {
1647  $drow['description'] = (str_replace("<BR>", " ", $drow['description']));
1648  $drow['description'] = (str_replace("&nbsp;", " ", $drow['description']));
1649  $ostring .= "P{$drow['description']}\r\n";
1650  }
1651  $ostring .= "CC\r\n";
1652  if (HCU_array_key_exists("fee", $drow) && trim($drow['fee']) != '') {
1653  $ostring .= "EFees\r\n\${$drow['fee']}\r\n";
1654  }
1655  if (HCU_array_key_exists("principal", $drow) && trim($drow['principal']) != '') {
1656  $ostring .= "EPrincipal\r\n\${$drow['principal']}\r\n";
1657  }
1658  if (HCU_array_key_exists("interest", $drow) && trim($drow['interest']) != '') {
1659  $ostring .= "EInterest\r\n\${$drow['interest']}\r\n";
1660  }
1661  $ostring .= "T{$drow['totalpay']}\r\n";
1662  $ostring .= "^\r\n";
1663  }
1664  }
1665  }
1666  }
1667  if (HCU_array_key_exists("cc", $datalist['balances']) && sizeof($datalist['balances']['cc'])) {
1668 
1669  foreach ($datalist['balances']['cc'] as $acctid => $acctdetls) {
1670  $baldesc = "{$acctdetls['description']} - {$acctdetls['loan']}";
1671 
1672  // IF CUSTOMIZED ACCOUNT NAME EXISTS, USE IT
1673  if (strlen($acctdetls['displayname']) > 0) {
1674  $baldesc = $acctdetls['displayname'];
1675  }
1676 
1677  $ostring .="!Account\r\nTCCard\r\nN$baldesc\r\n^\r\n";
1678  $ostring .="!Type:Oth L\r\n";
1679 
1680  if (sizeof($datalist['txns'][$acctid])) {
1681  foreach ($datalist['txns'][$acctid] as $key => $drow) {
1682  $date = $drow['date'];
1683  $date = (substr($date, 5, 2) . "/" . substr($date, 8, 2) . "/" . substr($date, 0, 4));
1684  $ostring .= "D$date\r\n";
1685  if (trim($drow['description']) != '') {
1686  $drow['description'] = (str_replace("<BR>", " ", $drow['description']));
1687  $drow['description'] = (str_replace("&nbsp;", " ", $drow['description']));
1688  $ostring .= "P{$drow['description']}\r\n";
1689  }
1690  $ostring .= "CC\r\n";
1691  if (trim($drow['fee']) != '') {
1692  $ostring .= "EFees\r\n\${$drow['fee']}\r\n";
1693  }
1694  if (trim($drow['principal']) != '') {
1695  $ostring .= "EPrincipal\r\n\${$drow['principal']}\r\n";
1696  }
1697  if (trim($drow['interest']) != '') {
1698  $ostring .= "EInterest\r\n\${$drow['interest']}\r\n";
1699  }
1700  $ostring .= "T{$drow['totalpay']}\r\n";
1701  $ostring .= "^\r\n";
1702  }
1703  }
1704  }
1705  }
1706 
1707  return $ostring;
1708 }
1709 
1710 function sqldate($date) {
1711 
1712  if (strtolower($date) == "now" || strtolower($date) == "today") {
1713  $date = date("m/d/Y");
1714  }
1715  # only allow 0-9 and dash(-)
1716  if (preg_match("/[^0-9\-\/ ]/", $date)) {
1717  return false;
1718  }
1719  list ($mm, $dd, $yy) = preg_split('#[-/]#', $date);
1720  $mm = sprintf('%02d', intval($mm));
1721  $dd = sprintf('%02d', intval($dd));
1722  if (strlen($yy) > 0 && strlen($yy) < 4) {
1723  $yy = ($yy < 70 ? 2000 + $yy : 1900 + $yy);
1724  }
1725  $yy = sprintf('%04d', intval($yy));
1726  if (checkdate($mm, $dd, $yy)) {
1727  return "${yy}${mm}${dd}";
1728  } else {
1729  return false;
1730  }
1731 }
1732 
1733 function ofxdate() {
1734  list ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $idist) = localtime();
1735  $year = ($year < 1900 ? $year + 1900 : $year);
1736  $mon = $mon + 1;
1737  return sprintf("%04d%02d%02d%02d%02d%02d", $year, $mon, $mday, $hour, $min, $sec);
1738 }
1739 
1740 function mdydate() {
1741  list ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $idist) = localtime();
1742  $year = ($year < 1900 ? $year + 1900 : $year);
1743  $mon = $mon + 1;
1744  return sprintf("%02d/%02d/%04d", $mon, $mday, $year);
1745 }
1746 
1747 
1748 ?>