Odyssey
hcuUserActivity.data
1 <?php
2  /**
3  * @package hcuUserActivity.data
4  *
5  * This gets the data for hcuUserActivity.prg in a json format.
6  */
7 
8  // ** SET SCRIPT LEVEL VARIABLES
9  $serviceShowInfo = false;
10  $serviceLoadMenu = false;
11  $serviceShowMenu = false;
12  $serviceAllowReadonly = true;
13 
14  // ** INCLUDE MAIN GLOBAL SCRIPT -- Handles security / global variable values
15  require_once(dirname(__FILE__) . '/../library/hcuService.i');
16 
17  // Include transfer scheduled to get interval lookup.
18  require_once(dirname(__FILE__) . '/../library/hcuTransferScheduled.i');
19  require_once(dirname(__FILE__) . '/../library/hcuTransfer.i');
20  require_once(dirname(__FILE__) . "/../library/hcuUserActivity.i");
21  require_once(dirname(__FILE__) . "/../../shared/library/hcuCommon.i");
22  $logger = $HB_ENV["SYSENV"]["logger"];
23 
24  try {
25  // *****************************************
26  // Step 1: get the confirm permissions for the features that we care about. If there are no confirm permissions and there are multiple users in the group, then throw an error.
27  $confirmPermissions = array();
28  $permissions = privPermGetAllFeatureRights($HB_ENV["dbh"], $HB_ENV, array("Uid" => $HB_ENV["Uid"]));
29  if (!intval($permissions["status"]["code"]) == 0) {
30  throw new exception($permissions["status"]["error"], 3);
31  }
32  $permissions = $permissions["data"][$HB_ENV["Uid"]];
33 
34  // Prevent the page from being accessible when the user doesn't have approve access to at least one feature.
35  $approvalFeatureList = getApprovalList();
36  $approvalFound = false;
37  foreach($permissions as $featureCode => $featureRecord) {
38  if (!in_array($featureCode, $approvalFeatureList)) {
39  continue; // Feature is irrelevant to this script.
40  }
41 
42  $approvalFound = $approvalFound || $featureRecord["confirm"];
43  $confirmPermissions[$featureCode] = $featureRecord["confirm"]; // Save the permission for later.
44  }
45 
46  if (!$approvalFound) {
47  $Cu = $HB_ENV["Cu"];
48  $Uid = $HB_ENV["Uid"];
49 
50  $sql = "select 'FOUND' from ${Cu}user a inner join ${Cu}user b on a.user_id = $Uid and a.group_id = b.group_id and a.user_id <> b.user_id";
51  $sth = db_query($sql, $HB_ENV["dbh"]);
52  if (!$sth) {
53  throw new exception("Check if multiple users found.", 5);
54  }
55  if (db_num_rows($sth) > 0) { // We care if there are multiple users. If it is one user, then user has the permissions to view the page.
56  throw new exception("No approval permissions found.", 4);
57  }
58  }
59 
60  // *******************************************
61  // Step 2: check to make sure that the right script is calling this script. This will only be the hcuUserActivity.prg script.
62  if (basename(parse_url($_SERVER['HTTP_REFERER'])["path"]) != "hcuUserActivity.prg") {
63  throw new exception("redirect check failed.", 2);
64  }
65 
66  // Step 3: get parameters from the request array
67  $string = array("filter" => FILTER_SANITIZE_STRING);
68  $parameters = array("a" => array("operation" => "", "grid" => "", "filterFeature" => "", "filterStatus" => "", "filterFrom" => "", "filterTo" => "", "type" => "", "dataId" => "",
69  "status" => "", "kendoId" => ""));
70  HCU_ImportVars($parameters, "a", array("operation" => $string, "grid" => $string, "filterFeature" => $string, "filterStatus" => $string, "filterFrom" => $string, "filterTo" => $string,
71  "type" => $string, "dataId" => $string, "status" => $string, "kendoId" => $string));
72  $operation = HCU_array_key_exists("operation", $parameters["a"]) ? trim($parameters["a"]["operation"]) : "";
73 
74  $genErr = str_replace(".", ":", $HB_ENV["MC"]->msg("ACH Query Error", HCU_DISPLAY_AS_RAW));
75 
76  // *************************************************
77  // Step 3: Find out which data call to actually do and do it.
78  $aryReply = array();
79  switch($operation) {
80  case "read":
81  $aryReply = readActivityGrid($HB_ENV, $genErr, $parameters["a"], $confirmPermissions, "read");
82  break;
83  case "filter":
84  $aryReply = readActivityGrid($HB_ENV, $genErr, $parameters["a"], $confirmPermissions, "filter");
85  break;
86  case "clearFilter":
87  $aryReply = readActivityGrid($HB_ENV, $genErr, $parameters["a"], $confirmPermissions, "clearFilter");
88  break;
89  case "setStatus":
90  $aryReply = setStatus($HB_ENV, $genErr, $parameters["a"], $confirmPermissions);
91  break;
92  case "local":
93  $aryReply = array("results" => array("mode" => "local", "homecuErrors" => array(), "homecuInfo" => array()));
94  break;
95  case "skipTransaction":
96  $aryReply = skipTransaction($HB_ENV, $genErr, $parameters["a"], $confirmPermissions);
97  break;
98  default: // Won't get here
99  throw new exception("operation undefined", 1);
100  }
101  }
102  catch(exception $e) {
103  $logger->error($e->getCode() . ": " . $e->getMessage());
104 
105  // Put dictionary entries in one place to throw whatever I want.
106  $err = "";
107  switch($e->getCode()) {
108  case 2:
109  case 3:
110  case 4:
111  case 5:
112  $err = $HB_ENV["MC"]->msg("Feature Unavailable", HCU_DISPLAY_AS_RAW);
113  break;
114  case 1:
115  default:
116  $err = $HB_ENV["MC"]->msg("ACH Unknown Action", HCU_DISPLAY_AS_RAW);
117  }
118  $aryReply = array("homecuErrors" => array($err), "homecuInfo" => array(), "homecuData" => array());
119  }
120  // End of global scope
121  // **********************************************
122 
123  // Functions for data calls
124  // ******************************************
125 
126  /**
127  * function skipTransaction($HB_ENV, $genErr, $parameters, $confirmPermissions)
128  * will skip the next scheduled trigger date for the transaction.
129  * Available statuses:
130  * 0 or null -- Awaiting approval
131  * 10 -- Approved
132  * 90 -- Declined
133  * 99 -- Cancelled
134  *
135  * @param $HB_ENV -- the environment variables. Contains the whole shebang.
136  * @param $genErr -- the error that the banking client will show if things aren't exactly stellar.
137  * @param $parameters -- from the $_REQUEST. array("type" => $type, "dataId" => $dataId, "status" => $status)
138  * $type -- from what table originally.
139  * $dataId -- the id of the table originally.
140  * $status -- the status to change the status to. See the available statuses.
141  * @param $confirmPermissions -- array of the confirm permissions of the features.
142  *
143  * @return array("results" => array("homecuInfo" => $homecuInfo, "homecuErrors" => $errors, "homecuData" => $gridData, "sqls" => $sqls));
144  * $results -- contains the whole shebang
145  * $homecuInfo -- contains one or zero messages ("successfully declined" or whatnot)
146  * $gridData -- contains the data for the grid to requery.
147  * $sqls -- the SQLs used.
148  */
149  function skipTransaction($HB_ENV, $genErr, $parameters, $confirmPermissions) {
150  // Extract the values that we need. Discard the rest.
151  $Cu = $HB_ENV["Cu"];
152  $MC = $HB_ENV["MC"];
153  $dbh = $HB_ENV["dbh"];
154  $Uid = $HB_ENV["Uid"];
155  $dataId = intval($parameters['dataId']);
156  $kendoId = intval($parameters['kendoId']);
157 
158  try {
159  $changeList = array($dataId);
160  $changeList = HCU_JsonEncode($changeList);
161  $txSkipSchedule = SkipTrans($dbh, $Cu, $Uid, $changeList, $MC);
162 
163  if ($txSkipSchedule['status'] !== "000") {
164  throw new Exception($MC->msg("Skip Transaction Error", HCU_DISPLAY_AS_RAW), $txSkipSchedule['status']);
165  }
166 
167  $parameters["grid"] = "scheduledTransactions";
168  $readResults = readActivityGrid($HB_ENV, $genErr, $parameters, $confirmPermissions, "filter")["results"];
169 
170  if (count($readResults["homecuErrors"]) > 0) {
171  throw new exception("filter failed.", 112);
172  }
173  $gridData = $readResults["homecuData"];
174 
175  $returnArray = array("results" => array("homecuInfo" => $MC->msg("Skip Transaction Success", HCU_DISPLAY_AS_RAW), "homecuErrors" => array(), "sqls" => "", "mode" => "skipTransaction", "dataId" => $dataId,"homecuData" => $gridData,"kendoId" => $kendoId));
176 
177  } catch (Exception $e) {
178  $returnArray = array("results" => array("homecuInfo" => array(), "homecuErrors" => array($e->getMessage()), "sqls" => "", "mode" => "skipTransaction", "dataId" => $dataId));
179  }
180 
181  return $returnArray;
182  }
183 
184  /**
185  * function setStatus($HB_ENV, $genErr, $parameters, $confirmPermissions)
186  * Changes the status from awaiting approval to something else. At this time, this is the only status that you can change.
187  * Available statuses:
188  * 0 or null -- Awaiting approval
189  * 10 -- Approved
190  * 90 -- Declined
191  * 99 -- Cancelled
192  *
193  * @param $HB_ENV -- the environment variables. Contains the whole shebang.
194  * @param $genErr -- the error that the banking client will show if things aren't exactly stellar.
195  * @param $parameters -- from the $_REQUEST. array("type" => $type, "dataId" => $dataId, "status" => $status)
196  * $type -- from what table originally.
197  * $dataId -- the id of the table originally.
198  * $status -- the status to change the status to. See the available statuses.
199  * @param $confirmPermissions -- array of the confirm permissions of the features.
200  *
201  * @return array("results" => array("homecuInfo" => $homecuInfo, "homecuErrors" => $errors, "homecuData" => $gridData, "sqls" => $sqls));
202  * $results -- contains the whole shebang
203  * $homecuInfo -- contains one or zero messages ("successfully declined" or whatnot)
204  * $gridData -- contains the data for the grid to requery.
205  * $sqls -- the SQLs used.
206  */
207  function setStatus($HB_ENV, $genErr, $parameters, $confirmPermissions) {
208 
209  // Extract the values that we need. Discard the rest.
210  $Cu = $HB_ENV["Cu"];
211  $MC = $HB_ENV["MC"];
212  $Cn = $HB_ENV["Cn"];
213  $dbh = $HB_ENV["dbh"];
214  $Uid = $HB_ENV["Uid"];
215  $logger = $HB_ENV["SYSENV"]["logger"];
216 
217  $sqls = array();
218  try {
219  extract($parameters);
220 
221  $type = isset($type) ? trim($type) : "";
222  $dataId = isset($dataId) ? intval($dataId) : 0;
223  $status = isset($status) ? intval($status) : 0;
224  $isSendCheck = isset($isSendCheck) ? $isSendCheck == "true" : false;
225 
226  switch($type) {
227  case "transhdr":
228  $table = "${Cu}transhdr";
229  break;
230  case "scheduled":
231  $table = "cu_scheduledtxn";
232  break;
233  default:
234  throw new exception("Table type is unexpected.", 101);
235  }
236 
237  if ($dataId <= 0) {
238  throw new exception("DataId needs to be greater than zero.", 102);
239  }
240 
241  $postedBy = $table == "cu_scheduledtxn" ? "user_id" : "posted_by";
242 
243  $sql = "select feature_code, $postedBy as posted_by, approved_status from $table where id = $dataId";
244  $sqls[] = $sql;
245  $sth = db_query($sql, $dbh);
246  if (!$sth) {
247  throw new exception("Select query failed.", 105);
248  }
249  if (db_num_rows($sth) == 0) {
250  throw new exception("Record is not found.", 106);
251  }
252  $record = db_fetch_assoc($sth, 0);
253  $record["approved_status"] = isset($record["approved_status"]) ? $record["approved_status"] : 0;
254 
255  if (!in_array($record["feature_code"], getApprovalList())) {
256  throw new exception("Feature code doesn't need approval.", 109);
257  }
258 
259  //if status is not approved and not editing from scheduled transactions grid
260  if ($record["approved_status"] != 0 && $parameters["grid"] != 'scheduledTransactions') {
261  throw new exception("At this time, approved status changes can only be from 'Awaiting Approval.'", 111);
262  }
263 
264  switch($status) {
265  case 10: // Approved
266  case 90: // Declined
267  if ($record["posted_by"] == $Uid) {
268  throw new exception("Cannot approve or decline a record posted by yourself.", 108);
269  }
270  if (!$confirmPermissions[$record["feature_code"]]) {
271  throw new exception("You cannot approve this record.", 110);
272  }
273  break;
274  case 99: // Cancelled
275  if ($record["posted_by"] != $Uid) {
276  throw new exception("Cannot cancel a record posted by someone else.", 107);
277  }
278  break;
279  default:
280  throw new exception("Status is unexpected.", 103);
281  }
282 
283  $transferData = null;
284  $repeatData = null;
285  $aryApprovalResults = array();
286 
287  if (!db_work ($dbh, HOMECU_WORK_BEGIN)) {
288  throw new exception("begin query failed.", 112);
289  }
290 
291  if ($status == 10 && $type == "transhdr"
292  && in_array(trim($record["feature_code"]), array(FEATURE_TRANSFERS, FEATURE_M2M_TRANSFERS))) { // If a regular transaction is approved, try to post it to the core.
293 
294  if (!ApproveTransfer($dbh, $HB_ENV, $MC, $dataId, $aryApprovalResults)) {
295  throw new exception($aryApprovalResults["status"]["errors"][0], 203);
296  }
297 
298  $HB_ENV["confirmationCode"] = $aryApprovalResults["status"]["confirm"];
299 
300  $transactionResults = array();
301  if (!ProcessTransfer($dbh, $HB_ENV, $MC, $dataId, $transactionResults, true)) {
302  // since there was an error posting to the core, we revert approval
303  // and commit only the cucorerequest record
304  RevertMarkAsApproved($dataId, $dbh, $Cu, 202);
305  // throw exception regardless of the RevertMarkAsApproved function
306  // would throw sql execution failure exception or not as we do not
307  // want to execute the code logic for successful transfer below
308  throw new exception($transactionResults["status"]["errors"][0], 202);
309  }
310 
311  // ** Successful transfer -- Need to return information..
312 
313  // Return the information to display to the user. Use the Posted date and confirmation regardless if needed confirmation or not.
314  $transferData = array(
315  array("label" => $MC->msg('Date', HCU_DISPLAY_AS_RAW), 'caption' => $transactionResults["txn"]["data_date"]),
316  array("label" => $MC->msg('Action', HCU_DISPLAY_AS_RAW), 'caption' => $transactionResults["txn"]["data_action"]),
317  array("label" => $MC->msg('From', HCU_DISPLAY_AS_RAW), 'caption' => $transactionResults["txn"]["data_from"]),
318  array("label" => $MC->msg('To', HCU_DISPLAY_AS_RAW), 'caption' => $transactionResults["txn"]["data_to"]),
319  array("label" => $MC->msg('Amount', HCU_DISPLAY_AS_RAW), 'caption' => "$" . mobile_formatnumber($transactionResults["txn"]["data_amount"]), ","),
320  array("label" => $MC->msg('Confirmation', HCU_DISPLAY_AS_RAW), 'caption' => $transactionResults["txn"]["data_confirm"])
321  );
322 
323  $message = $MC->msg("record approved", HCU_DISPLAY_AS_RAW);
324  } else if ($type == "scheduled") {
325 
326  $sql = "update cu_scheduledtxn set approved_by = " . intval($Uid) . ", approved_date = now(), approved_status = " . intval($status) . "
327  where id = " . intval($dataId) . " and cu = '" . prep_save(strtoupper($Cu), 10) . "'";
328  $sth = db_query($sql, $dbh);
329  if (!$sth) {
330  throw new exception ("Update query failed.", 207);
331  }
332 
333  $repeatData = $MC->msg('Repeating transfer scheduled', HCU_DISPLAY_AS_RAW) . ".";
334  } else if ($type == "transhdr") { // Cancel, decline transaction
335 
336  $sql = "update ${Cu}transhdr set approved_by = '" . intval($Uid) . "', approved_date = now(), approved_status = " . intval($status) . "
337  where id = " . intval($dataId);
338  $sth = db_query($sql, $dbh);
339  if (!$sth) {
340  throw new exception ("Update query failed.", 208);
341  }
342  }
343 
344  $status = $status == 10 ? "approved" : ($status == 99 ? "cancelled" : ($status == 90 ? "declined" : ""));
345  $message = $MC->msg("record $status", HCU_DISPLAY_AS_RAW);
346 
347  if (!db_work($dbh, HOMECU_WORK_COMMIT)) {
348  throw new exception("commit work failed.", 205);
349  }
350 
351  $returnArray = array("results" => array("homecuInfo" => array($message), "homecuErrors" => array(), "sqls" => $sqls, "mode" => "setStatus",
352  "dataId" => $dataId, "transferData" => $transferData, "repeatData" => $repeatData));
353  }
354  catch(exception $e) {
355  $logger->error($e->getCode() . ": " . $e->getMessage());
356 
357  if ($e->getCode() > 200) {
358  db_work($dbh, HOMECU_WORK_ROLLBACK); // Got greater problems if this fails.
359  $errors = array($MC->msg("Trans processing failure", HCU_DISPLAY_AS_HTML) . " " . $e->getMessage());
360  } else {
361  $errors = array("$genErr {$e->getCode()}.");
362  }
363 
364  $returnArray = array("results" => array("homecuInfo" => array(), "homecuErrors" => $errors, "sqls" => $sqls, "mode" => "setStatus", "dataId" => $dataId));
365  }
366 
367  $gridData = [];
368  try {
369  $parameters["grid"] = "priorActivity";
370  $readResults = readActivityGrid($HB_ENV, $genErr, $parameters, $confirmPermissions, "filter")["results"];
371  $sqls = array_merge($sqls, $readResults["sqls"]);
372 
373  if (count($readResults["homecuErrors"]) > 0) {
374  throw new exception("filter failed.", 112);
375  }
376  $gridData = $readResults["homecuData"];
377 
378  } catch(exception $e) {
379  $logger->error($e->getCode() . ": " . $e->getMessage());
380  }
381 
382  $returnArray["results"]["homecuData"] = $gridData;
383  $returnArray["results"]["kendoId"] = $kendoId;
384  return $returnArray;
385  }
386 
387  /**
388  * function getDefaultFilter(&$whereTranshdr, &$whereSched, $dbh, $Cu, $Cn, &$sqls)
389  * This function gets the default where clauses of the queries when the page is loaded.
390  *
391  * @param $whereTranshdr -- Overwrites this variable and sent to the query for getting regular transactions.
392  * @param $whereSched -- Overwrites this variable and sent to the query for getting scheduled transactions.
393  * @param $dbh -- the database connection.
394  * @param $Cu -- the credit union
395  * @param $Cn -- the logged in user
396  * @param $sqls -- the list of SQLs for the data call
397  */
398  function getDefaultFilter(&$whereTranshdr, &$whereSched, $dbh, $Cu, $Cn, $validUserIds) {
399  $approvalFeatureList = getApprovalList();
400  $whereTranshdr = "(t.approved_date >= now() - interval '7 days' or t.posted_date >= now() - interval '7 days')"
401  . "and t.feature_code in ('" . implode("','", $approvalFeatureList) . "') and t.posted_by in $validUserIds";
402  $whereSched = "(s.approved_date >= now() - interval '7 days' or s.create_date >= now() - interval '7 days' or now() <= s.end_date)"
403  . "and s.feature_code in ('" . implode("','", $approvalFeatureList) . "') and s.user_id in $validUserIds";
404  }
405 
406  /**
407  * function getFilter($parameters, $MC, $grid, &$whereTranshdr, &$whereSched)
408  * This function gets the filter parameters from the REQUEST and then append them to the queries for getting regular transactions and scheduled transactions.
409  *
410  * @param $parameters -- an array of all the parameters from the REQUEST.
411  * @param $MC -- the dictionary for translation.
412  * @param $grid -- the grid to get filters for: either "pendingApproval", "scheduledTransactions", or "priorActivity."
413  * @param $whereTranshdr -- the where clause for the regular transactions to append filter criteria to the query.
414  * @param $whereSched -- the where clause for the scheduled transactions to append filter criteria to the query.
415  * @param $dbh -- the database connection
416  * @param $Cu -- the credit union
417  */
418  function getFilter($parameters, $MC, $grid, &$whereTranshdr, &$whereSched, $dbh, $Cu, $Uid) {
419  $approvalFeatureList = getApprovalList();
420  extract($parameters);
421 
422  $feature = isset($filterFeature) ? trim($filterFeature) : "";
423  $status = isset($filterStatus) ? trim($filterStatus) : "";
424  $from = isset($filterFrom) ? trim($filterFrom) : "";
425  $to = isset($filterTo) ? trim($filterTo) : "";
426 
427  if ($from != "" && !DateTime::createFromFormat("Y-m-d", $from)) {
428  throw new exception("From date is invalid.", 203);
429  }
430  if ($to != "" && !DateTime::createFromFormat("Y-m-d", $to)) {
431  throw new exception("To date is invalid.", 206);
432  }
433 
434  $whereTranshdr = array();
435  $whereSched = array();
436  $whereBaseTranshdr = array();
437  $whereBaseSched = array();
438 
439  if ($status != "") {
440  $statusesApproved = getApprovalStatuses($MC);
441  $statusesActive = getActiveStatuses($MC);
442 
443  $statuses = array_merge(array(), $statusesApproved, $statusesActive);
444  $found = false;
445  foreach($statuses as $thisStatus) {
446  if ($thisStatus["value"] == $status) {
447  $found = true;
448  break;
449  }
450  }
451  if (!$found) {
452  throw new exception("Status is invalid.", 205);
453  }
454 
455  $whereBaseTranshdr[] = "t.approved_status = " . intval($status);
456 
457  if ($grid == "scheduledTransactions") {
458  $whereBaseSched[] = "s.status = '" . trim($status) . "'";
459  } else {
460  $whereBaseSched[] = "s.approved_status = " . intval($status);
461  }
462  }
463 
464  if ($feature != "") {
465  $features = getFeatures($dbh, $Cu, $sqls, $MC, $Uid);
466  $found = false;
467  foreach($features as $thisFeature) {
468  if (trim($thisFeature["value"]) == $feature) {
469  $found = true;
470  break;
471  }
472  }
473  if (!$found) {
474  throw new exception("Feature is invalid.", 206);
475  }
476 
477  $whereBaseTranshdr[] = "t.feature_code = '" . prep_save($feature, 10) . "'";
478  $whereBaseSched[] = "s.feature_code = '" . prep_save($feature, 10) . "'";
479  } else {
480  $whereBaseTranshdr[] = "t.feature_code in ('" . implode("','", $approvalFeatureList) . "')";
481  $whereBaseSched[] = "s.feature_code in ('" . implode("','", $approvalFeatureList) . "')";
482  }
483 
484  switch($grid) {
485  case "":
486  throw new exception("Grid is not set.", 201);
487  break;
488  case "scheduledTransactions":
489  if ($from != "") {
490  if (!HCU_array_key_exists("next_trigger_date", $whereSched)) {
491  $whereSched["next_trigger_date"] = array();
492  $whereSched["approved_date"] = array();
493  $whereSched["created_date"] = array();
494  }
495  $whereSched["next_trigger_date"][] = "s.next_trigger_date >= '$from'";
496  $whereSched["approved_date"][] = "s.approved_date >= '$from'";
497  $whereSched["created_date"][] = "s.create_date >= '$from'";
498  }
499  if ($to != "") {
500  if (!HCU_array_key_exists("next_trigger_date", $whereSched)) {
501  $whereSched["next_trigger_date"] = array();
502  $whereSched["approved_date"] = array();
503  $whereSched["created_date"] = array();
504  }
505  $whereSched["next_trigger_date"][] = "s.next_trigger_date <= '$to'";
506  $whereSched["approved_date"][] = "s.approved_date <= '$to'";
507  $whereSched["created_date"][] = "s.create_date <= '$to'";
508  }
509  break;
510  case "priorActivity":
511  if ($from != "") {
512  if (!HCU_array_key_exists("approved_date", $whereTranshdr)) {
513  $whereTranshdr["approved_date"] = array();
514  $whereTranshdr["posted_date"] = array();
515  $whereSched["approved_date"] = array();
516  $whereSched["created_date"] = array();
517  }
518 
519  $whereTranshdr["approved_date"][] = "t.approved_date >= '$from'";
520  $whereTranshdr["posted_date"][] = "t.posted_date >= '$from'";
521  $whereSched["approved_date"][] = "s.approved_date >= '$from'";
522  $whereSched["created_date"][] = "s.create_date >= '$from'";
523  }
524  if ($to != "") {
525  if (!HCU_array_key_exists("approved_date", $whereTranshdr)) {
526  $whereTranshdr["approved_date"] = array();
527  $whereTranshdr["posted_date"] = array();
528  $whereSched["approved_date"] = array();
529  $whereSched["created_date"] = array();
530  }
531 
532  $whereTranshdr["approved_date"][] = "t.approved_date <= '$to'";
533  $whereTranshdr["posted_date"][] = "t.posted_date <= '$to'";
534  $whereSched["approved_date"][] = "s.approved_date <= '$to'";
535  $whereSched["created_date"][] = "s.create_date <= '$to'";
536  }
537  break;
538  default:
539  throw new exception("Grid is invalid.", 207);
540  }
541 
542  $whereTranshdr = parseWhere($whereTranshdr, $whereBaseTranshdr);
543  $whereSched = parseWhere($whereSched, $whereBaseSched);
544  }
545 
546  /**
547  * function getScheduledTransactionsTable(&$sqls, &$records, $setSQL, $whereSched, $grid, $Uid, $dbh, $Cu, $MC, $confirmPermissions)
548  * This function gets the results from the cu_scheduledtxn. After the results are retrieved, then they are sent to various translate and detail functions to get the data for the grid.
549  *
550  * @param $sqls -- list of SQLs to append new SQL to.
551  * @param $records -- list of records to append new records to.
552  * @param $setSQL -- The SQL to set the timezone for times to show up as the CU's.
553  * @param $whereSched -- the where clause gathered from other functions: getFilter and getDefaultFilter.
554  * @param $grid -- the grid to get filters for: either "pendingApproval", "scheduledTransactions", or "priorActivity."
555  * @param $Uid -- the id of the currently logged in user.
556  * @param $dbh -- the database connection
557  * @param $Cu -- the credit union
558  * @param $MC -- the dictionary for translating.
559  * @param $confirmPermissions -- map of users and what confirmation permissions they have. (If they don't have TRN permissions, then they won't be able to see TRN records.)
560  * @param $trans -- the array of transactions for the "other" TRN records.
561  * @param $flagset3 -- needed to account descriptions.
562  */
563  function getScheduledTransactionsTable(&$sqls, &$records, $whereSched, $grid, $Uid, $dbh, $Cu, $MC, $confirmPermissions, $tz, $validUserIds, $trans, $flagset3) {
564  $intervalLookup = getIntervalLookup($MC);
565  switch($grid) {
566  case "pendingApproval":
567  $where = "coalesce(s.approved_by, 0) = 0 and coalesce(s.approved_status, 0) = 0 and s.user_id in $validUserIds and ($whereSched)";
568  $sortable = "create_date";
569  break;
570  case "scheduledTransactions":
571  $where = "(s.end_date is null or now() <= s.end_date or s.next_trigger_date < s.end_date) and s.approved_status = 10 and s.user_id = $Uid and ($whereSched)";
572  $sortable = "next_trigger_date";
573  break;
574  case "priorActivity":
575  // Prior activity: this where statement has the following structure
576  // QUERY 1:
577  // user_id == Uid and approved_status == 90, 99
578  // OR
579  // user_id == Uid and approved_status == 10 and end_date not null, now > end_date, next_trigger_date >= end_date
580  // Query 2:
581  // approved_by == Uid and user_id != Uid and approved_status == 10, 90
582  // Query 3:
583  // filter/user input from getFilter()
584  // WHERE -> ( QUERY 1 OR Query 2 ) AND Query 3
585  $where = "((s.user_id = '$Uid' and (s.approved_status in (90, 99) or (s.approved_status = 10 and s.end_date is not null and now() > s.end_date and s.next_trigger_date >= s.end_date))) or (s.approved_by = $Uid and s.user_id <> '$Uid' and s.approved_status in (10, 90))) and ($whereSched)";
586  $sortable = "approved_date";
587  break;
588  default: throw new exception("table is unknown.", 1);
589  }
590  /**
591  * Modified ONLY the uato join for cross account records. Based on the record type of the useraccounts table {D, L, T, P} I join the appropriate columns for the lookup.
592  */
593  $sql = "with uaua as (
594  select accountnumber, accounttype, display_name, certnumber,
595  trim(recordtype) || '|' || trim(accountnumber) || '|' || trim(accounttype) || '|' || certnumber as key,
596  user_id, recordtype from ${Cu}useraccounts),
597  albalb as (select description, false as iscross, accountnumber as frommember, 'D|' || trim(accountnumber) || '|' || trim(accounttype) || '|' || certnumber as key
598  from ${Cu}accountbalance
599  union all select description, false, accountnumber, 'L|' || trim(accountnumber) || '|' || trim(loannumber) || '|0' as key from ${Cu}loanbalance
600  union all select description, true, accountnumber, case when deposittype = 'L' or deposittype = 'C' then 'L' else 'D' end
601  || '|' || trim(tomember) || '|' || trim(accounttype) || '|0' as key from ${Cu}crossaccounts
602  )
603  select txn.*, uafrom.display_name as from_displayname, albfrom.description as from_desc, uafrom.accountnumber as from_acct, uafrom.accounttype as from_accounttype,
604  uafrom.certnumber as from_certnumber, uato.display_name as to_displayname, albto.description as to_desc, uato.accountnumber as to_acct, uato.accounttype as to_accounttype,
605  uato.certnumber as to_certnumber from
606  (select s.end_date is null or now() <= s.end_date as isscheduled, s.id as data_id, s.name, s.feature_code, s.user_id, s.create_date, s.start_date, s.end_date,
607  s.next_trigger_date, s.status, s.approved_date, coalesce(a.user_name, s.user_id::text) as username, coalesce(b.user_name, s.approved_by::text) as approved_username,
608  s.approved_by, coalesce(f.description, s.feature_code) as feature, s.approved_status, s.status as active_status, s.txn_data, s.repeating_parameters, s.last_edit_date,
609  replace(s.txn_data::json->'txn'->>'from', 'C|', 'L|') as fromid, s.txn_data::json->'txn'->>'frommember' as frommember, s.txn_data::json->'txn'->>'fromsuffix' as fromsuffix,
610  replace(s.txn_data::json->'txn'->>'to', 'C|', 'L|') as toid, s.txn_data::json->'txn'->>'tomember' as tomember, s.txn_data::json->'txn'->>'tosuffix' as tosuffix,
611  strpos(s.txn_data::json->'txn'->>'transactioncode', 'X') > 0 as iscross,
612  '' as processed_by from cu_scheduledtxn s
613  left join ${Cu}user a on s.user_id = a.user_id
614  left join ${Cu}user b on s.approved_by = b.user_id
615  left join cu_feature f on s.feature_code = f.feature_code
616  where s.cu = '$Cu' and ($where)
617  ) txn
618  left join uaua uafrom
619  on (txn.fromid = uafrom.key or txn.fromid || '|0' = uafrom.key) and txn.user_id = uafrom.user_id
620  left join albalb albfrom
621  on (txn.fromid = albfrom.key or txn.fromid || '|0' = albfrom.key) and txn.iscross = albfrom.iscross and txn.frommember = albfrom.frommember
622  left join uaua uato
623  on
624  CASE
625  WHEN uato.recordtype = 'D' THEN
626  txn.toid
627  WHEN uato.recordtype in ('L', 'C') THEN
628  txn.toid || '|0'
629  WHEN uato.recordtype = 'T' THEN
630  'T' || '|' || txn.frommember || '|' || txn.tosuffix || '#' || txn.tomember || '|0'
631  WHEN uato.recordtype = 'P' THEN
632  'P' || '|' || txn.frommember || '|' || txn.tosuffix || '#' || txn.tomember || '|0'
633  ELSE
634  txn.toid
635  END = uato.key
636  and txn.user_id = uato.user_id and uato.recordtype in ('T', 'P') = txn.iscross
637  left join albalb albto
638  on (txn.toid = albto.key or txn.toid || '|0' = albto.key) and txn.iscross = albto.iscross and txn.frommember = albto.frommember
639  where (albto.key is null or uato.key is null)
640  or (uato.recordtype in ('T', 'P') and albto.iscross and txn.iscross)
641  or (uato.recordtype not in ('T', 'P') and not albto.iscross and not txn.iscross)";
642  $sth = db_query($sql, $dbh);
643 
644  if (!$sth) {
645  $error = pg_result_error($sth);
646  throw new exception("Query(getScheduledTransactionsTable) failed: [$error] cu[$Cu] userIds[$validUserIds] where[$whereSched]", 303);
647  }
648 
649  $isScheduled = true;
650  $achcols = array();
651  $achpmts = array();
652  $exts = array();
653  $stRecords = array();
654  for($i = 0; $row = db_fetch_assoc($sth, $i); $i++) {
655 
656  if ($row["user_id"] != $Uid && !$confirmPermissions[$row["feature_code"]]) { // Do not process a record that isn't created by the user and the user doesn't have permissions.
657  continue;
658  }
659 
660  // Convert dates into dateTime with the timezone of the CU.
661  $row["create_date"] = getValidDate($row["create_date"], $tz);
662  $row["start_date"] = getValidDate($row["start_date"], $tz, false);
663  $row["end_date"] = getValidDate($row["end_date"], $tz, false);
664  $row["next_trigger_date"] = getValidDate($row["next_trigger_date"], $tz, false);
665  $row["approved_date"] = getValidDate($row["approved_date"], $tz);
666  $row["last_edit_date"] = getValidDate($row["last_edit_date"], $tz, false);
667 
668  $row["type"] = "scheduled";
669  $row["approved_status"] = isset($row["approved_status"]) ? intval($row["approved_status"]) : 0;
670 
671  if (!isset($row["repeating_parameters"])) {
672  throw new exception("Repeating parameters are not defined.", 304);
673  }
674  $repeatingInterval = HCU_JsonDecode($row["repeating_parameters"]);
675  if (!is_array($repeatingInterval)) {
676  throw new exception("Repeating parameters malformed.", 305);
677  }
678  if (!HCU_array_key_exists("interval", $repeatingInterval)) {
679  throw new exception("Interval not found.", 306);
680  }
681  $row["recurringInterval"] = trim($repeatingInterval["interval"]);
682  unset($row["repeating_parameters"]);
683  $row["recurringIntervalText"] = HCU_array_key_exists($row["recurringInterval"], $intervalLookup) ? $intervalLookup[$row["recurringInterval"]] : "Unknown";
684 
685  $row["dateSortObj"] = $row[$sortable];
686  $row["customData"] = HCU_JsonDecode($row["txn_data"]);
687 
688  switch($row["feature_code"]) {
689  case "ACHCOL":
690  $achcols[] = $row["data_id"];
691  break;
692  case "ACHPMT":
693  $achpmts[] = $row["data_id"];
694  break;
695  case "TRNEXT":
696  case "TRNM2M":
697  $exts[] = $row["data_id"];
698  break;
699  }
700 
701  $stRecords[] = $row;
702  }
703 
704  $sql = array();
705  $achMap = array();
706  if (count($achcols) > 0) {
707  $sql[] = "select s.id as data_id, ap.ach_name, ap.display_name, ap.address, ap.dfi_data from cu_scheduledtxn s
708  inner join ${Cu}achpartner ap on s.feature_code = 'ACHCOL' and cast(s.txn_data::json->'txn'->>'from' as int) = ap.id
709  where s.id in (" . implode(", ", $achcols) . ") and s.cu = '$Cu'";
710  }
711  if (count($achpmts) > 0) {
712  $sql[] = "select s.id as data_id, ap.ach_name, ap.display_name, ap.address, ap.dfi_data from cu_scheduledtxn s
713  inner join ${Cu}achpartner ap on s.feature_code = 'ACHPMT' and cast(s.txn_data::json->'txn'->>'to' as int) = ap.id
714  where s.id in (" . implode(", ", $achpmts) . ") and s.cu = '$Cu'";
715  }
716 
717  if (count($sql) > 0) {
718  $sql = implode(" union all ", $sql);
719  $sqls[] = $sql;
720  $sth = db_query($sql, $dbh);
721  if (!$sth) {
722  throw new exception("ach map query failed.", 307);
723  }
724  for($i = 0; $row = db_fetch_assoc($sth, $i); $i++) {
725  $row["dfi_data"] = HCU_JsonDecode($row["dfi_data"]);
726  $row["address"] = HCU_JsonDecode($row["address"]);
727 
728  $achMap[$row["data_id"]] = $row;
729  }
730  }
731 
732  $sql = array();
733  $extMap = array();
734  if (count($exts) > 0) {
735  $sql[] = "select s.id as data_id, 'from' as dir, ea.display_name, ea.remote_info from cu_scheduledtxn s
736  inner join ${Cu}extaccount ea on s.feature_code in ('TRNEXT') and s.txn_data::json->'txn'->>'type' in ('X2L') and cast(s.txn_data::json->'txn'->>'from' as int) = ea.id
737  and ea.type = 'EXT' where s.id in (" . implode(", ", $exts) . ") and s.cu = '$Cu'"; // Member-to-member can only come from the local account.
738  $sql[] = "select s.id as data_id, 'to', ea.display_name, ea.remote_info from cu_scheduledtxn s
739  inner join ${Cu}extaccount ea on s.feature_code in ('TRNEXT', 'TRNM2M') and s.txn_data::json->'txn'->>'type' in ('L2X', 'L2M') and replace(s.feature_code, 'TRN', '') = ea.type
740  and cast(s.txn_data::json->'txn'->>'to' as int) = ea.id where s.id in (" . implode(", ", $exts) . ") and s.cu = '$Cu'";
741  }
742 
743  if (count($sql) > 0) {
744  $sql = implode(" union all ", $sql);
745  $sqls[] = $sql;
746  $sth = db_query($sql, $dbh);
747  if (!$sth) {
748  throw new exception("ext map query failed.", 308);
749  }
750  for($i = 0; $row = db_fetch_assoc($sth, $i); $i++) {
751  $row["remote_info"] = HCU_JsonDecode($row["remote_info"]);
752 
753  $extMap[$row["data_id"]] = $row;
754  }
755  }
756 
757  for($i = 0, $count = count($stRecords); $i != $count; $i++) {
758  $row = $stRecords[$i];
759  if ($row["user_id"] != $Uid && !$confirmPermissions[$row["feature_code"]]) { // Do not process a record that isn't created by the user and the user doesn't have permissions.
760  continue;
761  }
762 
763  $row["grid"] = $grid;
764 
765  translateCommonNeeded($row, $isScheduled, $Uid, $MC);
766  detailsCommon($row, $isScheduled, $MC);
767 
768  $extAccount = HCU_array_key_exists($row["data_id"], $extMap) ? $extMap[$row["data_id"]] : null;
769  $achAccount = HCU_array_key_exists($row["data_id"], $achMap) ? $achMap[$row["data_id"]] : null;
770 
771  switch($row["feature_code"]) {
772  case "TRN":
773  translateTRN($row, $isScheduled, $MC, $trans, $dbh, $Cu, $Uid, $flagset3);
774  break;
775  case "TRNEXT":
776  translateTRNEXT($row, $isScheduled, $extAccount, $MC, $dbh, $Cu, $Uid, $flagset3);
777  break;
778  case "TRNM2M":
779  translateTRNM2M($row, $isScheduled, $extAccount, $MC, $dbh, $Cu, $Uid, $flagset3);
780  break;
781  case "ACHCOL":
782  case "ACHPMT":
783  translateACH($row, $achAccount, $isScheduled, $row["feature_code"], $MC, $dbh, $Cu, $Uid, $flagset3);
784  break;
785  }
786 
787  translateCleanup($row, $isScheduled);
788  $records[$i] = $row;
789  }
790 
791  }
792 
793  /**
794  * function getRegularTransactionsTable(&$sqls, &$records, $setSQL, $whereTranshdr, $grid, $Uid, $MC, $dbh, $Cu, $confirmPermissions)
795  * This function gets the results from the ${Cu}transhdr and ${Cu}transdtl tables.
796  * After the results are retrieved, then they are sent to various translate and detail functions to get the data for the grid.
797  *
798  * @param $sqls -- list of SQLs to append new SQL to.
799  * @param $records -- list of records to append new records to.
800  * @param $setSQL -- The SQL to set the timezone for times to show up as the CU's.
801  * @param $whereTranshdr -- the where clause gathered from other functions: getFilter and getDefaultFilter.
802  * @param $grid -- the grid to get filters for: either "pendingApproval", "scheduledTransactions", or "priorActivity."
803  * @param $Uid -- the id of the currently logged in user.
804  * @param $MC -- the dictionary for translating.
805  * @param $dbh -- the database connection
806  * @param $Cu -- the credit union
807  * @param $confirmPermissions -- map of users and what confirmation permissions they have. (If they don't have TRN permissions, then they won't be able to see TRN records.)
808  * @param $trans -- the array of transactions for the "other" TRN records.
809  * @param $flagset3 -- needed for getting account descriptions.
810  */
811  function getRegularTransactionsTable(&$sqls, &$records, $whereTranshdr, $grid, $Uid, $MC, $dbh, $Cu, $confirmPermissions, $tz, $validUserIds, $trans, $flagset3, $HB_ENV) {
812  switch($grid) {
813  case "pendingApproval":
814  $where = "t.accountnumber is not null and coalesce(t.approved_by, 0) = 0 and coalesce(t.approved_status, 0) = 0 and t.posted_by in $validUserIds and ($whereTranshdr)";
815  $sortable = "posted_date";
816  break;
817  case "scheduledTransactions": throw new exception("table doesn't use this database table.", 2); break;
818  case "priorActivity":
819  $where = "t.accountnumber is not null and (t.approved_by = '$Uid' or t.posted_by = '$Uid') and t.approved_status in (10, 90, 99) and ($whereTranshdr)";
820  $sortable = "approved_date";
821  break;
822  default: throw new exception("table is unknown.", 1); break;
823  }
824 
825  // Have to rename the id column because Kendo uses the id field by default in the grid. Will need another id for the kendo grid because the grid is coming from two sources.
826  // Only get entries that have an account number to avoid internal transactions (i.e. micro deposits for external accounts)
827  $sql = "with uaua as (select accountnumber, accounttype, display_name, certnumber, trim(recordtype) || '|' || trim(accountnumber) || '|' || trim(accounttype) || '|' || certnumber as key,
828  user_id, recordtype from ${Cu}useraccounts),
829  albalb as (select false as iscross, description, accountnumber as frommember,
830  'D|' || trim(accountnumber) || '|' || trim(accounttype) || '|' || certnumber as key from ${Cu}accountbalance
831  union all
832  select false as iscross, description, accountnumber,
833  'L|' || trim(accountnumber) || '|' || trim(loannumber) || '|0' as key from ${Cu}loanbalance
834  union all
835  select true as iscross, description, accountnumber,
836  case when deposittype = 'L' or deposittype = 'C' then 'L' else 'D' end || '|' || trim(tomember) || '|' || trim(accounttype) || '|0' as key
837  from ${Cu}crossaccounts
838  )
839  select txn.*, uafrom.display_name as from_displayname, albfrom.description as from_desc, uafrom.accountnumber as from_acct, uafrom.accounttype as from_accounttype,
840  uafrom.certnumber as from_certnumber, uato.display_name as to_displayname, albto.description as to_desc, uato.accountnumber as to_acct, uato.accounttype as to_accounttype,
841  uato.certnumber as to_certnumber from
842  (select t.id, t.accountnumber, t.accounttype, t.deposittype, t.transactioncode, t.feature_code, t.effective_date, t.posted_date, t.memo, t.posted_by, t.approved_date,
843  coalesce(a.user_name, t.posted_by::text) as username, coalesce(b.user_name, t.approved_by::text) as approved_username, t.approved_by, t.id as data_id, t.approved_status,
844  coalesce(f.description, t.feature_code) as feature, coalesce(d.amount, 0) as amount, d.transdata, t.processed_date, t.processed_status, t.processed_by,
845  replace(d.transdata::json->>'acct_source', 'C|', 'L') as fromid, d.transdata::json->>'source_key' as fromkey, d.transdata::json->'source_key'->>'accountnumber' as frommember, d.transdata::json->'source_key'->>'accounttype' as fromsuffix,
846  replace(d.transdata::json->>'acct_dest', 'C|', 'L|') as toid, d.transdata::json->'dest_key' as tokey, d.transdata::json->'dest_key'->>'accountnumber' as tomember,
847  case when d.transdata::json->'dest_key'->>'recordtype' = 'L' or d.transdata::json->'dest_key'->>'recordtype' = 'C' then d.transdata::json->'dest_key'->>'loannumber' else d.transdata::json->'dest_key'->>'accounttype' end as tosuffix
848 
849  from ${Cu}transhdr t
850  left join ${Cu}user a on t.posted_by = a.user_id
851  left join ${Cu}user b on t.approved_by = b.user_id
852  left join cu_feature f on t.feature_code = f.feature_code
853  left join ${Cu}transdtl d on t.id = d.transhdr_id
854  where $where) txn
855  left join uaua uafrom
856  on (txn.fromid = uafrom.key or txn.fromid || '|0' = uafrom.key) and txn.posted_by = uafrom.user_id
857  left join albalb albfrom
858  on (txn.fromid = albfrom.key or txn.fromid || '|0' = albfrom.key)
859  and txn.transactioncode in ('XP', 'XA') = albfrom.iscross and txn.frommember = albfrom.frommember
860  left join uaua uato
861  ON CASE WHEN txn.transactioncode in ('XP', 'XA') and uato.recordtype in ('T', 'P') THEN
862  uato.recordtype || '|' || txn.frommember || '|' || txn.tosuffix || '#' || txn.tomember || '|0'
863  WHEN txn.transactioncode not in ('XP', 'XA') and uato.recordtype = 'D' THEN
864  txn.toid
865  WHEN txn.transactioncode not in ('XP', 'XA') and uato.recordtype in ('L', 'C') THEN
866  txn.toid || '|0'
867  ELSE
868  txn.toid END = uato.key AND txn.posted_by = uato.user_id AND uato.recordtype in ('T', 'P') = txn.transactioncode in ('XP', 'XA')
869  left join albalb albto
870  on (txn.toid = albto.key or txn.toid || '|0' = albto.key)
871  and txn.transactioncode in ('XP', 'XA') = albto.iscross and txn.frommember = albto.frommember";
872 
873  $sqls[] = $sql;
874  $sth = db_query($sql, $dbh);
875  if (!$sth) {
876  throw new exception("transhdr query failed.", 301);
877  }
878 
879  $gtRecords = array();
880  for($i = 0; $row = db_fetch_assoc($sth, $i); $i++) {
881  if (!($row["posted_by"] == $Uid || $confirmPermissions[$row["feature_code"]])) { // Do not process a record that isn't created by the user and the user doesn't have permissions.
882  continue;
883  }
884 
885  // Need to get confirmation code, we need to call GetTransferConfirmation()
886  // which needs HB_ENV, and getValidDate sets the dates we need as an object
887  // where GetTransferConfirmCode needs a string.
888  if ($row['processed_date'] != null) {
889  $row['confirmation'] = GetTransferConfirmCode($HB_ENV, "process", $row);
890  } else if ($row['approved_date'] != null) {
891  $row['confirmation'] = GetTransferConfirmCode($HB_ENV, "approve", $row);
892  } else {
893  // not processed, not approved, get posted
894  // confirmation code
895  $row['confirmation'] = GetTransferConfirmCode($HB_ENV, "post", $row);
896  }
897 
898  // Convert dates into dateTime with the timezone of the CU.
899  $row["posted_date"] = getValidDate($row["posted_date"], $tz);
900  $row["effective_date"] = getValidDate($row["effective_date"], $tz, false);
901  $row["approved_date"] = getValidDate($row["approved_date"], $tz);
902  $row["processed_date"] = getValidDate($row["processed_date"], $tz);
903  $row["grid"] = $grid;
904 
905  $row["type"] = "transhdr";
906  $row["approved_status"] = isset($row["approved_status"]) ? intval($row["approved_status"]) : 0;
907 
908  $row["dateSortObj"] = $row[$sortable];
909 
910  $customData = HCU_JsonDecode($row["transdata"]);
911  $customData["amount"] = $row["amount"];
912 
913  $key = $row["data_id"] . "a"; // Add the "a" so it isn't mistaken as an indexed key.
914  if (!isset($gtRecords[$key])) {
915  $row["customData"] = array();
916  $row["fullAmount"] = 0;
917  $gtRecords[$key] = $row;
918  }
919 
920  $gtRecords[$key]["customData"][] = $customData;
921  $gtRecords[$key]["fullAmount"] += $row["amount"];
922  }
923 
924  $isScheduled = false;
925  foreach($gtRecords as $key => $row) {
926  translateCommonNeeded($row, $isScheduled, $Uid, $MC);
927  detailsCommon($row, $isScheduled, $MC);
928 
929  switch($row["feature_code"]) {
930  case "TRN":
931  translateTRN($row, $isScheduled, $MC, $trans, $dbh, $Cu, $Uid, $flagset3);
932  break;
933  case "TRNEXT":
934  translateTRNEXT($row, $isScheduled, null, $MC, $dbh, $Cu, $Uid, $flagset3);
935  break;
936  case "TRNM2M":
937  translateTRNM2M($row, $isScheduled, null, $MC, $dbh, $Cu, $Uid, $flagset3);
938  break;
939  case "ACHCOL":
940  case "ACHPMT":
941  translateACH($row, null, $isScheduled, $row["feature_code"], $MC, $dbh, $Cu, $Uid, $flagset3);
942  break;
943  }
944 
945  translateCleanup($row, $isScheduled);
946 
947  $records[$key] = $row;
948  }
949  }
950 
951  /**
952  * function translateCommonNeeded(&$row, $isScheduled, $Uid, $MC)
953  * This function gets the values for the grid that are needed for all transactions.
954  *
955  * @param $row -- the scheduled transaction or regular transaction record from the getRegularTransactionsTable or getScheduledTransactionsTable queries.
956  * @param $isScheduled -- if true, the row comes from the scheduled transaction query versus the regular transaction query.
957  * @param $Uid -- the id of the currently logged in user.
958  * @param $MC -- the dictionary for translating.
959  */
960  function translateCommonNeeded(&$row, $isScheduled, $Uid, $MC) {
961 
962  $displayDate = $isScheduled ? $row["next_trigger_date"] : $row["posted_date"];
963  $row["displayDateFull"] = isset($displayDate) ? $displayDate->format(getDFormat()) : "";
964  $row["displayDateMonth"] = isset($displayDate) ? $displayDate->format("M") : "";
965  $row["displayDateDay"] = isset($displayDate) ? $displayDate->format("d") : "";
966  $row["displayDateYear"] = isset($displayDate) ? $displayDate->format("Y") : "";
967 
968  $postBy = $isScheduled ? $row["user_id"] : $row["posted_by"];
969  $row["canApprove"] = $postBy != $Uid;
970 
971  switch($row["approved_status"]) {
972  case 10:
973  if (HCU_array_key_exists("processed_status", $row) && $row["processed_status"] == 99) {
974  $row["approvedDescription"] = $MC->msg("Failed", HCU_DISPLAY_AS_JS);
975  $row["infoClass"] = "failed";
976  } else if ($row["grid"] == "scheduledTransactions" || $row["canApprove"]) { // If seeing transfer through approver's view, prior activity is also the ones that you've approved.
977  if (HCU_array_key_exists("active_status", $row)) {
978  if ($row["active_status"] == "A") {
979  $row["approvedDescription"] = $MC->msg("Active", HCU_DISPLAY_AS_JS);
980  $row["infoClass"] = "approved";
981  } else { // active_status == I
982  $row["approvedDescription"] = $MC->msg("Inactive", HCU_DISPLAY_AS_JS);
983  $row["infoClass"] = "failed";
984  }
985  } else {
986  $row["approvedDescription"] = $MC->msg("Completed", HCU_DISPLAY_AS_JS);
987  $row["infoClass"] = "completed";
988  }
989  } else {
990  $row["approvedDescription"] = $MC->msg("Completed", HCU_DISPLAY_AS_JS);
991  $row["infoClass"] = "completed";
992  }
993  break;
994  case 99:
995  $row["approvedDescription"] = $MC->msg("Cancelled", HCU_DISPLAY_AS_JS);
996  $row["infoClass"] = "cancelled";
997  break;
998  case 90:
999  $row["approvedDescription"] = $MC->msg("Declined", HCU_DISPLAY_AS_JS);
1000  $row["infoClass"] = "declined";
1001  break;
1002  case 0:
1003  $row["approvedDescription"] = "";
1004  $row["infoClass"] = $row["canApprove"] ? "awaiting" : "awaiting-non";
1005  break;
1006  }
1007 
1008  // Translate the "Funds Transfer", "External Accounts", etc.
1009  $feature = $MC->msg("CU feature " . $row["feature_code"], HCU_DISPLAY_AS_RAW);
1010  $row["feature"] = isset($feature) ? $feature : $row["feature"]; // If the dictionary exists, use it. Otherwise, use the value in the database.
1011 
1012  // Needed but should be overwritten by the other translate functions per transaction type.
1013  $row["area1Label"] = "";
1014  $row["area1Text"] = "";
1015  $row["area2Label"] = "";
1016  $row["area2Text"] = "";
1017  $row["area3"] = "";
1018  //adding label for interval
1019  $row["interval"] = "";
1020  $row["details"] = array();
1021 
1022  // Area4 labels. Logic was duplicated in each of the transfer types and changes needed to be made for #1427 so move it here.
1023  $processDate = "";
1024  if (!$isScheduled && in_array($row["feature_code"], array("ACHCOL", "ACHPMT"))) {
1025  $processDate = $row["effective_date"];
1026  $processDate = isset($processDate) ? $processDate->format(getDFormat()) : $MC->msg("Online Deposits Pending", HCU_DISPLAY_AS_RAW);
1027  } else if ($row["grid"] == "pendingApproval") {
1028  $processDate = $isScheduled ? $row["start_date"] : $row["effective_date"];
1029  $processDate = isset($processDate) ? $processDate->format(getDFormat()) : "";
1030  } else if ($row["grid"] == "scheduledTransactions") {
1031  $processDate = $row["next_trigger_date"];
1032  $processDate = isset($processDate) ? $processDate->format(getDFormat()) : "";
1033  } else if ($row["grid"] == "priorActivity") {
1034  $processDate = $isScheduled ? $row["create_date"] : $row["posted_date"];
1035  $processDate = isset($processDate) ? $processDate->format(getDFormat()) : "";
1036  }
1037 
1038  // $completedDate = $isScheduled ? $row["last_edit_date"] : $row["approved_date"];
1039  $completedDate = $isScheduled ? $row["next_trigger_date"] : $row["approved_date"];
1040  $completedDate = isset($completedDate) ? $completedDate->format(getDFormat()) : "";
1041 
1042  $approvedDate = $row["approved_date"];
1043  $approvedDate = isset($approvedDate) ? $approvedDate->format(getDFormat()) : "";
1044 
1045  $row["area4Label"] = "";
1046  $row["area4Text"] = "";
1047 
1048  if ($row["processed_by"] == "*sched*") {
1049  $row["area4Label"] = "";
1050  $row["area4Text"] = $MC->msg("From Schedule", HCU_DISPLAY_AS_RAW);
1051  } else if (!$isScheduled && in_array($row["feature_code"], array("ACHCOL", "ACHPMT"))) { // ACHCOL and ACHPMT is special. The regular transactions also have Effective Date.
1052  $row["area4Label"] = $MC->msg("ACH Effective Date", HCU_DISPLAY_AS_RAW);
1053  $row["area4Text"] = $processDate;
1054  } else if ($row["approved_status"] == 10) {
1055 
1056  if ($row["canApprove"]) {
1057  $row["area4Label"] = $MC->msg("Approved on", HCU_DISPLAY_AS_RAW);
1058  $row["area4Text"] = $approvedDate;
1059  } else if ($row["grid"] == "scheduledTransactions") {
1060  $row["area4Label"] = $MC->msg("Next Trigger", HCU_DISPLAY_AS_RAW);
1061  $row["area4Text"] = $processDate;
1062  } else if ($row["grid"] == "priorActivity") {
1063  $row["area4Label"] = $MC->msg("Completed on", HCU_DISPLAY_AS_RAW);
1064  $row["area4Text"] = $completedDate;
1065  }
1066 
1067  } else if ($row["approved_status"] == 99) {
1068  $row["area4Label"] = $MC->msg("Cancelled on", HCU_DISPLAY_AS_RAW);
1069  $row["area4Text"] = $approvedDate;
1070  } else if ($row["approved_status"] == 90) {
1071  $row["area4Label"] = $MC->msg("Declined on", HCU_DISPLAY_AS_RAW);
1072  $row["area4Text"] = $approvedDate;
1073  } else if ($isScheduled) {
1074 
1075  if ($row["grid"] == "pendingApproval") {
1076  $row["area4Label"] = $MC->msg("ACH Effective Date", HCU_DISPLAY_AS_RAW);
1077  $row["area4Text"] = $processDate;
1078  } else if ($row["grid"] == "scheduledTransactions") {
1079  $row["area4Label"] = $MC->msg("Next Trigger", HCU_DISPLAY_AS_RAW);
1080  $row["area4Text"] = $processDate;
1081  } else if ($row["grid"] == "priorActivity") {
1082  $row["area4Label"] = $MC->msg("Processed Date", HCU_DISPLAY_AS_RAW);
1083  $row["area4Text"] = $processDate;
1084  }
1085 
1086  } else { // Regular transfer that is not approved, cancelled, or declined.
1087  $row["area4Label"] = "";
1088  $row["area4Text"] = $MC->msg("Immediate", HCU_DISPLAY_AS_RAW);
1089  }
1090 
1091  }
1092 
1093  /**
1094  * function detailsCommon(&$row, $isScheduled, $MC)
1095  * This function creates the top portion of the details for the grid row that is common to all transactions.
1096  *
1097  * @param $row -- the scheduled transaction or regular transaction record from the getRegularTransactionsTable or getScheduledTransactionsTable queries.
1098  * @param $isScheduled -- if true, the row comes from the scheduled transaction query versus the regular transaction query.
1099  * @param $MC -- the dictionary for translating.
1100  */
1101  function detailsCommon(&$row, $isScheduled, $MC) {
1102 
1103  $createdOnDate = $isScheduled ? $row["create_date"] : $row["posted_date"];
1104  $createdOnDate = isset($createdOnDate) ? $createdOnDate->format(getGFormat()) : "";
1105  $processedDate = !$isScheduled ? ($row["grid"] == "priorActivity" ? $row["effective_date"] : $row["processed_date"]) : null;
1106  $processedDate = isset($processedDate) ? $processedDate->format(getDFormat()) : $MC->msg("Online Deposits Pending", HCU_DISPLAY_AS_JS);
1107  $approvedDate = $row["approved_date"];
1108  $approvedDate = isset($approvedDate) ? $approvedDate->format(getGFormat()) : "";
1109 
1110  // $completedDate = $isScheduled ? $row["last_edit_date"] : $row["approved_date"];
1111  $completedDate = $isScheduled ? $row["next_trigger_date"] : $row["approved_date"];
1112  $completedDate = isset($completedDate) ? $completedDate->format(getDFormat()) : "";
1113 
1114  // Put the confirmation code at the top of the list.
1115  // Scheduled transfers do not have confirmation codes
1116  // only add this detail for non-scheduled.
1117  if (!$isScheduled) {
1118  $confirmationCode = $row['confirmation'];
1119  $row["details"][] = array("label" => $MC->msg("Confirmation", HCU_DISPLAY_AS_RAW), "text" => $confirmationCode);
1120  }
1121 
1122  $row["details"][] = array("label" => $MC->msg("Created On", HCU_DISPLAY_AS_RAW), "text" => $createdOnDate);
1123  $row["details"][] = array("label" => $MC->msg("Created By", HCU_DISPLAY_AS_RAW), "text" => isset($row["username"]) ? trim($row["username"]) : "");
1124 
1125  $isCompleted = $row["grid"] == "priorActivity" && !$row["canApprove"];
1126 
1127  switch($row["approved_status"]) {
1128  case 10:
1129  $row["details"][] = array("label" => $MC->msg("Approved on", HCU_DISPLAY_AS_RAW), "text" => $approvedDate);
1130  $row["details"][] = array("label" => $MC->msg("Approved by", HCU_DISPLAY_AS_RAW), "text" => $row["approved_username"]);
1131 
1132  if ($isCompleted) {
1133  $row["details"][] = array("label" => $MC->msg("Completed on", HCU_DISPLAY_AS_RAW), "text" => $completedDate);
1134  }
1135  break;
1136  case 90:
1137  $row["details"][] = array("label" => $MC->msg("Declined on", HCU_DISPLAY_AS_RAW), "text" => $approvedDate);
1138  $row["details"][] = array("label" => $MC->msg("Declined by", HCU_DISPLAY_AS_RAW), "text" => $row["approved_username"]);
1139  break;
1140  case 99:
1141  $row["details"][] = array("label" => $MC->msg("Cancelled on", HCU_DISPLAY_AS_RAW), "text" => $approvedDate);
1142  $row["details"][] = array("label" => $MC->msg("Cancelled by", HCU_DISPLAY_AS_RAW), "text" => $row["approved_username"]);
1143  break;
1144  }
1145 
1146  if ($isScheduled) {
1147  $startDate = $row["start_date"];
1148  $startDate = isset($startDate) ? $startDate->format(getDFormat()) : "";
1149  $endDate = $row["end_date"];
1150  $endDate = isset($endDate) ? $endDate->format(getDFormat()) : "";
1151 
1152 
1153  $row["details"][] = array("label" => $MC->msg("Start Date", HCU_DISPLAY_AS_RAW), "text" => $startDate);
1154  $row["details"][] = array("label" => $MC->msg("End Date", HCU_DISPLAY_AS_RAW), "text" => $endDate);
1155 
1156  if (!$isCompleted) {
1157  $nextTriggerDate = $row["next_trigger_date"];
1158  $nextTriggerDate = isset($nextTriggerDate) ? $nextTriggerDate->format(getDFormat()) : "";
1159  $row["details"][] = array("label" => $MC->msg("Next Trigger", HCU_DISPLAY_AS_RAW), "text" => $nextTriggerDate);
1160  }
1161 
1162  if ($row["grid"] != "priorActivity") {
1163  $row["details"][] = array("label" => $MC->msg("Status", HCU_DISPLAY_AS_RAW), "text" => $MC->msg($row["status"] == "A" ? "Active" : "Inactive", HCU_DISPLAY_AS_JS));
1164  }
1165 
1166  $row["details"][] = array("label" => $MC->msg("Interval", HCU_DISPLAY_AS_RAW), "text" => $row["recurringIntervalText"]);
1167  } else {
1168  if (!$isCompleted && !in_array($row["approved_status"], array(90,99))) {
1169  $row["details"][] = array("label" => $MC->msg("ACH Effective Date", HCU_DISPLAY_AS_RAW), "text" => $processedDate);
1170  }
1171  }
1172 
1173  }
1174 
1175  /**
1176  * function translateTRN(&$row, $isScheduled, $MC)
1177  * This populates the four areas iff the feature_code is TRN.
1178  *
1179  * @param $row -- the scheduled transaction or regular transaction record from the getRegularTransactionsTable or getScheduledTransactionsTable queries.
1180  * @param $isScheduled -- if true, the row comes from the scheduled transaction query versus the regular transaction query.
1181  * @param $MC -- the dictionary for translating.
1182  * @param $trans -- the array of transactions for the "other" TRN records.
1183  */
1184  function translateTRN(&$row, $isScheduled, $MC, $trans, $dbh, $Cu, $Uid, $flagset3) {
1185  $srcAcctId = $dstAcctId = null;
1186  $srcAcctKey = $dstAcctKey = null;
1187  $srcAcctDesc = $dstAcctDesc = null;
1188  $hasDstDesc = false;
1189 
1190  if ($isScheduled) {
1191  $srcAcctId = explode("|", $row['customData']['txn']['from']);
1192  $srcAcctKey = array(
1193  "accountnumber" => $row['customData']['txn']['frommember'],
1194  "recordtype" => $row['customData']['txn']['fromtype'],
1195  );
1196  if ($srcAcctKey['recordtype'] == "D") {
1197  $srcAcctKey['accounttype'] = $row['customData']['txn']['fromsuffix'];
1198  $srcAcctKey['certnumber'] = $srcAcctId[3];
1199  } else if ($srcAcctKey['recordtype'] == "L" || $srcAcctKey['recordtype'] == "C") {
1200  $srcAcctKey['loannumber'] = $row['customData']['txn']['fromsuffix'];
1201  }
1202 
1203  $dstAcctId = explode("|", $row['customData']['txn']['to']);
1204  $dstAcctKey = array(
1205  "accountnumber" => $row['customData']['txn']['tomember'],
1206  "recordtype" => $row['customData']['txn']['totype']
1207  );
1208  if ($dstAcctKey['recordtype'] == "D") {
1209  $dstAcctKey['accounttype'] = $row['customData']['txn']['tosuffix'];
1210  $dstAcctKey['certnumber'] = $dstAcctId[3];
1211  } else if ($dstAcctKey['recordtype'] == "L" || $dstAcctKey['recordtype'] == "C") {
1212  $dstAcctKey['loannumber'] = $row['customData']['txn']['tosuffix'];
1213  }
1214 
1215  $row["area3"] = money_format('$%i', $row['customData']['txn']["amount"]) . " " . trim($row["recurringIntervalText"]);
1216 
1217  $row["interval"] = trim($row["recurringIntervalText"]);
1218 
1219  } else {
1220  $srcAcctId = explode("|", $row['customData'][0]['acct_source']);
1221  $srcAcctKey = HCU_array_key_value('source_key', $row['customData'][0]);
1222 
1223  $dstAcctId = explode("|", $row['customData'][0]['acct_dest']);
1224  $dstAcctKey = HCU_array_key_value('dest_key', $row['customData'][0]);
1225 
1226  $row["area3"] = money_format('$%i', $row["fullAmount"]);
1227  }
1228 
1229  $srcAcctDisp = GetMemberDescription($dbh, $Cu, $Uid, $srcAcctKey);
1230  if ($srcAcctKey['recordtype'] == "D") {
1231  $srcAcctDesc = getAccountDescription($dbh, $Cu, $srcAcctKey['accountnumber'], $srcAcctDisp['description'], $srcAcctKey['accounttype'],
1232  $srcAcctDisp['display_name'], $flagset3, $srcAcctId[3]);
1233  } else if ($srcAcctKey['recordtype'] == "L" || $srcAcctKey['recordtype'] == "C") {
1234  $srcAcctDesc = getAccountDescription($dbh, $Cu, $srcAcctKey['accountnumber'], $srcAcctDisp['description'], $srcAcctKey['loannumber'], $srcAcctDisp['display_name'],
1235  $flagset3, $row["from_certnumber"]);
1236  }
1237 
1238  if ($dstAcctId[0] == "O") {
1239  if ($isScheduled) {
1240  $hasDstDesc = HCU_array_key_value($row['customData']['txn']["tosuffix"], $trans);
1241  } else {
1242  $hasDstDesc = HCU_array_key_value($dstAcctId[2], $trans);
1243  }
1244  if (!$hasDstDesc) {
1245  $dstAcctDesc = $MC->msg("Unknown", HCU_DISPLAY_AS_JS);
1246  } else {
1247  $cudesc = isset($hasDstDesc[2]) ? trim($hasDstDesc[2]) : "";
1248  $noncudesc = isset($hasDstDesc[0]) ? trim($hasDstDesc[0]) : "";
1249  $dstAcctDesc = $cudesc != "" ? $cudesc : $noncudesc;
1250  }
1251  } else {
1252 
1253  /*
1254  * Cross Account Lookup
1255  * if the transactioncode is in {XA, XP} then supply different values for looking up the Account Description
1256  */
1257  if ($isScheduled) {
1258  $recordTransCode = $row['customData']['txn']['transactioncode'];
1259  $recordToInfo = $row['customData']['txn'];
1260  } else {
1261  $recordTransCode = $row['transactioncode'];
1262  $recordToInfo = $row;
1263  }
1264  if (in_array($recordTransCode, Array("XA", "XP"))) {
1265  /*
1266  * Cross Account Transfers need to be made within the same "Member" account. They can not cross over to a
1267  * different member number source.
1268  * Therefore, I should be able to use the 'frommember' as the member number to lookup in the useraccounts table.
1269  *
1270  * The lookup ONLY needs be modified for looking up the ORIGINAL description using the GetMemberDescription function
1271  * The normal process of displaying the description should be done using the AcctKey as is from the txn record.
1272  *
1273  */
1274  $acctTypeorLoan = ($dstAcctKey['recordtype'] == "L" || $dstAcctKey['recordtype'] == "C" ? "loannumber" : "accounttype");
1275  $localAcctKey = Array(
1276  "recordtype" => $dstAcctKey['recordtype'],
1277  "accountnumber" => $recordToInfo['frommember'],
1278  $acctTypeorLoan => $recordToInfo['tosuffix'] . '#' . $recordToInfo['tomember'],
1279  "certnumber" => 0
1280  );
1281 
1282  } else {
1283  $localAcctKey = $dstAcctKey;
1284  }
1285  // ** Gets the appropriate Core Description
1286  $dstAcctDisp = GetMemberDescription($dbh, $Cu, $Uid, $localAcctKey);
1287  if ($dstAcctKey['recordtype'] == "D") {
1288  $dstAcctDesc = getAccountDescription($dbh, $Cu, $dstAcctKey['accountnumber'], $dstAcctDisp['description'], $dstAcctKey['accounttype'], $dstAcctDisp['display_name'],
1289  $flagset3, $dstAcctId[3]);
1290  } else if ($dstAcctKey['recordtype'] == "L" || $dstAcctKey['recordtype'] == "C") {
1291  $dstAcctDesc = getAccountDescription($dbh, $Cu, $dstAcctKey['accountnumber'], $dstAcctDisp['description'], $dstAcctKey['loannumber'], $dstAcctDisp['display_name'],
1292  $flagset3, $row["to_certnumber"]);
1293  }
1294 
1295 
1296  }
1297 
1298  // setup row display
1299  $row["area1Label"] = $MC->msg("From", HCU_DISPLAY_AS_JS);
1300  $row['area1Text'] = $srcAcctDesc;
1301  $row["area2Label"] = $MC->msg("To", HCU_DISPLAY_AS_JS);
1302  $row['area2Text'] = $dstAcctDesc;
1303 
1304  // setup details view display
1305  $row["details"][] = array("label" => $MC->msg("From Account", HCU_DISPLAY_AS_RAW), "text" => $srcAcctDesc);
1306  $dstAcctId[0] == "O" ?
1307  $row["details"][] = array("label" => $MC->msg("Special Transfer", HCU_DISPLAY_AS_RAW), "text" => $dstAcctDesc) :
1308  $row["details"][] = array("label" => $MC->msg("To Account", HCU_DISPLAY_AS_RAW), "text" => $dstAcctDesc);
1309  $isScheduled ?
1310  $row["details"][] = array("label" => $MC->msg("Amount", HCU_DISPLAY_AS_RAW), "text" => money_format('$%i', $row["customData"]["txn"]["amount"])) :
1311  $row["details"][] = array("label" => $MC->msg("Amount", HCU_DISPLAY_AS_RAW), "text" => money_format('$%i', $row["amount"]));
1312  $isScheduled ?
1313  $row['details'][] = array("label" => $MC->msg("Comment", HCU_DISPLAY_AS_JS), "text" => $row["customData"]["txn"]['memo']) :
1314  $row['details'][] = array("label" => $MC->msg("Comment", HCU_DISPLAY_AS_JS), "text" => $row['memo']);
1315  }
1316 
1317  /**
1318  * function translateTRNEXT(&$row, $isScheduled, $extAccount, $MC)
1319  * This populates the four areas iff the feature_code is TRNEXT.
1320  *
1321  * @param $row -- the scheduled transaction or regular transaction record from the getRegularTransactionsTable or getScheduledTransactionsTable queries.
1322  * @param $isScheduled -- if true, the row comes from the scheduled transaction query versus the regular transaction query.
1323  * @param $extAccount -- the external account record for details.
1324  * @param $MC -- the dictionary for translating.
1325  * @param $dbh -- the database connection (needed for getting the mask variable.)
1326  * @param $Cu -- the credit union
1327  * @param $flagset3 -- contains the two flags needed for determining account descriptions.
1328  */
1329  function translateTRNEXT(&$row, $isScheduled, $extAccount, $MC, $dbh, $Cu, $Uid, $flagset3) {
1330  $localAcctId = $localAcctKey = $localAcctDisp = $localAcctDesc = null;
1331  $externalAcctId = $externalAcctDesc = $externalAcctRouting = $externalAcctAccount = null;
1332  $trnAmnt = $trnMemo = null;
1333 
1334  $mask = GetMask($dbh, $Cu);
1335  $mask = $mask["code"] != 0 ? array("start" => -2) : $mask["data"]; // Just return the default mask in this case.
1336 
1337  $trnDir = $isScheduled ?
1338  ($extAccount['dir'] == "to" ? "to" : "from") :
1339  ($row['fromkey'] ? "to" : "from");
1340 
1341  if ($isScheduled) {
1342  $row["area1Label"] = $MC->msg($extAccount["dir"] == "from" ? "ACH From Account" : "From", HCU_DISPLAY_AS_JS);
1343  $row["area2Label"] = $MC->msg($extAccount["dir"] == "to" ? "ACH To Account" : "To", HCU_DISPLAY_AS_JS);
1344 
1345  if ($trnDir == "from") {
1346  $localAcctId = explode("|", $row["customData"]["txn"]["to"]);
1347  $localAcctKey = array(
1348  "accountnumber" => $row['customData']['txn']['tomember'],
1349  "recordtype" => $row['customData']['txn']['totype']
1350  );
1351  if ($localAcctKey['recordtype'] == "D") {
1352  $localAcctKey['accounttype'] = $row['customData']['txn']['tosuffix'];
1353  $localAcctKey['certnumber'] = $localAcctId[3];
1354  } else if ($localAcctKey['recordtype'] == "L" || $localAcctKey['recordtype'] == "C") {
1355  $localAcctKey['loannumber'] = $row['customData']['txn']['tosuffix'];
1356  }
1357  $localAcctDisp = GetMemberDescription($dbh, $Cu, $Uid, $localAcctKey);
1358  if ($localAcctKey['recordtype'] == "D") {
1359  $localAcctDesc = getAccountDescription($dbh, $Cu, $localAcctKey['accountnumber'], $localAcctDisp['description'], $localAcctKey['accounttype'], $localAcctDisp['display_name'],
1360  $flagset3, $localAcctKey['certnumber']);
1361  } else if ($localAcctKey['recordtype'] == "L" || $localAcctKey['recordtype'] == "C") {
1362  $localAcctDesc = getAccountDescription($dbh, $Cu, $localAcctKey['accountnumber'], $localAcctDisp['description'], $localAcctKey['loannumber'], $localAcctDisp['display_name'],
1363  $flagset3, $row["to_certnumber"]);
1364  }
1365  }
1366  else
1367  {
1368  $localAcctId = explode("|", $row["customData"]["txn"]["from"]);
1369  $localAcctKey = array(
1370  "accountnumber" => $row['customData']['txn']['frommember'],
1371  "recordtype" => $row['customData']['txn']['fromtype']
1372  );
1373  if ($localAcctKey['recordtype'] == "D") {
1374  $localAcctKey['accounttype'] = $row['customData']['txn']['fromsuffix'];
1375  $localAcctKey['certnumber'] = $localAcctId[3];
1376  } else if ($localAcctKey['recordtype'] == "L" || $localAcctKey['recordtype'] == "C") {
1377  $localAcctKey['loannumber'] = $row['customData']['txn']['fromsuffix'];
1378  }
1379  $localAcctDisp = GetMemberDescription($dbh, $Cu, $Uid, $localAcctKey);
1380  if ($localAcctKey['recordtype'] == "D") {
1381  $localAcctDesc = getAccountDescription($dbh, $Cu, $localAcctKey['accountnumber'], $localAcctDisp['description'], $localAcctKey['accounttype'], $localAcctDisp['display_name'],
1382  $flagset3, $localAcctKey['certnumber']);
1383  } else if ($localAcctKey['recordtype'] == "L" || $localAcctKey['recordtype'] == "C") {
1384  $localAcctDesc = getAccountDescription($dbh, $Cu, $localAcctKey['accountnumber'], $localAcctDisp['description'], $localAcctKey['loannumber'], $localAcctDisp['display_name'],
1385  $flagset3, $row["from_certnumber"]);
1386  }
1387  }
1388  $externalAcctDesc = trim($extAccount["display_name"]);
1389  $externalAcctRouting = trim($extAccount["remote_info"]["rdfi"]["routing"]);
1390  $externalAcctAccount = trim($extAccount["remote_info"]["rdfi"]["account"]);
1391  $trnAmnt = money_format('$%i', $row['customData']['txn']["amount"]);
1392  $trnMemo = $row['customData']['txn']["memo"];
1393  } else {
1394  $row["area1Label"] = $MC->msg($trnDir == "from" ? "ACH From Account" : "From", HCU_DISPLAY_AS_JS);
1395  $row["area2Label"] = $MC->msg($trnDir == "to" ? "ACH To Account" : "To", HCU_DISPLAY_AS_JS);
1396 
1397  if ($trnDir == "from")
1398  {
1399  $externalAcctId = $row["customData"][0]["acct_source"];
1400 
1401  $localAcctKey = $row['customData'][0]['dest_key'];
1402  $localAcctDisp = GetMemberDescription($dbh, $Cu, $Uid, $localAcctKey);
1403  if ($localAcctKey['recordtype'] == "D") {
1404  $localAcctDesc = getAccountDescription($dbh, $Cu, $localAcctKey['accountnumber'], $localAcctDisp['description'], $localAcctKey['accounttype'], $localAcctDisp['display_name'],
1405  $flagset3, $localAcctKey['certnumber']);
1406  } else if ($localAcctKey['recordtype'] == "L" || $localAcctKey['recordtype'] == "C") {
1407  $localAcctDesc = getAccountDescription($dbh, $Cu, $localAcctKey['accountnumber'], $localAcctDisp['description'], $localAcctKey['loannumber'], $localAcctDisp['display_name'],
1408  $flagset3, $row["to_certnumber"]);
1409  }
1410  } else {
1411  $externalAcctId = $row["customData"][0]["acct_dest"];
1412 
1413  $localAcctKey = $row['customData'][0]['source_key'];
1414  $localAcctDisp = GetMemberDescription($dbh, $Cu, $Uid, $localAcctKey);
1415  if ($localAcctKey['recordtype'] == "D") {
1416  $localAcctDesc = getAccountDescription($dbh, $Cu, $localAcctKey['accountnumber'], $localAcctDisp['description'], $localAcctKey['accounttype'], $localAcctDisp['display_name'],
1417  $flagset3, $localAcctKey['certnumber']);
1418  } else if ($localAcctKey['recordtype'] == "L" || $localAcctKey['recordtype'] == "C") {
1419  $localAcctDesc = getAccountDescription($dbh, $Cu, $localAcctKey['accountnumber'], $localAcctDisp['description'], $localAcctKey['loannumber'], $localAcctDisp['display_name'],
1420  $flagset3, $row["to_certnumber"]);
1421  }
1422  }
1423 
1424  $externalAcctDesc = trim($externalAcctId["remote_entity"]["name"]);
1425  $externalAcctRouting = trim($externalAcctId["rdfi"]["rdfi_routing"]);
1426  $externalAcctAccount = trim($externalAcctId["rdfi"]["rdfi_account"]);
1427  $trnAmnt = money_format('$%i', $row["fullAmount"]);
1428  $trnMemo = $row["memo"];
1429  }
1430 
1431  if ($trnDir == "from") {
1432  $row['area1Text'] = $externalAcctDesc;
1433  $row['area2Text'] = $localAcctDesc;
1434 
1435  // setup details display
1436  $row["details"][] = array("type" => "wellStart");
1437  $row["details"][] = array("type" => "header", "text" => $MC->msg("ACH From Account", HCU_DISPLAY_AS_RAW));
1438  $row["details"][] = array("label" => $MC->msg("ACH Routing Number", HCU_DISPLAY_AS_RAW), "text" => $externalAcctRouting);
1439  $row["details"][] = array("label" => $MC->msg("Account #", HCU_DISPLAY_AS_RAW), "text" => ApplyMask($externalAcctAccount, $mask));
1440  $row["details"][] = array("label" => $MC->msg("Description", HCU_DISPLAY_AS_RAW), "text" => $externalAcctDesc);
1441  $row["details"][] = array("type" => "wellEnd");
1442  } else {
1443  $row["details"][] = array("label" => $MC->msg("ACH From Account", HCU_DISPLAY_AS_RAW), "text" => $localAcctDesc);
1444  }
1445 
1446  if ($trnDir == "to") {
1447  $row['area1Text'] = $localAcctDesc;
1448  $row['area2Text'] = $externalAcctDesc;
1449 
1450  // setup details display
1451  $row["details"][] = array("type" => "wellStart");
1452  $row["details"][] = array("type" => "header", "text" => $MC->msg("ACH To Account", HCU_DISPLAY_AS_RAW));
1453  $row["details"][] = array("label" => $MC->msg("ACH Routing Number", HCU_DISPLAY_AS_RAW), "text" => $externalAcctRouting);
1454  $row["details"][] = array("label" => $MC->msg("Account #", HCU_DISPLAY_AS_RAW), "text" => ApplyMask($externalAcctAccount, $mask));
1455  $row["details"][] = array("label" => $MC->msg("Description", HCU_DISPLAY_AS_RAW), "text" => $externalAcctDesc);
1456  $row["details"][] = array("type" => "wellEnd");
1457  } else {
1458  $row["details"][] = array("label" => $MC->msg("ACH To Account", HCU_DISPLAY_AS_RAW), "text" => $localAcctDesc);
1459  }
1460 
1461  $row["area3"] = $trnAmnt;
1462  if ($isScheduled) {
1463  $row["area3"] .= " " . trim($row["recurringIntervalText"]);
1464  //adding label for interval
1465  $row["interval"] = trim($row["recurringIntervalText"]);
1466  }
1467 
1468  // setup details display
1469  $row["details"][] = array("label" => $MC->msg("Amount", HCU_DISPLAY_AS_RAW), "text" => $trnAmnt);
1470  $row["details"][] = array("label" => $MC->msg("Comment", HCU_DISPLAY_AS_RAW), "text" => $trnMemo);
1471  }
1472 
1473  /**
1474  * function translateTRNM2M(&$row, $isScheduled, $extAccount, $MC)
1475  * This populates the four areas iff the feature_code is TRNM2M. The FROM account
1476  * will always be a local account; only the TO account is an external member.
1477  *
1478  * @param $row -- the scheduled transaction or regular transaction record from the getRegularTransactionsTable or getScheduledTransactionsTable queries.
1479  * @param $isScheduled -- if true, the row comes from the scheduled transaction query versus the regular transaction query.
1480  * @param $extAccount -- the external account record for details.
1481  * @param $MC -- the dictionary for translating.
1482  * @param $dbh -- the database connection (needed for getting the mask variable.)
1483  * @param $Cu -- the credit union
1484  * @param $flagset3 -- contains the two flags needed for determining account descriptions.
1485  */
1486  function translateTRNM2M(&$row, $isScheduled, $extAccount, $MC, $dbh, $Cu, $Uid, $flagset3) {
1487  $localAcctId = $localAcctKey = $localAcctDisp = $localAcctDesc = null;
1488  $externalAcctId = $externalAcctDesc = $externalAcctRouting = $externalAcctAccount = null;
1489  $trnAmnt = $trnMemo = null;
1490 
1491  $mask = GetMask($dbh, $Cu);
1492  $mask = $mask["code"] != 0 ? array("start" => -2) : $mask["data"]; // Just return the default mask in this case.
1493 
1494  $trnDir = "to";
1495 
1496  $row["area1Label"] = $MC->msg("From", HCU_DISPLAY_AS_JS);
1497  $row["area2Label"] = $MC->msg("To", HCU_DISPLAY_AS_JS);
1498 
1499  if ($isScheduled) {
1500  // M2M accounts only go from local to M2M
1501  $localAcctId = explode("|", $row["customData"]["txn"]["from"]);
1502  $localAcctKey = array(
1503  "accountnumber" => $row['customData']['txn']['frommember'],
1504  "recordtype" => $row['customData']['txn']['fromtype']
1505  );
1506  if ($localAcctKey['recordtype'] == "D") {
1507  $localAcctKey['accounttype'] = $row['customData']['txn']['fromsuffix'];
1508  $localAcctKey['certnumber'] = $localAcctId[3];
1509  } else if ($localAcctKey['recordtype'] == "L" || $localAcctKey['recordtype'] == "C") {
1510  $localAcctKey['loannumber'] = $row['customData']['txn']['fromsuffix'];
1511  }
1512  $localAcctDisp = GetMemberDescription($dbh, $Cu, $Uid, $localAcctKey);
1513  if ($localAcctKey['recordtype'] == "D") {
1514  $localAcctDesc = getAccountDescription($dbh, $Cu, $localAcctKey['accountnumber'], $localAcctDisp['description'], $localAcctKey['accounttype'], $localAcctDisp['display_name'],
1515  $flagset3, $localAcctKey['certnumber']);
1516  } else if ($localAcctKey['recordtype'] == "L" || $localAcctKey['recordtype'] == "C") {
1517  $localAcctDesc = getAccountDescription($dbh, $Cu, $localAcctKey['accountnumber'], $localAcctDisp['description'], $localAcctKey['loannumber'], $localAcctDisp['display_name'],
1518  $flagset3, $row["from_certnumber"]);
1519  }
1520 
1521  $externalAcctDesc = trim($extAccount["display_name"]);
1522  $externalAcctAccount = trim($extAccount["remote_info"]["rdfi"]["account"]);
1523  $externalAcctName = trim($extAccount["remote_info"]["rdfi"]["name"]);
1524 
1525  $trnAmnt = money_format('$%i', $row['customData']['txn']["amount"]);
1526  $trnMemo = $row['customData']['txn']["memo"];
1527  } else {
1528  // M2M accounts only go from local to M2M
1529  $externalAcctId = $row["customData"][0]["acct_dest"];
1530 
1531  $localAcctKey = $row['customData'][0]['source_key'];
1532  $localAcctDisp = GetMemberDescription($dbh, $Cu, $Uid, $localAcctKey);
1533  if ($localAcctKey['recordtype'] == "D") {
1534  $localAcctDesc = getAccountDescription($dbh, $Cu, $localAcctKey['accountnumber'], $localAcctDisp['description'], $localAcctKey['accounttype'], $localAcctDisp['display_name'],
1535  $flagset3, $localAcctKey['certnumber']);
1536  } else if ($localAcctKey['recordtype'] == "L" || $localAcctKey['recordtype'] == "C") {
1537  $localAcctDesc = getAccountDescription($dbh, $Cu, $localAcctKey['accountnumber'], $localAcctDisp['description'], $localAcctKey['loannumber'], $localAcctDisp['display_name'],
1538  $flagset3, $row["to_certnumber"]);
1539  }
1540 
1541  $externalAcctDesc = trim($row['customData'][0]["dest_key"]["display_name"]);
1542  $externalAcctAccount = trim($row['customData'][0]["dest_key"]["accountnumber"]);
1543  $externalAcctName = trim($row['customData'][0]["dest_key"]["name"]);
1544 
1545  $trnAmnt = money_format('$%i', $row["fullAmount"]);
1546  $trnMemo = $row["memo"];
1547  }
1548 
1549  $row["details"][] = array("label" => $MC->msg("From Account", HCU_DISPLAY_AS_RAW), "text" => $localAcctDesc);
1550 
1551  $row['area1Text'] = $localAcctDesc;
1552  $row['area2Text'] = $externalAcctDesc;
1553 
1554  // setup details display
1555  $row["details"][] = array("type" => "wellStart");
1556  $row["details"][] = array("type" => "header", "text" => $MC->msg("ACH To Account", HCU_DISPLAY_AS_RAW));
1557  $row["details"][] = array("label" => $MC->msg("Account #", HCU_DISPLAY_AS_RAW), "text" => ApplyMask($externalAcctAccount, $mask));
1558  $row["details"][] = array("label" => $MC->msg("Description", HCU_DISPLAY_AS_RAW), "text" => $externalAcctDesc);
1559  $row["details"][] = array("label" => $MC->msg("EXT Name On Account", HCU_DISPLAY_AS_RAW), "text" => $externalAcctName);
1560  $row["details"][] = array("type" => "wellEnd");
1561 
1562  $row["area3"] = $trnAmnt;
1563  if ($isScheduled) {
1564  $row["area3"] .= " " . trim($row["recurringIntervalText"]);
1565  //adding label for interval
1566  $row["interval"] = trim($row["recurringIntervalText"]);
1567  }
1568 
1569  // setup details display
1570  $row["details"][] = array("label" => $MC->msg("Amount", HCU_DISPLAY_AS_RAW), "text" => $trnAmnt);
1571  $row["details"][] = array("label" => $MC->msg("Comment", HCU_DISPLAY_AS_RAW), "text" => $trnMemo);
1572  }
1573 
1574  /**
1575  * function translateACH(&$row, $isScheduled, $MC)
1576  * This populates the four areas iff the feature_code is ACHCOL or ACHPMT.
1577  *
1578  * @param $row -- the scheduled transaction or regular transaction record from the getRegularTransactionsTable or getScheduledTransactionsTable queries.
1579  * @param $isScheduled -- if true, the row comes from the scheduled transaction query versus the regular transaction query.
1580  * @param $featureCode -- the feature code. Can only be ACHCOL or ACHPMT.
1581  * @param $MC -- the dictionary for translating.
1582  * @param $dbh -- the database connection (needed for getting the mask variable.)
1583  * @param $Cu -- the credit union
1584  * @param $flagset3 -- contains the two flags needed for determining account descriptions.
1585  */
1586  function translateACH(&$row, $partnerRow, $isScheduled, $featureCode, $MC, $dbh, $Cu, $Uid, $flagset3) {
1587  $localAcctId = $localAcctKey = $localAcctDisp = $localAcctDesc = $localAcctNum = null;
1588  $externalAcctId = $externalAcctDesc = $externalAcctRouting = $externalAcctAccount = null;
1589  $trnAmnt = $trnMemo = null;
1590 
1591  $mask = GetMask($dbh, $Cu);
1592  $mask = $mask["code"] != 0 ? array("start" => -2) : $mask["data"]; // Just return the default mask in this case.
1593 
1594  $row["area1Label"] = $MC->msg($featureCode == "ACHCOL" ? "Deposit into" : "Withdrawal from", HCU_DISPLAY_AS_JS);
1595  if ($isScheduled) {
1596  $localAcctId = $row["area1Text"] = $featureCode == "ACHCOL" ?
1597  explode("|", $row['customData']['txn']['to']) :
1598  explode("|", $row['customData']['txn']['from']);
1599 
1600  $localAcctKey = array(
1601  "accountnumber" => $localAcctId[1],
1602  "recordtype" => $localAcctId[0]
1603  );
1604 
1605  if ($localAcctKey['recordtype'] == "D") {
1606  $localAcctKey['accounttype'] = $localAcctId[2];
1607  $localAcctKey['certnumber'] = $localAcctId[3];
1608  } else if ($localAcctKey['recordtype'] == "L" || $localAcctKey['recordtype'] == "C") {
1609  $localAcctKey['loannumber'] = $localAcctId[2];
1610  }
1611 
1612  $localAcctNum = ApplyMask($localAcctKey['accountnumber'], $mask);
1613  $localAcctDisp = GetMemberDescription($dbh, $Cu, $Uid, $localAcctKey);
1614  if ($localAcctKey['recordtype'] == "D") {
1615  $localAcctDesc = getAccountDescription($dbh, $Cu, $localAcctKey['accountnumber'], $localAcctDisp['description'], $localAcctKey['accounttype'], $localAcctDisp['display_name'],
1616  $flagset3, $localAcctKey['certnumber']);
1617  } else if ($localAcctKey['recordtype'] == "L" || $localAcctKey['recordtype'] == "C") {
1618  $localAcctDesc = getAccountDescription($dbh, $Cu, $localAcctKey['accountnumber'], $localAcctDisp['description'], $localAcctKey['loannumber'], $localAcctDisp['display_name'],
1619  $flagset3, $row["to_certnumber"]);
1620  }
1621 
1622  $trnAmnt = money_format('$%i', $row["customData"]["txn"]["amount"]) . " " . trim($row["recurringIntervalText"]);
1623 
1624  $trnMemo = $row["customData"]['txn']['memo'];
1625  $externalAcctDesc = ApplyMask($partnerRow["dfi_data"]["dfi_account"], $mask);
1626  } else {
1627 
1628  $localAcctKey = $row["area1Text"] = $featureCode == "ACHCOL" ?
1629  $row['customData'][0]['dest_key'] :
1630  $row['customData'][0]['source_key'];
1631 
1632  $localAcctNum = ApplyMask($localAcctKey['accountnumber'], $mask);
1633  $localAcctDisp = GetMemberDescription($dbh, $Cu, $Uid, $localAcctKey);
1634  if ($localAcctKey['recordtype'] == "D") {
1635  $localAcctDesc = getAccountDescription($dbh, $Cu, $localAcctKey['accountnumber'], $localAcctDisp['description'], $localAcctKey['accounttype'], $localAcctDisp['display_name'],
1636  $flagset3, $localAcctKey['certnumber']);
1637  } else if ($localAcctKey['recordtype'] == "L" || $localAcctKey['recordtype'] == "C") {
1638  $localAcctDesc = getAccountDescription($dbh, $Cu, $localAcctKey['accountnumber'], $localAcctDisp['description'], $localAcctKey['loannumber'], $localAcctDisp['display_name'],
1639  $flagset3, $row["to_certnumber"]);
1640  }
1641 
1642  $externalAcctDesc = isset($row["memo"]) ? trim($row["memo"]) : "";
1643  $notSoLocal = $featureCode == "ACHCOL" ? $row["customData"][0]["acct_source"] : $row["customData"][0]["acct_dest"];
1644 
1645  if ($row["area2Text"] == "") {
1646  $acct = ApplyMask($notSoLocal["rdfi"]["rdfi_account"], $mask);
1647 
1648  if (count($row["customData"]) > 1) {
1649  $externalAcctDesc = $MC->msg("ACH Batch", HCU_DISPLAY_AS_JS);
1650  } else {
1651  $externalAcctDesc = $acct;
1652  }
1653  }
1654  $trnAmnt = money_format('$%i', $row["fullAmount"]);
1655  $trnMemo = $row['memo'];
1656  }
1657 
1658  $row['area1Text'] = $localAcctDesc;
1659  $row['area2Text'] = $externalAcctDesc;
1660  $row['area3'] = $trnAmnt;
1661 
1662  // SETUP DETAILS DISPLAY
1663  $localAccountLabel = $MC->msg($featureCode == "ACHCOL" ? "ACH To Account" : "ACH From Account", HCU_DISPLAY_AS_RAW);
1664  $localSubaccountLabel = $MC->msg($featureCode == "ACHCOL" ? "ACH To Sub-Account" : "ACH From Sub-Account", HCU_DISPLAY_AS_RAW);
1665 
1666  $row["details"][] = array("type" => "wellStart");
1667  $row["details"][] = array("type" => "header", "text" => $row["feature"]);
1668  $row["details"][] = array("label" => $localAccountLabel, "text" => $localAcctNum);
1669  $row["details"][] = array("label" => $localSubaccountLabel, "text" => $localAcctDesc);
1670  $row["details"][] = array("label" => $MC->msg("Total Amount", HCU_DISPLAY_AS_RAW), "text" => $trnAmnt);
1671  $row["details"][] = array("label" => $MC->msg("ACH Memo", HCU_DISPLAY_AS_RAW), "text" => $trnMemo);
1672  $row["details"][] = array("type" => "wellEnd");
1673 
1674  $customDataCount = count($row["customData"]);
1675  foreach($row["customData"] as $index => $partner) {
1676  $row["details"][] = array("type" => "altGroupStart");
1677 
1678  if ($isScheduled) {
1679  $email = $partnerRow["address"]["email"];
1680  $address1 = $partnerRow["address"]["address1"];
1681  $address2 = $partnerRow["address"]["address2"];
1682  $city = trim($partnerRow["address"]["city"]);
1683  $state = trim($partnerRow["address"]["state"]);
1684  $zip = trim($partnerRow["address"]["zip"]);
1685  $address3 = $city == "" ? ($state == "" ? "" : $state) : ($state == "" ? $city : "$city, $state");
1686  $address3 = $address3 == "" ? $zip : "$address3 $zip";
1687  $routing = $partnerRow["dfi_data"]["dfi_routing"];
1688  $account = ApplyMask($partnerRow["dfi_data"]["dfi_account"], $mask);
1689  $accounttype = $partnerRow["dfi_data"]["dfi_account_type"];
1690  $addenda = $row['customData']['txn']['addenda'];
1691  $amount = $partner["amount"];
1692  } else {
1693  $notSoLocal = $featureCode == "ACHCOL" ? "acct_source" : "acct_dest";
1694  $dfi = $partner[$notSoLocal]["rdfi"];
1695  $rem = $partner[$notSoLocal]["remote_entity"];
1696  $name = $rem["name"];
1697  $email = $rem["email"];
1698  $address1 = $rem["address1"];
1699  $address2 = $rem["address2"];
1700  $address3 = ""; // TODO: this information is not saved here.
1701  $routing = $dfi["rdfi_routing"];
1702  $account = ApplyMask($dfi["rdfi_account"], $mask);
1703  $accounttype = $dfi["rdfi_account_type"];
1704  $addenda = $dfi["addenda"];
1705  $amount = $partner["amount"];
1706  }
1707 
1708  switch($accounttype) {
1709  case 10: $accounttype = $MC->msg("ACH Checking", HCU_DISPLAY_AS_JS); break;
1710  case 20: $accounttype = $MC->msg("ACH Savings", HCU_DISPLAY_AS_JS); break;
1711  default: $accounttype = "";
1712  }
1713 
1714  if (!$isScheduled && $customDataCount > 1) {
1715  $row["details"][] = array("type" => "header", "text" => $name);
1716  }
1717 
1718  $row["details"][] = array("label" => $MC->msg("Amount", HCU_DISPLAY_AS_RAW), "text" => money_format('$%i', $amount));
1719  $row["details"][] = array("label" => $MC->msg("Email", HCU_DISPLAY_AS_RAW), "text" => $email);
1720  $row["details"][] = array("type" => "address", "label" => $MC->msg("ACH Address", HCU_DISPLAY_AS_RAW), "addresses" => array($address1, $address2, $address3));
1721  $row["details"][] = array("label" => $MC->msg("ACH Routing Number", HCU_DISPLAY_AS_RAW), "text" => $routing);
1722  $row["details"][] = array("label" => $MC->msg("Account", HCU_DISPLAY_AS_RAW), "text" => $account);
1723  $row["details"][] = array("label" => $MC->msg("Account Type", HCU_DISPLAY_AS_RAW), "text" => $accounttype);
1724  $row["details"][] = array("label" => $MC->msg("ACH Addenda", HCU_DISPLAY_AS_RAW), "text" => $addenda);
1725 
1726  $row["details"][] = array("type" => "altGroupEnd");
1727  }
1728  }
1729 
1730  /**
1731  * function translateCleanup(&$row, $isScheduled)
1732  * This function removes all attributes of the row that were needed to calculate the details and areas and are not being used for the actual grid.
1733  * It also adds attributes needed to parse details.
1734  *
1735  * @param $row -- the scheduled transaction or regular transaction record from the getRegularTransactionsTable or getScheduledTransactionsTable queries.
1736  * @param $isScheduled -- if true, the row comes from the scheduled transaction query versus the regular transaction query.
1737  */
1738  function translateCleanup(&$row, $isScheduled) {
1739  unset($row["customData"]);
1740  unset($row["amount"]);
1741  unset($row["to_desc"]);
1742  unset($row["from_desc"]);
1743  unset($row["fromid"]);
1744  unset($row["toid"]);
1745  unset($row["from_accounttype"]);
1746  unset($row["from_acct"]);
1747  unset($row["from_certnumber"]);
1748  unset($row["from_displayname"]);
1749  unset($row["to_accounttype"]);
1750  unset($row["to_acct"]);
1751  unset($row["to_certnumber"]);
1752  unset($row["to_displayname"]);
1753  unset($row["processed_by"]);
1754  unset($row["grid"]);
1755 
1756  if ($isScheduled) {
1757  unset($row["name"]);
1758  unset($row["user_id"]);
1759  unset($row["create_date"]);
1760  unset($row["start_date"]);
1761  unset($row["end_date"]);
1762  unset($row["next_trigger_date"]);
1763  unset($row["status"]);
1764  unset($row["approved_date"]);
1765  unset($row["username"]);
1766  unset($row["approved_username"]);
1767  unset($row["approved_by"]);
1768  unset($row["txn_data"]);
1769  unset($row["repeating_parameters"]);
1770  unset($row["last_edit_date"]);
1771  } else {
1772  unset($row["accountnumber"]);
1773  unset($row["accounttype"]);
1774  unset($row["deposittype"]);
1775  unset($row["transactioncode"]);
1776  unset($row["effective_date"]);
1777  unset($row["posted_date"]);
1778  unset($row["memo"]);
1779  unset($row["posted_by"]);
1780  unset($row["approved_date"]);
1781  unset($row["username"]);
1782  unset($row["approved_username"]);
1783  unset($row["approved_by"]);
1784  unset($row["transdata"]);
1785  unset($row["processed_date"]);
1786  unset($row["processed_status"]);
1787  }
1788 
1789  // Need to set all possible attributes or kendo template will fail.
1790  for($i = 0, $count = count($row["details"]); $i != $count; $i++) {
1791  $detail = $row["details"][$i];
1792  $detail["type"] = !HCU_array_key_exists("type", $detail) || !isset($detail["type"]) ? "normalRow" : trim($detail["type"]);
1793  $detail["label"] = !HCU_array_key_exists("label", $detail) || !isset($detail["label"]) ? "" : trim($detail["label"]);
1794  $detail["text"] = !HCU_array_key_exists("text", $detail) || !isset($detail["text"]) ? "" : trim($detail["text"]);
1795  $detail["addresses"] = !HCU_array_key_exists("addresses", $detail) || !isset($detail["addresses"]) ? array() : $detail["addresses"];
1796 
1797  $addresses = array();
1798  foreach($detail["addresses"] as $address) {
1799  $addresses[] = isset($address) ? trim($address) : "";
1800  }
1801  $detail["addresses"] = $addresses;
1802  $row["details"][$i] = $detail;
1803  }
1804  }
1805 
1806  /**
1807  * function readActivityGrid($HB_ENV, $genErr, $parameters, $confirmPermissions, $mode="read")
1808  * This function gets the resultset for a particular grid. It is the main function that calls everything for read, filter, and clearFilter data calls.
1809  *
1810  * @param $HB_ENV -- the global environment variables.
1811  * @param $genErr -- the generic error to return if there is any sort of error.
1812  * @param $parameters -- the parameters from the REQUEST.
1813  * @param $confirmPermissions -- map of users and what confirmation permissions they have. (If they don't have TRN permissions, then they won't be able to see TRN records.)
1814  * @param $mode -- the mode to use: either "read", "clearFilter", or "filter." Corresponds with the particular data call.
1815  *
1816  * @return array
1817  * -> Results -- Has to be packaged as such because rules.
1818  * : -> homecuInfo -- The message to return saying that everything was okay (if it actually was.)
1819  * : -> homecuErrors -- This will be the generic error plus the error code
1820  * : -> homecuData -- The records returned for the grid in question
1821  * : -> sqls -- All SQL used
1822  */
1823  function readActivityGrid($HB_ENV, $genErr, $parameters, $confirmPermissions, $mode = "read") {
1824  // Extract the values that we need. Don't discard the environment information because it could be needed later.
1825  $Cu = $HB_ENV["Cu"];
1826  $MC = $HB_ENV["MC"];
1827  $Cn = $HB_ENV["Cn"];
1828  $dbh = $HB_ENV["dbh"];
1829  $Uid = $HB_ENV["Uid"];
1830  $tz = $HB_ENV["tz"];
1831  $logger = $HB_ENV["SYSENV"]["logger"];
1832 
1833  if (!HCU_array_key_exists("grid", $parameters)) {
1834  throw new exception("Grid is not specified.", 1);
1835  }
1836  $grid = $parameters["grid"];
1837 
1838  $sqls = array();
1839  // Buffer to write own errors and see what translates into the dictionary.
1840 
1841  try {
1842  $whereTranshdr = array();
1843  $whereSched = array();
1844 
1845  $validUserIds = getValidUserIds($dbh, $Cu, $Cn, $sqls);
1846  $validUserIds = $validUserIds["validUserIds"];
1847 
1848  switch ($mode) {
1849  case "read": getDefaultFilter($whereTranshdr, $whereSched, $dbh, $Cu, $Cn, $validUserIds); break;
1850  case "clearFilter": getFilter(array(), $MC, "scheduledTransactions", $whereTranshdr, $whereSched, $dbh, $Cu, $Uid); break;
1851  case "filter": getFilter($parameters, $MC, "scheduledTransactions", $whereTranshdr, $whereSched, $dbh, $Cu, $Uid); break;
1852  default: throw new exception("Mode is not valid.", 1); break;
1853  }
1854 
1855  $tz = new DateTimeZone($tz);
1856 
1857  $trans = Get_HaveTrans($dbh,$HB_ENV);
1858 
1859  $records = array();
1860  getScheduledTransactionsTable($sqls, $records, $whereSched, $grid, $Uid, $dbh, $Cu, $MC, $confirmPermissions, $tz, $validUserIds, $trans, $HB_ENV["Fset3"]);
1861 
1862  if ($grid != "scheduledTransactions") {
1863  getRegularTransactionsTable($sqls, $records, $whereTranshdr, $grid, $Uid, $MC, $dbh, $Cu, $confirmPermissions, $tz, $validUserIds, $trans, $HB_ENV["Fset3"], $HB_ENV);
1864  }
1865 
1866  usort($records, $grid == "pendingApproval" ? "cmp" : "revCmp");
1867  gridModify($records);
1868  } catch(exception $e) {
1869  $logger->error($e->getCode() . ": " . $e->getMessage());
1870  return array("results" => array("homecuInfo" => array(), "homecuErrors" => array("$genErr {$e->getCode()}."), "homecuData" => array(), "sqls" => $sqls, "mode" => $mode,
1871  "grid" => $grid));
1872  }
1873  return array("results" => array("homecuInfo" => array(), "homecuErrors" => array(), "homecuData" => $records, "sqls" => $sqls, "mode" => $mode, "grid" => $grid));
1874  }
1875 
1876  // Align with banking's usual data returns
1877  // ******************************************
1878 
1879  header('Content-type: application/json');
1880  if (!$HB_ENV["SYSENV"]["devmode"])
1881  unset($aryReply["results"]["sqls"]);
1882  print HCU_JsonEncode($aryReply);