Odyssey
stmtupload.prg
1 <?php
2  // This file will upload a file for the credit union
3  // It will perform the following functions
4 
5  // Process File
6  // Redirect User
7  // Exit File Exists
8  // Exist Size Error
9  // Print a form for upload
10 
11  require_once ("$admLibrary/ck_aticket.i"); // Just a precaution to make sure that it is processed through the cookie
12 
13 /**
14  * function GetSelf()
15  * @return The URL of this script.
16  */
17 function GetSelf() {
18  return "main.prg?ft=86";
19 }
20 
21 $string= array("filter" => FILTER_DEFAULT);
22 $parameters = array("a" => array());
23 HCU_ImportVars($parameters, "a", array("action" => $string, "period" => $string));
24 extract($parameters["a"]);
25 
26 $action = isset($action) ? trim($action) : "";
27 $period = isset($period) ? trim($period) : "";
28 
29  $ccname = 'CREDIT CARD';
30  if (preg_match("/^$ccname/",$period)) {
31  $saved_file = "$home_path/tmp/{$chome}ccard.daz";
32  } else {
33  $saved_file = "$home_path/tmp/{$chome}stmnt.daz";
34  }
35 
36  // Check to make sure when they upload a file that a valid period is selected
37  if ($action != '') {
38  if (!$period || $period == 'Select') {
39  $msg = "You must select a Statement Period.";
40  $action = ""; // Force the action to blank so it falls through the default section
41  }
42  }
43  switch ($action) {
44  case "uploadFile":
45  $fileArray = $_FILES["files"]; // With only one file, the array is that file.
46  // Don't allow a file size of 0 bytes
47  if (!is_uploaded_file($fileArray['tmp_name']) || ($fileArray['size'] < 1)) {
48  // A problem occurred record the information that I know and mail it to mark@homecu.net
49  // Gather msg together
50  switch ($fileArray['error']) {
51  case 0:
52  $up_err = "0: No error, the file was uploaded successfully";
53  break;
54  case 1:
55  $up_err = "1: The upload is larger than the amount allowable by the upload_max_filesize directive in the php.ini";
56  break;
57  case 2:
58  $up_err = "2: The upload is larger than the MAX_FILE_SIZE directive that was specified via html";
59  break;
60  case 3:
61  $up_err = "3: The file was only partially uploaded";
62  break;
63  case 3:
64  $up_err = "4: no file was uploaded";
65  break;
66  default:
67  $up_err = "NOT SET";
68  }
69  $up_fe = (!file_exists("{$fileArray['tmp_name']}") ? "True" : "False");
70  $msg = "
71 Upload File Error --\n
72 Client Information \n
73  Client Filename: {$fileArray['name']}\n
74  Client Filesize: {$fileArray['size']}\n
75  Client Filetype: {$fileArray['type']}\n\n
76  Client IP: {$_SERVER['REMOTE_ADDR']}\n\n
77 Web Server Information \n
78  Temp File Name - {$fileArray['tmp_name']}
79  Temp File exist - $up_fe\n
80  Error Reported - $up_err\n\n
81 
82  ";
83  $notify = new ErrorMail;
84  $notify->line = __LINE__;
85  $notify->file = __FILE__;
86  $notify->callingfunction = __FUNCTION__;
87  $notify->sql = $msg;
88  $notify->cu = "$Cu";
89  $notify->survey = "";
90  $notify->mailto = "mark@homecu.net";
91  $notify->SendErr();
92  // IF we got here, the file is NOT an uploaded file report an error
93 
94  // An error may occur here if the file is too large, this can be set in the php.ini file the variable is upload_max_filesize
95  header('Content-type: text/plain');
96  print HCU_JsonEncode(array("error" => array("File could not be uploaded. Please retry.", "If the problem persists call HomeCU and report the problem."), "code" => 1));
97  } else {
98  $real_name = "";
99  $find_ary = array("\\", "/", " ", ";"); // Create the list of characters for replacement
100  $rpl_ary = array("", "", "", ""); // Create the list of characters that will be replacing
101 
102  $real_name = str_replace($find_ary, $rpl_ary, $fileArray['name']);
103 
104  // Now move the file from the temporary position into the credit unions /tmp directory
105  if (!move_uploaded_file($fileArray['tmp_name'], $saved_file)) {
106  unlink ($fileArray['tmp_name']);
107  } else {
108  // File was moved change the mod settings
109  $rc = @chmod($saved_file, 0644);
110  }
111 
112 
113  // MWS 2/27/03 -- before executing set the environment path for the users e-mail address
114  $sql = "SELECT email FROM cuadmnotify
115  WHERE cu = '$Cu' AND role = 'esload'";
116  $em_rs = db_query($sql, $dbh);
117  list($esload) = db_fetch_array($em_rs, 0);
118  db_free_result($em_rs);
119 
120  $sql = "SELECT email FROM cuadminusers
121  WHERE cu = '$Cu' AND user_name = '$Cn' ";
122  $em_rs = db_query($sql, $dbh);
123  list($email) = db_fetch_array($em_rs, 0);
124  db_free_result($em_rs);
125  if (trim($email) != '') { $esload = no_dupes("$email;$esload"); }
126  putenv("ADMMAIL=$esload");
127 
128 /*
129  * if $period starts with $ccname case insensitive, call the credcardload.pl script
130  * eventually, if $period is for tax forms (1099 or 1098) call the taxformload.pl script
131  */
132 
133  $scriptDir = GetScriptDir();
134  // The file was moved successfully
135  if (preg_match("/^$ccname/",$period)) {
136  $command = "/usr/bin/nice -19 /usr/bin/env perl $scriptDir/ccardload.pl " . escapeshellcmd($home_path) ." \"{$period}\" >/dev/null &";
137  } else {
138  $command = "/usr/bin/nice -19 /usr/bin/env perl $scriptDir/stmntload.pl " . escapeshellcmd($home_path) ." \"{$period}\" >/dev/null &";
139  }
140 
141  $rc = exec ($command);
142 
143  // Now set a cookie for the filename that was last uploaded
144  HCU_setcookie_env($SYSENV, "LastStmtName", $fileArray['name'], time()+60*60*24*30);
145 
146 
147  header('Content-type: text/plain');
148  print HCU_JsonEncode(array("error" => array(), "code" => 0, "data" => array("name" => $fileArray["name"], "size" => $fileArray["size"])));
149 
150  }
151  break;
152  default:
153 
154  // This is the default, which is to print the multi-part form for uploading
155  # first, make sure the configuration file and the stmnt director exist
156  if (!(is_readable("$home_path/bin/stmntload.cfg")
157  && is_dir("$home_path/stmnt"))) {
158  # give error
159  PrintFirstUploaded();
160 
161  } else {
162  $lastUploadedFile = HCU_array_key_value('LastStmtName', $_COOKIE);
163  $lastUploadedFile = $lastUploadedFile ? trim($lastUploadedFile) : "";
164 
165  $scriptDir = GetScriptDir();
166  $command = "/usr/bin/nice -19 /usr/bin/env perl $scriptDir/stmntload_running_status.pl " . strtolower($Cu);
167  $commandRs = exec($command);
168  $commandStatusAry = explode("\t", $commandRs);
169  $commandStatus = trim($commandStatusAry[0]);
170 
171  $lastUploadedStatus = 0;
172  switch ($commandStatus) { // index 0 should always be our cases
173  case 'Error':
174  case 'Abort':
175  $lastUploadedStatus = 1; // failed during processing
176  break;
177  case 'Running':
178  $lastUploadedStatus = 2; // waiting or in processing
179  break;
180  case 'Norm/0':
181  case 'Undo/0':
182  default:
183  $lastUploadedStatus = 0; // success / no uploaded files
184  break;
185  }
186 
187  // There is a 60 second delay before the upload process actually begins,
188  // we must check for the existence of the .daz file.
189 
190  // If the .daz file exists, the upload process is currently running
191  $cuLower = strtolower($Cu);
192  if (is_dir("$home_path/tmp") && file_exists("$home_path/tmp/{$cuLower}stmnt.daz")) {
193  $lastUploadedStatus = 2;
194  }
195 
196  PrintSelectUpload($lastUploadedFile, $lastUploadedStatus, GetPeriodData($home_path));
197  break;
198  }
199  }
200 
201 /**
202  * function no_dupes($estring)
203  * Function to check for duplicates in the eStatement string.
204  *
205  * @param $estring -- the eStatement string.
206  * @return A string of eStatements.
207  */
208 function no_dupes($estring) {
209  $return = ""; // Prevent E_NOTICE.
210  foreach (explode(";",$estring) as $x => $ema) {
211  $ema = trim($ema);
212  if ($ema != "" && (strpos("$return","$ema") === false)) {
213  $return .= "$ema;";
214  }
215  }
216  return $return;
217 }
218 
219 /**
220  * function return_bytes($val)
221  * Function to return the bytes.
222  *
223  * @param $val -- the previous value.
224  * @return The value in bytes.
225  */
226 function return_bytes($val) {
227  $val = trim($val);
228  $last = strtolower($val[strlen($val)-1]);
229  switch($last) {
230  // The 'G' modifier is available since PHP 5.1.0
231  case 'g':
232  $val *= 1000;
233  case 'm':
234  $val *= 1000;
235  case 'k':
236  $val *= 1000;
237  }
238  return $val;
239 }
240 
241 /**
242  * function GetPeriodData($home_path)
243  * This function replaces the old code for separating out data from the presentation. Old code printed out HTML. This is sent to a kendo Drop Down List.
244  *
245  * @param $home_path -- Where files for the CU live.
246  * @return $periods -- Array of the options (text only.) If credit cards are configured, then those show up in the list as well.
247  */
248 function GetPeriodData($home_path) {
249  $periodData = array();
250  $ccname = GetCCName();
251 
252  $date = new DateTime();
253  $thisyr = intval($date->format("Y"));
254  $thisday = intval($date->format("d"));
255  $thisMonthAbbrev = $date->format("M");
256  $thismo = intval($date->format("n")) - 1;
257 
258  $date->modify("first day of last month");
259  $lastmo = intval($date->format("n")) - 1;
260  $lastMonthAbbrev = $date->format("M");
261  $lastyr = intval($date->format("Y"));
262 
263  # Dec & after 24th, or Jan-May, or June & before 25th set 2nd half
264  if (($thismo == 11 && $thisday > 24) || $thismo < 5 || ($thismo == 5 && $thisday < 25)) {
265  $half = "2nd";
266  $halfyr = ($thismo == 11 ? $thisyr : $thisyr - 1);
267  } else {
268  $half = "1st";
269  $halfyr = $thisyr;
270  }
271 
272  $periods = array("Select");
273  $carpers = array();
274 
275  # if past mid month, show the current month
276  if ($thisday > 15) {
277  $periods[] = "$thisMonthAbbrev $thisyr";
278  $carpers[] = "$ccname $thisMonthAbbrev $thisyr";
279  }
280 
281  $periods[] = "$lastMonthAbbrev $lastyr";
282  $carpers[] = "$ccname $lastMonthAbbrev $lastyr";
283 
284  $quarter = intval($thismo / 3); // Get the calendar quarter we are in
285 
286  # if past mid month and current month ends a qtr, show the current quarter
287 
288  if ($thisday > 15 && $thismo % 3 == 2) {
289  $periods[] = "Quarter " . ($quarter + 1) . " $thisyr";
290  $carpers[] = "$ccname Quarter " . ($quarter + 1) . " $thisyr";
291  }
292 
293  switch ($quarter) {
294  case 0:
295  $periods[] = "Quarter 4 ". ($thisyr - 1);
296  $periods[] = "Quarter 3 ". ($thisyr - 1);
297  $carpers[] = "$ccname Quarter 4 ". ($thisyr - 1);
298  $carpers[] = "$ccname Quarter 3 ". ($thisyr - 1);
299  break;
300  case 1:
301  $periods[] = "Quarter 1 $thisyr";
302  $periods[] = "Quarter 4 ". ($thisyr - 1);
303  $carpers[] = "$ccname Quarter 1 $thisyr";
304  $carpers[] = "$ccname Quarter 4 ". ($thisyr - 1);
305  break;
306  default:
307  $periods[] = "Quarter $quarter $thisyr";
308  $periods[] = "Quarter " . ($quarter - 1) . " $thisyr";
309  $carpers[] = "$ccname Quarter $quarter $thisyr";
310  $carpers[] = "$ccname Quarter " . ($quarter - 1) . " $thisyr";
311  }
312 
313  $periods[] = "$half Half $halfyr";
314  $carpers[] = "$ccname $half Half $halfyr";
315 
316  # and now append so all Credit Card options are at the end of the list but only show if the credit card config is done
317  if (is_readable(GetCCConfig($home_path))) {
318  $periods = array_merge($periods, $carpers);
319  }
320 
321  return $periods;
322 }
323 
324 /**
325  * function PrintSelectUpload($lastUploadedFile, $periodData)
326  * Prints the page with kendo controls.
327  *
328  * @param $lastUploadedFile -- The value of the cookie to record that. If it is non-empty, then there will be a "Last File Uploaded" line.
329  * @param $periodData -- All the available options for the period Drop Down List.
330  * @return nothing but prints out the page.
331  */
332 function PrintSelectUpload($lastUploadedFile, $lastUploadedStatus, $periodData) { ?>
333 <script type="text/javascript">
334  <?php getShowWaitFunctions(); ?>
335  var maxSize = <?php echo return_bytes(ini_get("upload_max_filesize")); ?>;
336 
337  <?php
338  /**
339  * function OpenConfirmDialog(fileData)
340  * Opens up a dialog to show that the file was successful. If the dialog is not yet created, then also create it.
341  *
342  * @param fileData -- JSON array of the name and size of the file.
343  */
344  ?>
345  function OpenConfirmDialog(fileData) {
346  var dialog = $("#confirmDialog").data("kendoDialog");
347  if (dialog == null) {
348  dialog = $("<div id='confirmDialog'></div>").appendTo("body").kendoDialog({
349  actions: [
350  {
351  text: "Okay", primary: true,
352  action: function() {
353  location.reload();
354  }
355  }
356  ],
357  visible: false,
358  title: "File Successfully Uploaded"
359  }).data("kendoDialog");
360  }
361 
362  var template = kendo.template($("#confirmationTemplate").html());
363  dialog.content(template(fileData)).open();
364  }
365 
366  <?php
367  /**
368  * function Init()
369  * Initializes all the controls for the page.
370  */
371  ?>
372  function Init() {
373  $.homecuValidator.setup({formValidate:'statementUploadDiv', formStatusField: 'formValidateDiv'});
374 
375  <?php
376  /**
377  * @var uploader
378  * This is the kendo control for uploading the file. It handles the call to upload and sends along the period selected.
379  */
380  ?>
381  var uploader = $("#uploader").kendoUpload({
382  async: {
383  saveUrl: "<?php echo GetSelf(); ?>&action=uploadFile",
384  withCredentials: true,
385  autoUpload: false
386  },
387  multiple: false,
388  showFileList: true,
389  error: function(e)
390  {
391  hideWaitWindow();
392  var response = e.XMLHttpRequest.responseText;
393  $.homecuValidator.displayMessage("File upload failed.", $.homecuValidator.settings.statusError );
394  },
395  success: function(e)
396  {
397  hideWaitWindow();
398  if (e.response.code != 0) {
399  $.homecuValidator.displayMessage(e.response.error, $.homecuValidator.settings.statusError );
400  e.preventDefault();
401  return false;
402  } else {
403  OpenConfirmDialog(e.response.data);
404  }
405 
406  },
407  select: function(e) <?php // When a file is selected. If we can prevent at this level, then the user doesn't have to click on the upload to know that the file is invalid. ?>
408  {
409  var error = "";
410 
411  try {
412  var file = e.files[0];
413 
414  if (file.size > maxSize) {
415  throw "File exceeds the max size.";
416  }
417  } catch(err) {
418  error = err;
419  }
420 
421  if (error.length != "")
422  {
423  $.homecuValidator.displayMessage(error, $.homecuValidator.settings.statusError );
424  e.preventDefault();
425  return false;
426  }
427  },
428  upload: function(e) {
429  var error = "";
430  try {
431  if (periodDDL.value() == null || periodDDL.value() == "Select") {
432  throw "Period must be selected.";
433  }
434  var file = e.files[0];
435 
436  if (file.size > maxSize) {
437  throw "File exceeds the max size.";
438  }
439  } catch(err) {
440  error = err;
441  }
442 
443  if (error.length != "") {
444  $.homecuValidator.displayMessage(error, $.homecuValidator.settings.statusError );
445  e.preventDefault();
446  return false;
447  } else {
448  e.data = {period: periodDDL.value()};
449  showWaitWindow();
450  }
451  },
452  localization: {
453  select: "Select File"
454  }
455  }).data("kendoUpload");
456 
457  <?php
458  /**
459  * @var periodDDL
460  * This is the kendo control for selecting the period. It is checked to see if there is a selection on upload.
461  */
462  ?>
463  var periodDDL = $("#periodDDL").kendoDropDownList({
464  dataSource: {
465  data: <?php echo HCU_JsonEncode($periodData); ?>
466  },
467  autoWidth: true
468  }).data("kendoDropDownList");
469 
470  <?php
471  /**
472  * $(".clearBtn").click(function()
473  * This is the click event for the clear button. All it does is remove selections from the periodDDL and the uploader.
474  */
475  ?>
476  $(".clearBtn").click(function() {
477  uploader.clearAllFiles();
478  periodDDL.value("Select");
479  $.homecuValidator.validate(); <?php // Just clears the status div. ?>
480  });
481 
482  <?php
483  /**
484  * $(".uploadBtn").click(function()
485  * This is the click event for the upload button. First it will check to see if there are selections. After that, it starts the upload.
486  */
487  ?>
488  $(".uploadBtn").click(function() {
489  var errors = [];
490  if (uploader.getFiles().length == 0) {
491  errors.push("File must be selected.");
492  }
493  if (periodDDL.value() == null || periodDDL.value() == "Select") {
494  errors.push("Period must be selected.");
495  }
496 
497  if (errors.length > 0) {
498  $.homecuValidator.displayMessage(errors, $.homecuValidator.settings.statusError );
499  } else {
500  $.homecuValidator.validate();
501  uploader.upload();
502  }
503  });
504  }
505 
506  $(document).ready(function() {
507  Init();
508  });
509 </script>
510 <style>
511  #statementUploadDiv {
512  max-width: 900px;
513  margin-right: initial;
514  margin-left: initial;
515  }
516 
517  .k-clear-selected, .k-upload-selected, .k-upload-status {
518  display: none !important;
519  }
520 </style>
521 
522 <?php
523 /**
524  * <script type="text/x-kendo-template" id="confirmationTemplate">
525  * This is a kendo template for the successful file upload dialog.
526  */
527 ?>
528 <script type="text/x-kendo-template" id="confirmationTemplate">
529  <div class="container-fluid">
530  <div class="row hcuSpacer">
531  <div class="col-xs-12">
532  Thank you for the upload.
533  </div>
534  </div>
535  <div class="row hcuSpacer">
536  <div class="col-xs-12">
537  The file <b>#: name #</b> with a size of <b>#: size #</b> bytes was successfully uploaded. It is now being processed.
538  </div>
539  </div>
540  <div class="row hcuSpacer">
541  <div class="col-xs-12">
542  An email status will be sent to the Credit Union.
543  </div>
544  </div>
545  <div class="row hcuSpacer">
546  <div class="col-xs-12">
547  If there are any errors, please do not resend your file. Contact <b>HomeCU</b> for support.
548  </div>
549  </div>
550  </div>
551 </script>
552 <div class="container-fluid vsgPrimary hcu-template" id="statementUploadDiv">
553  <div class="row">
554  <div id="formValidateDiv" class="k-block k-error-colored formValidateDiv" style="display:none;"></div>
555  </div>
556  <div class="row hcuSpacer">
557  <h3 class="col-xs-12">Statement File Upload</h3>
558  </div>
559  <div class="well well-sm">
560  <?php if ($lastUploadedFile != "") { ?>
561  <div class="row hcuSpacer">
562  <label class="col-xs-12 col-sm-3">Last File Uploaded</label>
563  <div class="col-xs-12 col-sm-9">
564  <?php echo $lastUploadedFile; ?>
565 
566  <?php if ($lastUploadedStatus == 2) { ?>
567  <label>&nbsp;Processing...</label>
568  <?php } else if ($lastUploadedStatus == 1) { ?>
569  <label style="color: red;">&nbsp;Failed</label>
570  <?php } ?>
571  </div>
572  </div>
573  <?php if ($lastUploadedStatus == 2) { ?>
574  <div class="row hcuSpacer hcu-secondary">
575  <div class="col-xs-12 vsgSecondary hcu-note">Refresh the page to view the current processing status</div>
576  </div>
577  <?php } ?>
578  <?php } ?>
579 
580  <?php if ($lastUploadedStatus < 2) { ?>
581  <div class="row hcuSpacer">
582  <label class="col-xs-12 col-sm-3">File Uploader</label>
583  <div class="col-xs-12 col-sm-9">
584  <input type="file" name="files" id="uploader" />
585  </div>
586  </div>
587  <div class="row hcuSpacer">
588  <label class="col-xs-12 col-sm-3">
589  Statement Period
590  </label>
591  <div class="col-xs-12 col-sm-9">
592  <div id="periodDDL"></div>
593  </div>
594  </div>
595  <?php } ?>
596  </div>
597  <div class="row hcu-secondary hcuSpacer">
598  <div class="col-xs-12 vsgSecondary hcu-note">
599  The file you upload must include complete account numbers. If you have changed your settings to mask all or part of the account number,
600  your file will not load correctly and may result in presenting eStatement information to the WRONG member!
601  </div>
602  </div>
603  <?php if ($lastUploadedStatus < 2) { ?>
604  <div class="hcu-edit-buttons k-state-default tabFooter">
605  <a class="clearBtn" href="#">Clear</a>
606  &nbsp;&nbsp;&nbsp;
607  <a class="uploadBtn k-button k-primary" href="#">Upload</a>
608  </div>
609  <?php } ?>
610 </div>
611 <?php }
612 
613 /**
614  * function PrintFirstUploaded()
615  * This function is called when the e-statement directory is not set up or the config file isn't readable.
616  */
617 function PrintFirstUploaded() { ?>
618 <div class="container-fluid vsgPrimary hcu-template" id="statementUploadDiv">
619  <div class="row hcuSpacer">
620  <h3 class="col-xs-12">Statement File Upload</h3>
621  </div>
622  <div class="row hcuSpacer">
623  <div class="col-xs-12">It looks like this is the first time you've uploaded eStatements. The configuration files and directories could not be found.</div>
624  </div>
625  <div class="row hcuSpacer">
626  <div class="col-xs-12">Please check with HomeCU first to get things set up right.</div>
627  </div>
628 </div>
629 <?php }