Odyssey
aAccessControl.prg
1 <?php
2 /**
3  * @package UserSupport (Subpackage access control)
4  * @author SPB
5  *
6  * This script is run through the user hub.
7  */
8 require_once("$sharedLibrary/sAPIAppl.i");
9 require_once("$sharedLibrary/sAPIAppl.std.i");
10 require_once(dirname(__FILE__) . "/aAccessControl.data");
11 
12 IncludeApplPlugin(array("dbh" => $dbh, "Cu" => $Cu));
13 
14 $string = array("filter" => HCUFILTER_INPUT_STRING);
15 $parameters = array("a" => array("operation" => "", "payload" => "", "userId" => "", "isPrimary" => "", "accountnumber" => "", "subaccounts" => "", "accounts" => ""));
16 HCU_ImportVars($parameters, "a", array("operation" => $string, "payload" => $string, "userId" => $string, "accountnumber" => $string, "subaccounts" => $string,
17  "accounts" => $string, "isPrimary" => $string, "latestKendoid" => $string));
18 extract($parameters["a"]);
19 
20 $operation = isset($operation) ? trim($operation) : "";
21 $isPrimary = isset($isPrimary) ? trim($isPrimary) == "Y" : false;
22 $payload = isset($payload) ? trim($payload) : "";
23 $accountnumber = isset($accountnumber) ? trim($accountnumber) : "";
24 $subaccounts = isset($subaccounts) ? trim($subaccounts) : "";
25 $accounts = isset($accounts) ? trim($accounts) : "";
26 $latestKendoid = isset($latestKendoid) ? intval($latestKendoid) : 1;
27 
28 $SYSENV["Cu"] = $Cu;
29 $SYSENV["cu"] = $Cu;
30 $SYSENV["live"] = $live;
31 $SYSENV["dbh"] = $dbh;
32 $SYSENV["flagset"] = $Fset;
33 $SYSENV["flagset2"] = $Fset2;
34 $SYSENV["flagset3"] = $Fset3; // For the Request Core Cross Account Packet Option.
35 $SYSENV["Cn"] = $Cn;
36 
37 $SYSENV["userId"] = null;
38 $userId = null;
39 if ($payload != "") {
40  try { $userId = HCU_PayloadDecode($Cu, $payload); } catch(exception $e) {}
41  $userId = isset($userId) ? $userId["user_id"] : null;
42  $SYSENV["userId"] = $userId;
43 }
44 
45 $SYSENV["disallowMultipleAccounts"] = ($Fset3 & GetFlagsetValue("CU3_DISALLOW_MULTIPLE_ACCOUNTS")) !== 0;
46 $SYSENV["allowZeroes"] = ($Fset3 & GetFlagsetValue("CU3_ALLOW_LEAD_ZEROS")) !== 0;
47 
48 if ($operation != "") {
49  if (!isset($userId)) {
50  $returnArray = array("error" => "No User Found", "record" => array(), "sql" => array());
51  } else {
52  switch($operation) {
53  case "saveAccountsAndSubaccounts":
54  $returnArray = SaveAccountsAndSubaccounts($SYSENV, $accounts, $subaccounts);
55  break;
56  case "createSubaccounts":
57  $returnArray = CreateSubaccounts($SYSENV, $subaccounts, $accountnumber, $latestKendoid);
58  break;
59  case "getAccountFromCore":
60  $returnArray = GetAccountFromCore($SYSENV, $accountnumber, $isPrimary);
61  unset($returnArray["fullData"]);
62  break;
63  case "deleteSubAccounts":
64  $returnArray = DeleteSubAccounts($SYSENV, $accountnumber, $subaccounts);
65  break;
66  default: // Won't get here
67  $returnArray = array("error" => array("Operation not specified: '$operation'"), "record" => array(), "sql" => array());
68  }
69  }
70 
71  header('Content-type: application/json');
72  print HCU_JsonEncode($returnArray);
73 } else {
74  if (isset($userId)) {
75  PrintPage("$menu_link?ft=$ft", $userId, ReadAccessControl($SYSENV), $payload, $live != "Y", $SYSENV["allowZeroes"]);
76  } else { ?>
77  <div class='noUserFound'><div>No User Found</div></div>
78  <?php }
79 }
80 
81 /**
82  * function printPage($self, $userId, $readData)
83  * This will print the page
84  *
85  * @param $self -- the URL of this script
86  * @param $userId -- the user id
87  * @param $readData -- the data from the read function
88  * @param $isBatch -- if is batch, then there is no way to add accounts to primary users through this script.
89  */
90 function PrintPage($self, $userId, $readData, $payload, $isBatch, $allowZeroes) { ?>
91  <script type="text/javascript">
92  //# sourceURL=accessControl.js
93 
94  var userSupportContents = {};
95  userSupportContents.accountData = [];
96  userSupportContents.subaccountData = [];
97  userSupportContents.isPrimary = false;
98  userSupportContents.subaccountsWithChanges = [];
99  userSupportContents.accountsHaveChanges = false;
100 
101  <?php
102  /**
103  * function Dirtify(dirty, container)
104  * This function sets the dirty flag after the cell is changed.
105  *
106  * @param Boolean dirty -- if there are changes or not.
107  * @param HTMLElement container -- this is the cell. (TD tag)
108  */
109  ?>
110  function Dirtify(dirty, container) {
111  if (dirty) {
112  if (!$(container).hasClass("k-dirty-cell")) {
113  $(container).addClass("k-dirty-cell");
114  $(container).prepend("<span class='k-dirty'></span>");
115  }
116  } else {
117  $(container).removeClass("k-dirty-cell");
118  $(container).find(".k-dirty").remove();
119  }
120  }
121 
122  <?php
123  /**
124  * function CreateAccountSnapshot(item)
125  * This sets the original fields to the current value before changes.
126  *
127  * @param {} item -- the dataItem in the dataSource to update.
128  */
129  ?>
130  function CreateAccountSnapshot(item) {
131  item.org_access = item.access;
132  item.org_esDsk = item.esDsk;
133  item.org_esApp = item.esApp;
134  item.org_bpDsk = item.bpDsk;
135  item.org_bpApp = item.bpApp;
136  item.org_rdcDsk = item.rdcDsk;
137  item.org_rdcApp = item.rdcApp;
138  }
139 
140  <?php
141  /**
142  * function CreateSubaccountSnapshot(item)
143  * This sets the original fields to the current value before changes.
144  *
145  * @param {} item -- the dataItem in the dataSource to update.
146  */
147  ?>
148  function CreateSubaccountSnapshot(item) {
149  item.org_int_deposit = item.int_deposit;
150  item.org_int_withdraw = item.int_withdraw;
151  item.org_ext_deposit = item.ext_deposit;
152  item.org_ext_withdraw = item.ext_withdraw;
153  item.org_view_balances = item.view_balances;
154  item.org_view_transactions = item.view_transactions;
155  }
156 
157  <?php
158  /**
159  * function GetChangedAccounts()
160  * Gets the changed accounts and packages them for the save call.
161  */
162  ?>
163  function GetChangedAccounts() {
164  var data = $("#accountGrid").data("kendoGrid").dataSource.data();
165  var accounts = [];
166  for(var i = 0; i != data.length; i++) {
167  var item = data[i];
168 
169  if (!item.dirty) {
170  continue;
171  }
172 
173  var realItem = {accountnumber: item.accountnumber};
174 
175  var hasChanges = false;
176  if (item.access != item.org_access) {
177  realItem.access = item.access;
178  hasChanges = true;
179  }
180  if (item.esDsk != item.org_esDsk || item.esApp != item.org_esApp) {
181  realItem.esDsk = item.esDsk;
182  realItem.esApp = item.esApp;
183  hasChanges = true;
184  }
185  if (item.bpDsk != item.org_bpDsk || item.bpApp != item.org_bpApp) {
186  realItem.bpDsk = item.bpDsk;
187  realItem.bpApp = item.bpApp;
188  hasChanges = true;
189  }
190  if (item.rdcDsk != item.org_rdcDsk || item.rdcApp != item.org_rdcApp) {
191  realItem.rdcDsk = item.rdcDsk;
192  realItem.rdcApp = item.rdcApp;
193  hasChanges = true;
194  }
195 
196  if (hasChanges) {
197  accounts.push(realItem);
198  }
199  }
200 
201  return {accounts: accounts};
202  }
203 
204  <?php
205  /**
206  * function GetChangedSubaccounts()
207  * Gets the changed subaccounts and packages them for the save call.
208  */
209  ?>
210  function GetChangedSubaccounts() {
211  var data = userSupportContents.subaccountData;
212  var subaccounts = [];
213  for(var i = 0; i != data.length; i++) {
214  var item = data[i];
215  if (!item.dirty) {
216  continue;
217  }
218 
219  accountnumber = item.accountnumber;
220  var realItem = {accountnumber: item.accountnumber, accounttype: item.accounttype, certnumber: item.certnumber, recordtype: item.recordtype};
221  <?php // Remaining columns for the primary key ?>
222 
223  var hasChanges = false;
224  if (item.int_deposit != item.org_int_deposit) {
225  realItem.int_deposit = item.int_deposit;
226  hasChanges = true;
227  }
228  if (item.int_withdraw != item.org_int_withdraw) {
229  realItem.int_withdraw = item.int_withdraw;
230  hasChanges = true;
231  }
232  if (item.ext_deposit != item.org_ext_deposit) {
233  realItem.ext_deposit = item.ext_deposit;
234  hasChanges = true;
235  }
236  if (item.ext_withdraw != item.org_ext_withdraw) {
237  realItem.ext_withdraw = item.ext_withdraw;
238  hasChanges = true;
239  }
240  if (item.view_balances != item.org_view_balances) {
241  realItem.view_balances = item.view_balances;
242  hasChanges = true;
243  }
244  if (item.view_transactions != item.org_view_transactions) {
245  realItem.view_transactions = item.view_transactions;
246  hasChanges = true;
247  }
248 
249  if (hasChanges) { <?php // Prevents the case where user checks and then unchecks a checkbox. ?>
250  subaccounts.push(realItem);
251  }
252  }
253 
254  return subaccounts;
255  }
256 
257  <?php
258  /**
259  * function PostPostPostPost()
260  * This obviously happens after everything else.
261  */
262  ?>
263  function PostPostPostPost() {
264  $("#externalTabWindow").data("isClosing", true);
265  $("#externalTabWindow").data("kendoWindow").close();
266  $("#externalTabWindow").data("isClosing", false);
267  }
268 
269  <?php
270  /**
271  * function UserSupportDoOnClose()
272  * Whew! I saved a couple of lines. No, this is needed as it is the hook function from the userSupportHead script.
273  */
274  ?>
275  function UserSupportDoOnClose() {
276  PotentiallyCancelChanges();
277  $("#externalTabWindow").data("shouldClose", false);
278  }
279 
280  <?php
281  /**
282  * function PotentiallyCancelChanges()
283  * This displays the discard changes dialog on close if there are changes made.
284  */
285  ?>
286  function PotentiallyCancelChanges() {
287  if ($("#accountGrid .k-dirty-cell .k-dirty").length == 0 && $(".subaccountGrid .k-dirty-cell .k-dirty").length == 0) {
288  PostPostPostPost();
289  } else {
290  var discardChangesDialog = $("#discardChangesDialog").data("kendoDialog");
291  if (discardChangesDialog == null) {
292  discardChangesDialog = $("<div id='discardChangesDialog'></div>").appendTo("body").kendoDialog({
293  title: "Discard Changes",
294  content: "<p>Changes have been made to this user's account access.</p><p>Do you wish to discard your changes?</p>",
295  actions: [
296  {text: "No"},
297  {text: "Yes", primary: true, action: function() {
298  PostPostPostPost();
299  }}
300  ],
301  visible: false,
302  open: function() {
303  if (window.activeWindows != null) {
304  window.activeWindows.push(this);
305  }
306  },
307  close: function() {
308  if (window.activeWindows != null) {
309  window.activeWindows.pop();
310  }
311  }
312  }).data("kendoDialog");
313  }
314  discardChangesDialog.open();
315  }
316  }
317 
318  <?php
319  /**
320  * function GetDirtyFlags(isAccountGrid, accountnumber)
321  * This gets the dirty flags so that they can be restored when going back to the accounts or the subaccounts.
322  *
323  * @param boolean isAccountGrid -- if true, the dirty is from the account, versus the subaccount.
324  * @param Number accountnumber -- the accountnumber of the subaccounts visible.
325  *
326  * @return dirtyFlags -- the array of dirty flags to replace.
327  */
328  ?>
329  function GetDirtyFlags(isAccountGrid, accountnumber) {
330  var dirtyFlags = userSupportContents.dirtyFlags[isAccountGrid ? "account" : "subaccount"];
331  if (!isAccountGrid) {
332  if (dirtyFlags[accountnumber] == null) {
333  dirtyFlags[accountnumber] = [];
334  }
335  }
336  return dirtyFlags;
337  }
338 
339  <?php
340  /**
341  * function SaveDirtyFlags(isAccountGrid)
342  * This function saves the dirty flags in the right array for retrieval later.
343  *
344  * @param boolean isAccountGrid -- if true, the dirty is from the account, versus the subaccount.
345  */
346  ?>
347  function SaveDirtyFlags(isAccountGrid) {
348  var accountnumber = $(".userAccessControlDiv .breadcrumb .active").text().trim();
349  var gridSelector = isAccountGrid ? "#accountGrid" : ".subaccountGrid";
350  var dirtyFlags = GetDirtyFlags(isAccountGrid, accountnumber);
351  isAccountGrid ? dirtyFlags.splice(0,dirtyFlags.length) : dirtyFlags[accountnumber].splice(0,dirtyFlags[accountnumber].length);
352  <?php // Clear the dirty flags. ?>
353  $(gridSelector).each(function() {
354  var grid = $("#"+$(this).attr("id")).data("kendoGrid");
355  $(this).find("tbody tr").each(function() {
356  var dataItem = grid.dataItem($(this));
357  var uid = $(this).data("uid");
358  $(this).find(".checkTD").each(function(index) {
359  if ($(this).is(".k-dirty-cell")) {
360  isAccountGrid ? dirtyFlags.push({uid: uid, index: index + 1}) : dirtyFlags[accountnumber].push({kendoid: dataItem.kendoid, index: index + 3,
361  first: $(this).find(".restriction:eq(0)").hasClass("allow"), sec: $(this).find(".restriction:eq(1)").hasClass("allow")});
362  }
363  });
364  });
365  });
366  }
367 
368  <?php
369  /**
370  * function RestoreDirtyFlags(isAccountGrid)
371  * Restores the dirty flags.
372  *
373  * @param boolean isAccountGrid -- if true, the dirty is from the account, versus the subaccount.
374  */
375  ?>
376  function RestoreDirtyFlags(isAccountGrid) {
377  var accountnumber = $(".userAccessControlDiv .breadcrumb .active").text().trim();
378  var gridSelector = isAccountGrid ? "#accountGrid" : ".subaccountGrid";
379  var dirtyFlags = GetDirtyFlags(isAccountGrid, accountnumber);
380  var theseDirtyFlags = isAccountGrid ? dirtyFlags : dirtyFlags[accountnumber];
381 
382  if (!isAccountGrid) {
383  var uidMap = {};
384  var data = $("#subaccountGridDeposit").data("kendoGrid").dataSource.data();
385  for(var i = 0, length = data.length; i != length; i++) {
386  uidMap[data[i].kendoid] = data[i].uid;
387  }
388  var data = $("#subaccountGridLoan").data("kendoGrid").dataSource.data();
389  for(var i = 0, length = data.length; i!= length; i++) {
390  uidMap[data[i].kendoid] = data[i].uid;
391  }
392  }
393 
394  for(var i = 0; i != theseDirtyFlags.length; i++) {
395  var aDirty = theseDirtyFlags[i];
396  var aSelector = $(gridSelector+ " tbody tr[data-uid='"+ (isAccountGrid ? aDirty.uid : uidMap[aDirty.kendoid]) + "'] td:eq("+ aDirty.index + ")");
397  $(aSelector).addClass("k-dirty-cell");
398  $(aSelector).prepend("<span class='k-dirty'></span>");
399  }
400  }
401 
402  <?php
403  /**
404  * function Init()
405  * The starting point for the wonders which is this script.
406  */
407  ?>
408  function Init() {
409  $.homecuValidator.setup({formValidate: "emptyForm", formStatusField: 'accessControlErrorDiv'});
410 
411  $("#externalTabWindow").data("preferredHeight", "auto");
412  userSupportContents.dirtyFlags = {account: [], subaccount: {}};
413  <?php printExtendShowOverflown(); ?>
414 
415  var leTemplate = kendo.template("\\# if (#: code #) { \\# <div class='restriction allow hcu-all-100'><i class='fa fa-check'></i></div> \\# } else { \\#"
416  + "<div class='restriction ban hcu-all-100'><i class='fa fa-ban'></i></div> \\# } \\#");
417 
418  var accountGrid = $("#accountGrid").kendoGrid({
419  dataSource: {
420  data: userSupportContents.accountData,
421  schema: {
422  model: {
423  id: "accountnumber",
424  fields: {
425  accountnumber: {type: "string"},
426  access: {type: "boolean"},
427  esDsk: {type: "boolean"},
428  esApp: {type: "boolean"},
429  bpDsk: {type: "boolean"},
430  bpApp: {type: "boolean"},
431  rdcDsk: {type: "boolean"},
432  rdcApp: {type: "boolean"}
433  }
434  }
435  },
436  batch: true,
437  sort: {field: "accountnumber", dir: "asc"}
438  },
439  columns: [
440  {headerTemplate: "Account #", columns: [{field: "accountnumber", headerTemplate: "&nbsp;", attributes: {"class": "uneditable"}, width: 45,
441  template: "# var dis = userSupportContents.subaccountsWithChanges[accountnumber] == null ? 'style=\"display:none\"' : ''; "
442  + "if (accountnumber == null) { # &nbsp; # } else { # <a href='\\#' class='subaccountEdit'>#: accountnumber #</a> # } #"
443  + "<div class='tabAsterisk' #= dis #>"
444  + "<i class='fa fa-asterisk fa-6'></i></div>"}]},
445  {headerTemplate: "Auto-Add <span class='show-autoadd-help' data-role='tooltip' data-position='top'>"
446  + "<span class='fa fa-info-circle fa-1'></span>"
447  + "</span>",
448  columns: [{field: "access", headerTemplate: "&nbsp;", width: 45, attributes: {"class": "accessTD checkTD"},
449  template: "<input type='checkbox' id='account_#: accountnumber #'" +
450  " name='access' # if (access) { # checked # } #>"}]},
451 
452  {headerTemplate: "eStatements", columns: [
453  {headerTemplate: "Dsk", template: leTemplate({code: "esDsk"}), width: 30, attributes: {"data-name": "esDsk"}},
454  {headerTemplate: "App", template: leTemplate({code: "esApp"}), width: 30, attributes: {"data-name": "esApp"}}
455  ]},
456  {headerTemplate: "Bill Pay", columns: [
457  {headerTemplate: "Dsk", template: leTemplate({code: "bpDsk"}), width: 30, attributes: {"data-name": "bpDsk"}},
458  {headerTemplate: "App", template: leTemplate({code: "bpApp"}), width: 30, attributes: {"data-name": "bpApp"}}
459  ]},
460  {headerTemplate: "RDC Setting", columns: [
461  {headerTemplate: "Dsk", template: leTemplate({code: "rdcDsk"}), width: 30, attributes: {"data-name": "rdcDsk"}},
462  {headerTemplate: "App", template: leTemplate({code: "rdcApp"}), width: 30, attributes: {"data-name": "rdcApp"}}
463  ]}
464  ],
465  autoBind: false,
466  height: 400,
467  noRecords: {
468  template: "<tr><td colspan='5'><span class='hcu-secondary'><span class='vsgSecondary'>No Records Found</span></span></td></tr>"
469  }
470  }).data("kendoGrid");
471 
472  $("#accountGrid .k-grid-header").css({paddingRight: "initial"});
473 
474  var templateTemplate = kendo.template("<div class='checkSpanSubaccountDiv'><div class='col-xs-6'><input type='checkbox' name='#: col1 #'"
475  + " class='dataCheckbox' \\# if (#: col1 #) { \\# checked \\# } \\# data-index='#: index #'></div><div class='col-xs-6'>"
476  + "<input type='checkbox' name='#: col2 #' class='dataCheckbox'"
477  + " \\# if (#: col2 #) { \\# checked \\# } \\# data-index='#: index + 1 #'></div></div>");
478 
479  var templateTemplate = kendo.template(""
480 
481  <?php // Get the correct boolean value based on the which columns the template is applied to. ?>
482  + "# var restrictClass1 = col1 == 'view_balances' ? 'restrictViewBalances' : (col1 == 'int_deposit' ? 'restrictIntDeposit' : 'restrictExtDeposit'); #"
483  + "# var restrictClass2 = col2 == 'view_transactions' ? 'restrictViewTransactions' :"
484  + "(col2 == 'int_withdraw' ? 'restrictIntWithdraw' : 'restrictExtWithdraw'); #"
485 
486  <?php // If the boolean value is true, then apply the disabled class. ?>
487  + "\\# var disabledClass1 = #: restrictClass1 # ? 'vsgDisabled' : ''; \\#"
488  + "\\# var disabledClass2 = #: restrictClass2 # ? 'vsgDisabled' : ''; \\#"
489 
490  + "<div class='checkSpanSubaccountDiv'><div class='col-xs-6 replaceDiv' data-name='#: col1 #' data-index='#: index #'><center>"
491  + "\\# if (#: col1 #) { \\#"
492  + "<div class='restriction allow hcu-all-100 \\#: disabledClass1 \\#'><i class='fa fa-check'></i></div> "
493  + "\\# } else { \\#"
494  + "<div class='restriction ban hcu-all-100 \\#: disabledClass1 \\#'>"
495  + "<i class='fa fa-ban'></i></div> "
496  + "\\# } \\#"
497  + "</center></div><div class='col-xs-6 replaceDiv' data-name='#: col2 #' data-index='#: index + 1 #'><center>"
498  + "\\# if (#: col2 #) { \\#"
499  + " <div class='restriction allow hcu-all-100 \\#: disabledClass2 \\#'><i class='fa fa-check'></i></div> "
500  + "\\# } else { \\#"
501  + "<div class='restriction ban hcu-all-100 \\#: disabledClass2 \\#'><i class='fa fa-ban'></i></div>"
502  + " \\# } \\#"
503  + "</center></div></div>");
504 
505  var templateHeaderTemplate = kendo.template("<div class='checkSpanSubaccountDiv'><div class='col-xs-6'><i class='fa #: fa1 # topNotCheckbox' "
506  + " data-index='#: index #'"
507  + "title='#: fa1Title #'></i></div><div class='col-xs-6'><i class='fa #: fa2 # topNotCheckbox'"
508  + "data-index='#: index + 1 #' title='#: fa2Title #'></i></div></div>");
509 
510  var subaccountGridDefinition = {
511  dataSource: {
512  <?php /* This is an intermediate solution.
513  /* 1) One solution is to do filtering client-side despite every grid being the same except for the filter.
514  This results in all the data being copied per grid.
515  You get timing issues because there is so much data on the screen. (Problem with mammoth trusted vendors.)
516  2) Another solution is to do server-side filtering which makes sense in some cases.
517  Not in this case because the subaccount records are appended to array
518  for the subaccounts. It isn't that much data and it doesn't need extra data calls.
519  (Server-side filtering means a call everytime the filter changes.)
520  3) A third solution is to do a local array and $.grep or otherwise restrict the data and then shove it into the grid.
521  This is what it was doing. There was a
522  couple of problems with this: a) When the grid was updated, records would show up sometimes but not always.
523  b) read call doesn't work because transport is not set up.
524  4) This solution: turn on the server-side filtering (so the client doesn't handle it) but add logic to filter yourself on read.
525  This is the first time that I've done this method.
526  */ ?>
527  transport: {
528  read: function(options) {
529  if (options.data.filter == null) {
530  options.success([]);
531  return;
532  }
533 
534  var filteredData = [];
535  for(var i = 0, iLength = userSupportContents.subaccountData.length; i != iLength; i++) {
536  var iRecord = userSupportContents.subaccountData[i];
537  var logic = options.data.filter.logic;
538  var valid = logic == "and";
539 
540  for(var j = 0, jLength = options.data.filter.filters.length; j != jLength; j++) {
541  var jRecord = options.data.filter.filters[j];
542  var thisValid = true;
543  switch(jRecord.operator) {
544  case "eq":
545  thisValid = iRecord[jRecord.field] == jRecord.value;
546  break;
547  <?php // Don't care about the others for this usage. ?>
548  }
549  valid = logic == "and" ? valid && thisValid : valid || thisValid;
550  }
551  if (valid) {
552  filteredData.push(iRecord);
553  }
554  }
555  options.success(filteredData);
556  }
557  },
558  schema: {
559  model: {
560  id: "kendoid",
561  fields: {
562  kendoid: {type: "number"},
563  accountnumber: {type: "string"},
564  accounttype: {type: "string"},
565  display_name: {type: "string"},
566  description: {type: "string"},
567  view_transactions: {type: "boolean"},
568  view_balances: {type: "boolean"},
569  int_deposit: {type: "boolean"},
570  int_withdraw: {type: "boolean"},
571  ext_deposit: {type: "boolean"},
572  ext_withdraw: {type: "boolean"},
573  recordtype: {type: "string"},
574  recordTypeFilter: {type: "string"},
575  checked: {type: "boolean"},
576  restrictIntDeposit: {type: "boolean"},
577  restrictExtDeposit: {type: "boolean"},
578  restrictIntWithdraw: {type: "boolean"},
579  restrictExtWithdraw: {type: "boolean"},
580  restrictViewBalances: {type: "boolean"},
581  restrictViewTransactions: {type: "boolean"},
582  perm_account_sort: {type: "string"},
583  perm_type_sort: {type: "number"}
584  }
585  }
586  },
587  serverFiltering: true,
588  sort: [{field: "accountnumber", dir: "asc"}, {field: "perm_account_sort", dir: "asc"},
589  {field: "perm_type_sort", dir: "asc"}, {field: "accounttype", dir: "asc"}]
590  },
591  columns: [
592  {template: "<input type='checkbox' class='rowCheckbox'>", attributes: {"class": "checkboxTD showClickable"},
593  headerTemplate: "<input type='checkbox' class='allCheckbox'>",
594  width: "45px", headerAttributes: {"class": "allCheckboxTD showClickable"}},
595  {title: "Sub-Account", field: "accounttype", width: 65},
596  {headerTemplate: "<a href='#' class='descriptionLink'>Description</a>", field: "display_name",
597  template: "<span class='displayName' style='display:none;'># if (display_name == '') { # <span class='vsgDisabled'> #: description # </span>"
598  + "# } else { # #: display_name # # } #</span><span class='coreDescription'>#: description #</span>",
599  attributes: {"class": "descrTD showEllipsis"}, width: "10%"},
600  {headerTemplate: "<center>View</center>", columns: [{headerTemplate: templateHeaderTemplate({fa1: "fa-money", fa1Title: "Balances", fa2: "fa-exchange",
601  fa2Title: "Transactions", index: 0}), attributes: {"class": "checkTD"}, headerAttributes: {"class": "checkTD"}, width: 70,
602  template: templateTemplate({col1: "view_balances", col2: "view_transactions", index: 0})}]},
603  {headerTemplate: "<center>Internal Transfer</center>", columns: [
604  {headerTemplate: templateHeaderTemplate({fa1: "fa-sign-in", fa1Title: "Deposit", fa2: "fa-sign-out",
605  fa2Title: "Withdraw", index: 2}), attributes: {"class": "checkTD"}, headerAttributes: {"class": "checkTD"}, width: 70,
606  template: templateTemplate({col1: "int_deposit", col2: "int_withdraw", index: 2})}]},
607  {headerTemplate: "<center>External Transfer</center>", columns: [
608  {headerTemplate: templateHeaderTemplate({fa1: "fa-sign-in", fa1Title: "Deposit", fa2: "fa-sign-out",
609  fa2Title: "Withdraw", index: 4}), attributes: {"class": "checkTD"}, headerAttributes: {"class": "checkTD"}, width: 70,
610  template: templateTemplate({col1: "ext_deposit", col2: "ext_withdraw", index: 4})}]}
611  ],
612  autoBind: false,
613  height: 150,
614  noRecords: {
615  template: "<tr><td colspan='5'><span class='hcu-secondary'><span class='vsgSecondary'>No Records Found</span></span></td></tr>"
616  }
617  };
618 
619  var subaccountGridDeposit = $("#subaccountGridDeposit").kendoGrid(subaccountGridDefinition).data("kendoGrid");
620 
621  subaccountGridDefinition.columns[0].title = "Loan Number";
622  subaccountGridDefinition.columns[4].columns[0].headerTemplate = templateHeaderTemplate({fa1: "fa-sign-in", fa1Title: "Payment", fa2: "fa-sign-out",
623  fa2Title: "Add - on", index: 2});
624  subaccountGridDefinition.columns[5].columns[0].headerTemplate = templateHeaderTemplate({fa1: "fa-sign-in", fa1Title: "Payment", fa2: "fa-sign-out",
625  fa2Title: "Add - on", index: 4});
626 
627  var subaccountGridLoan = $("#subaccountGridLoan").kendoGrid(subaccountGridDefinition).data("kendoGrid");
628  $("#subaccountGridDeposit").addClass("subaccountGrid");
629  $("#subaccountGridLoan").addClass("subaccountGrid");
630  <?php // Add it afterwards. If you add the class directly to the HTML and then do kendoGrid, kendo will copy all attributes but the ID.
631  // Referencing the class later will act weird. ?>
632 
633  $("body").on("keypress", function(e) {
634  if ([10,13].indexOf(e.which) != -1) {
635  if ($(".accessDialog:visible").length != 0) {
636  var dialog = $(".accessDialog:visible").data("kendoDialog");
637  var actions = dialog.options.actions;
638  for(var i = 0; i != actions.length; i++) {
639  if (actions[i].primary) {
640  if (actions[i].action() !== false) {
641  dialog.close();
642  }
643  break;
644  }
645  }
646  }
647  }
648  });
649 
650  $(".subaccountGrid").on("click", ".checkboxTD", function(e) {
651  if ($(e.target).is("[type='checkbox']")) {
652  return;
653  }
654  $(this).find("[type='checkbox']").click();
655  return false;
656  });
657 
658  $(".subaccountGrid").on("click", ".allCheckboxTD", function(e) {
659  if ($(e.target).is("[type='checkbox']")) {
660  return;
661  }
662  $(this).find("[type='checkbox']").click();
663  return false;
664  });
665 
666  $(".subaccountGrid").on("click", ".topNotCheckbox", function() {
667  var index = Number($(this).data("index"));
668  var id = $(this).closest(".subaccountGrid").attr("id");
669  var selector = "#" + id + " tbody .replaceDiv[data-index='"+index+"'] .restriction";
670  var isNot = $(selector + ":not(:checked)");
671  var isToo = $(selector + ":checked");
672  if ($(isNot).length > 0) {
673  $(isNot).click();
674  } else {
675  $(isToo).click();
676  }
677  });
678 
679  $("#accountGrid").on("click", ".topNotCheckbox", function() {
680  var label = $(this).text().trim();
681  var code = $(this).closest(".checkSpanDiv").data("code");
682  var selector = "#accountGrid tbody .replaceDiv[data-name='" + code + label + "'] .restriction";
683  var isNot = $(selector + ":not(:checked)");
684  var isToo = $(selector + ":checked");
685 
686  if ($(isNot).length > 0) {
687  $(isNot).click();
688  } else {
689  $(isToo).click();
690  }
691  });
692 
693  $("#accountGrid").on("click", ".restriction.allow", function() {
694  var td = $(this).closest("td");
695  var name = $(td).data("name");
696  $(td).html("<div class='restriction ban hcu-all-100'><i class='fa fa-ban'></i></div>");
697  var tr = $(td).closest("tr");
698  var dataItem = accountGrid.dataItem(tr);
699  dataItem.dirty = true;
700  dataItem[name] = false;
701 
702  var isSame = dataItem["org_" + name] == false;
703 
704  Dirtify(!isSame, $(td));
705  });
706 
707  $("#accountGrid").on("click", ".restriction.ban", function() {
708  var td = $(this).closest("td");
709  var name = $(td).data("name");
710  $(td).html("<div class='restriction allow hcu-all-100'><i class='fa fa-check'></i></div>");
711  var tr = $(td).closest("tr");
712  var dataItem = accountGrid.dataItem(tr);
713  dataItem.dirty = true;
714  dataItem[name] = true;
715 
716  var isSame = dataItem["org_" + name] == true;
717 
718  Dirtify(!isSame, $(td));
719  });
720 
721  $("#accountGrid").on("click", "tbody .accessTD [type='checkbox']", function() {
722  var value = $(this).prop("checked");
723  var dataItem = accountGrid.dataItem($(this).closest("tr"));
724  dataItem.access = value;
725  dataItem.dirty = true;
726 
727  var isSame = value == dataItem.org_access;
728 
729  Dirtify(!isSame, $(this).closest("td"));
730  });
731 
732  $("#accountGrid").on("click", "tbody .accessTD, tbody .primaryTD", function(e) {
733  if ($(e.target).is("[type='checkbox']")) {
734  return;
735  }
736  $(this).find("[type='checkbox']").click();
737  });
738 
739  $(".subaccountGrid").on("click", ".descriptionLink", function() {
740  var id = $(this).closest(".subaccountGrid").attr("id");
741  var value = $(this).text().trim();
742  if (value == "Description") {
743  $(this).text("Display Name");
744  $("#" + id +" .coreDescription").hide();
745  $("#" + id +" .displayName").show();
746  } else {
747  $(this).text("Description");
748  $("#" + id +" .displayName").hide();
749  $("#" + id +" .coreDescription").show();
750  }
751  return false;
752  });
753 
754  $(".subaccountGrid").on("click", ".restriction", function() {
755  if ($(this).hasClass("vsgDisabled")) {
756  return;
757  }
758 
759  var div = $(this).closest(".replaceDiv");
760  var td = $(this).closest("td");
761  var name = $(div).data("name");
762  var grid = $(this).closest(".subaccountGrid").data("kendoGrid");
763  var isAllow = $(this).hasClass("allow");
764  $(div).html(isAllow ? "<center><div class='restriction ban hcu-all-100'><i class='fa fa-ban'></i></div></center>"
765  : "<center><div class='restriction allow hcu-all-100'><i class='fa fa-check'></i></div></center>");
766  var tr = $(div).closest("tr");
767  var dataItem = grid.dataItem(tr);
768  dataItem.dirty = true;
769  dataItem[name] = isAllow ? false : true;
770 
771  var other = $(td).find(".replaceDiv:not([data-name='"+name+"']) .restriction");
772  var otherValue = $(other).hasClass("allow");
773  var otherName = $(other).closest(".replaceDiv").data("name");
774 
775  if (name == "view_balances") {
776  var transRestrict = $(td).find("[data-name='view_transactions'] .restriction");
777  var tr = $(td).closest("tr");
778  var intWithdraw = $(tr).find("[data-name='int_withdraw'] .restriction");
779  var extWithdraw = (tr).find("[data-name='ext_withdraw'] .restriction");
780  if (isAllow) {
781  $(transRestrict).removeClass("allow").addClass("ban vsgDisabled");
782  $(transRestrict).find("i").removeClass("fa-check").addClass("fa-ban");
783  dataItem.view_transactions = false;
784  otherValue = false;
785 
786  if ($(intWithdraw).hasClass("allow")) {
787  $(intWithdraw).removeClass("allow").addClass("ban");
788  $(intWithdraw).find("i").removeClass("fa-check").addClass("fa-ban");
789  var td = $(intWithdraw).closest("td");
790 
791  var subName = "int_withdraw";
792  var subOtherName = "int_deposit";
793  dataItem[subName] = false;
794  Dirtify(!(dataItem[subName] == dataItem["org_" + subName] && dataItem[subOtherName] == dataItem["org_" + subOtherName]), $(td));
795  }
796 
797  if ($(extWithdraw).hasClass("allow")) {
798  $(extWithdraw).removeClass("allow").addClass("ban");
799  $(extWithdraw).find("i").removeClass("fa-check").addClass("fa-ban");
800  var td = $(extWithdraw).closest("td");
801 
802  var subName = "ext_withdraw";
803  var subOtherName = "ext_deposit";
804  dataItem[subName] = false;
805  Dirtify(!(dataItem[subName] == dataItem["org_" + subName] && dataItem[subOtherName] == dataItem["org_" + subOtherName]), $(td));
806  }
807  } else {
808  $(transRestrict).removeClass("vsgDisabled");
809  }
810  } else if (name == "int_withdraw" || name == "ext_withdraw") {
811  if (!isAllow) {
812  var tr = $(td).closest("tr");
813  var viewBalances = $(tr).find("[data-name='view_balances'] .restriction");
814  var transRestrict = $(tr).find("[data-name='view_transactions'] .restriction");
815 
816  if (!$(viewBalances).hasClass("allow")) {
817  $(viewBalances).removeClass("ban").addClass("allow");
818  $(transRestrict).removeClass("vsgDisabled");
819  $(viewBalances).find("i").removeClass("fa-ban").addClass("fa-check");
820  var td = $(viewBalances).closest("td");
821 
822  var subName = "view_balances";
823  var subOtherName = "view_transactions";
824  dataItem[subName] = true;
825  Dirtify(!(dataItem[subName] == dataItem["org_" + subName] && dataItem[subOtherName] == dataItem["org_" + subOtherName]), $(td));
826  }
827  }
828  }
829 
830  Dirtify(!(dataItem[name] == dataItem["org_"+name] && otherValue == dataItem["org_" + otherName]), $(td));
831  });
832 
833  var data = <?php echo HCU_JsonEncode($readData); ?>;
834  if (data.error.length > 0) {
835  $.homecuValidator.displayMessage(data.error, $.homecuValidator.settings.statusError );
836  } else {
837  userSupportContents.isPrimary = data.isPrimary;
838  userSupportContents.latestKendoid = data.latestKendoid;
839  userSupportContents.dontShowAddNewAccount = data.dontShowAddNewAccount;
840 
841  if (!userSupportContents.isPrimary) {
842  $(".userAccessControlDiv .addNewAccountBtn").parent().remove();
843  }
844 
845  var accountData = data.accountData;
846  var subaccountData = data.subaccountData;
847 
848  for(var i = 0; i != accountData.length; i++) {
849  CreateAccountSnapshot(accountData[i]);
850  }
851 
852  for(var i = 0; i != subaccountData.length; i++) {
853  CreateSubaccountSnapshot(subaccountData[i]);
854  }
855  userSupportContents.accountData = new kendo.data.ObservableArray(accountData);
856  userSupportContents.subaccountData = new kendo.data.ObservableArray(subaccountData);
857  accountGrid.dataSource.data(userSupportContents.accountData);
858  subaccountGridDeposit.dataSource.read();
859  subaccountGridLoan.dataSource.read();
860 
861  $("#accountGrid .k-grid-content.k-auto-scrollable, .subaccountGrid .k-grid-content.k-auto-scrollable").css({overflowY: "initial"});
862  $(".subaccountGrid .k-grid-header").css({paddingRight: "initial"});
863  $("#accountGrid, .subaccountGrid").css({height: "initial", maxHeight: 400, overflowY: "auto", overflowX: "hidden"});
864 
865  data.dontShowAddNewAccount ? $(".addNewAccountBtn").hide() : $(".addNewAccountBtn").show();
866  }
867 
868  $(".userAccessControlDiv").on("mouseup", ".updateBtn", function() {
869  if (!$.homecuValidator.validate()) {
870  return;
871  }
872 
873  if ($(".breadcrumb .goToAccountsBtn:visible").length > 0) {
874  var accountnumber = $(".breadcrumb .active").text().trim();
875  SaveToUpperManagement(accountnumber);
876  }
877  var changedAccounts = GetChangedAccounts();
878  var changedSubaccounts = GetChangedSubaccounts();
879 
880  if (changedAccounts.accounts.length == 0 && changedSubaccounts.length == 0) {
881  PostPostPostPost();
882  } else {
883  var error = "";
884 
885  var parameters = {payload: "<?php echo $payload; ?>", subaccounts: kendo.stringify(changedSubaccounts),
886  accounts: kendo.stringify(changedAccounts.accounts)};
887 
888  if (error != "") {
889  $.homecuValidator.displayMessage(error, $.homecuValidator.settings.statusError );
890  } else {
891  showWaitWindow();
892  $.post("<?php echo $self; ?>&operation=saveAccountsAndSubaccounts", parameters, function(data) {
893  hideWaitWindow();
894  if (data.error.length > 0) {
895  $.homecuValidator.displayMessage(data.error, $.homecuValidator.settings.statusError );
896  } else {
897  PostPostPostPost();
898  }
899 
900  });
901  }
902  }
903  return false;
904  });
905 
906  $(".userAccessControlDiv").on("mouseup", ".cancelBtn", function() {
907  PotentiallyCancelChanges();
908  return false;
909  });
910 
911  $(".userAccessControlDiv").on("click", ".subaccountEdit", function() {
912 
913  var accountsHaveChanges = $("#accountGrid .k-dirty-cell").length > 0;
914  var dataItem = accountGrid.dataItem($(this).closest("tr"));
915  var accountnumber = dataItem.accountnumber.trim();
916 
917  $('#auto-add-access')
918  <?php // 08/19 Set the sub account checkbox data attribute to "save" this account number ?>
919  .data('accountnumber', accountnumber)
920  <?php // Copy the checked state of the original checkbox to the sub account checkbox so they are in sync ?>
921  .prop('checked', $('#account_' + accountnumber).prop('checked'));
922 
923  subaccountGridLoan.dataSource.filter([{field: "accountnumber", operator: "eq", value: accountnumber},
924  {field: "recordTypeFilter", operator: "eq", value: "L"}]);
925  subaccountGridDeposit.dataSource.filter([{field: "accountnumber", operator: "eq", value: accountnumber},
926  {field: "recordTypeFilter", operator: "eq", value: "D"}]);
927 
928  <?php // All checkbox should be disabled if no records ?>
929  $("#subaccountGridDeposit .allCheckbox").prop("disabled", subaccountGridDeposit.dataSource.view().length == 0);
930  $("#subaccountGridLoan .allCheckbox").prop("disabled", subaccountGridLoan.dataSource.view().length == 0);
931 
932  $(".userAccessControlDiv .breadcrumb").html('<li><a href="#" class="goToAccountsBtn">Accounts' +
933  (accountsHaveChanges ? ' <div class="tabAsterisk"><i class="fa fa-asterisk fa-6"></i></div>' : '')
934  + '</a></li><li class="active">'+accountnumber+'</li>');
935  $(".userAccessControlDiv .1").hide();
936  $(".userAccessControlDiv .2").show();
937  $(".userAccessControlDiv .hcu-icon-delete").show();
938  $(".userAccessControlDiv .hcu-icon-delete").addClass("vsgDisabled");
939  RestoreDirtyFlags(false);
940  return false;
941  });
942 
943  $(".userAccessControlDiv").on("click", ".goToAccountsBtn", function() {
944  $(".subaccountGrid .rowCheckbox:checked").click();
945  $(".subaccountGrid .allCheckbox").prop("checked", false);
946 
947  var accountnumber = $(".userAccessControlDiv .breadcrumb .active").text().trim();
948  var isDirty = $(".subaccountGrid .k-dirty-cell").length > 0;
949  isDirty ? userSupportContents.subaccountsWithChanges[accountnumber] == true : delete userSupportContents.subaccountsWithChanges[accountnumber];
950  $("#accountGrid tbody tr").each(function() {
951  var accountTD = $(this).find("td:eq(0)");
952  if ($(accountTD).text().trim() == accountnumber) {
953  var ast = $(accountTD).find(".tabAsterisk");
954  isDirty ? $(ast).show() : $(ast).hide();
955  return false; <?php // Found it; don't go through the other rows. ?>
956  }
957  });
958  SaveDirtyFlags(false); <?php // Need to save the dirty so that we can go back to it. ?>
959  SaveToUpperManagement(accountnumber);
960 
961  $(".userAccessControlDiv .breadcrumb").html('<li class="active">Accounts</li>');
962  $(".userAccessControlDiv .2").hide();
963  $(".userAccessControlDiv .1").show();
964  $(".userAccessControlDiv .hcu-icon-delete").hide();
965  return false;
966  });
967 
968  $(".userAccessControlDiv").on("click", ".addNewAccountBtn", function () {
969  OpenNewAccountDialog();
970  return false;
971  });
972 
973  $(".userAccessControlDiv").on("click", ".addNewSubaccountsBtn", function () {
974  OpenSubaccountsDirectly(userSupportContents.isPrimary);
975  return false;
976  });
977 
978  var toolTipProps = homecuTooltip.defaults;
979  toolTipProps.filter = ".showEllipsis:visible:overflown";
980  toolTipProps.content = function(e) {
981  return $(e.target).text().trim();
982  };
983 
984  $("#accountGrid").kendoTooltip(toolTipProps);
985  $(".subaccountGrid").kendoTooltip(toolTipProps);
986 
987  var toolTipProps = homecuTooltip.defaults;
988  toolTipProps.filter = ".topNotCheckbox";
989  toolTipProps.content = function(e) {
990  return $(e.target).attr("title").trim();
991  };
992 
993  $(".subaccountGrid").kendoTooltip(toolTipProps);
994 
995  <?php printCheckboxEvents("#subaccountGridDeposit"); printCheckboxEvents("#subaccountGridLoan"); ?>
996 
997  $(".subaccountGrid").on("click", ".rowCheckbox,.allCheckbox", function() {
998  var checked = $(this).prop("checked");
999  var isAll = $(this).is(".allCheckbox");
1000  var gridId = $(this).closest(".k-grid").attr("id");
1001  var delSelector = $(".userAccessControlDiv .hcu-icon-delete");
1002  if (isAll) {
1003  if (checked || $(".subaccountGrid:not(#"+gridId+") .rowCheckbox:checked").length > 0) {
1004  $(delSelector).removeClass("k-state-disabled vsgDisabled");
1005  } else {
1006  $(delSelector).addClass("k-state-disabled vsgDisabled");
1007  }
1008  } else {
1009  if (checked || $(".subaccountGrid .rowCheckbox:checked").length > 0) {
1010  $(delSelector).removeClass("k-state-disabled vsgDisabled");
1011  } else {
1012  $(delSelector).addClass("k-state-disabled vsgDisabled");
1013  }
1014  }
1015  });
1016 
1017  $(".userAccessControlDiv").on("click", ".hcu-icon-delete", function() {
1018 
1019  <?php // Do not do anything if delete button is disabled. ?>
1020  if ($(this).closest(".hcu-icon-delete").hasClass("vsgDisabled")) {
1021  return false;
1022  }
1023 
1024  var deleteConfirmDialog = $("#deleteConfirmDialog").data("kendoDialog");
1025  if (deleteConfirmDialog == null) {
1026  deleteConfirmDialog = $("<div id='deleteConfirmDialog'></div>").appendTo("body").kendoDialog({
1027  title: "Delete Sub-Accounts",
1028  content: "Are you sure you want to delete these sub-accounts?",
1029  actions: [
1030  {text: "No"},
1031  {text: "Yes", primary: true, action: function() {
1032 
1033  $("#deleteConfirmDialog").data("kendoDialog").close();
1034 
1035  $.homecuValidator.validate();
1036  SaveDirtyFlags(false);
1037 
1038  var accountnumber = $(".breadcrumb .active").text().trim();
1039  SaveToUpperManagement(accountnumber);
1040  var toBeDeleted = [];
1041  var gridData = $("#subaccountGridDeposit").data("kendoGrid").dataSource.view();
1042  var kendoIds = [];
1043  for(var i = 0; i != gridData.length; i++) {
1044  var row = gridData[i];
1045  if (row.checked) {
1046  toBeDeleted.push({accounttype: row.accounttype, certnumber: row.certnumber, recordtype: row.recordtype});
1047  kendoIds.push(row.kendoid);
1048  }
1049  }
1050  gridData = $("#subaccountGridLoan").data("kendoGrid").dataSource.view();
1051  for(var i = 0; i != gridData.length; i++) {
1052  var row = gridData[i];
1053  if (row.checked) {
1054  toBeDeleted.push({accounttype: row.accounttype, certnumber: row.certnumber, recordtype: row.recordtype});
1055  kendoIds.push(row.kendoid);
1056  }
1057  }
1058  var parameters = {subaccounts: kendo.stringify(toBeDeleted), accountnumber: accountnumber, payload: "<?php echo $payload; ?>"};
1059  showWaitWindow();
1060  $.post("<?php echo $self; ?>&operation=deleteSubAccounts", parameters, function(data) {
1061  hideWaitWindow();
1062  doDoThatThing = false;
1063  if (data.error.length > 0) {
1064  $.homecuValidator.displayMessage(data.error, $.homecuValidator.settings.statusError );
1065  } else {
1066  var thisParticularData = $.grep(userSupportContents.subaccountData, function(n,i) { return kendoIds.indexOf(n.kendoid) == -1; });
1067  userSupportContents.subaccountData = new kendo.data.ObservableArray(thisParticularData);
1068  $("#subaccountGridDeposit").data("kendoGrid").dataSource.read();
1069  $("#subaccountGridLoan").data("kendoGrid").dataSource.read();
1070 
1071  if (data.showAddNewAccount) {
1072  $(".addNewAccountBtn").show();
1073  }
1074 
1075  if (userSupportContents.isPrimary && $("#subaccountGridDeposit").data("kendoGrid").dataSource.view().length == 0
1076  && $("#subaccountGridLoan").data("kendoGrid").dataSource.view().length == 0) {
1077  userSupportContents.accountData = new kendo.data.ObservableArray($.grep(userSupportContents.accountData,
1078  function(n,i) { return n.accountnumber != accountnumber }));
1079  doDoThatThing = true;
1080 
1081  $(".userAccessControlDiv .goToAccountsBtn").click();
1082  } else {
1083  $(".subaccountGrid .allCheckbox").prop("checked", false);
1084  $("#subaccountGridDeposit .allCheckbox").prop("disabled", subaccountGridDeposit.dataSource.view().length == 0);
1085  $("#subaccountGridLoan .allCheckbox").prop("disabled", subaccountGridLoan.dataSource.view().length == 0);
1086  $(".userAccessControlDiv .hcu-icon-delete").addClass("vsgDisabled");
1087 
1088  RestoreDirtyFlags(false);
1089  }
1090 
1091  if (doDoThatThing) {
1092  $("#accountGrid").data("kendoGrid").dataSource.data(userSupportContents.accountData);
1093  }
1094  }
1095  });
1096 
1097  return false;
1098  }}
1099  ],
1100  visible: false,
1101  open: function() {
1102  if (window.activeWindows != null) {
1103  window.activeWindows.push(this);
1104  }
1105  },
1106  close: function() {
1107  if (window.activeWindows != null) {
1108  window.activeWindows.pop();
1109  }
1110  }
1111  }).data("kendoDialog");
1112  }
1113  deleteConfirmDialog.open();
1114  return false;
1115  });
1116 
1117  $(".show-autoadd-help").kendoTooltip({
1118  content: "When checked, the user will gain access to any additional sub-accounts added on the core."
1119  });
1120 
1121  <?php /** 08-19 from the sub account screen, set the checked state of the now hidden "auto add" boxes. */ ?>
1122  $('#auto-add-access').on('click touchstart', function() {
1123  var targ = '#account_' + $(this).data('accountnumber');
1124  $(targ).click();
1125  });
1126  }
1127 
1128  <?php
1129  /**
1130  * function OpenNewAccountDialog()
1131  * This opens a new account dialog!
1132  */
1133  ?>
1134  function OpenNewAccountDialog() {
1135  var memAccountDialog = $("#memAccountDialog").data("kendoDialog");
1136  var accountSearchMtb = $("#memAccountDialog [name='accountSearch']").data("kendoMaskedTextBox");
1137  if (memAccountDialog == null) {
1138  memAccountDialog = $("<div id='memAccountDialog' class='accessDialog'></div>").appendTo("body").kendoDialog({
1139  title: "Find Account",
1140  content: $("#findAccountTemplate").html(),
1141  actions: [
1142  {text: "Cancel"},
1143  {text: "Search", primary: true, action: function() {
1144  memAccountDialog.close();
1145  $("#memAccountDialog").data("invalid", false);
1146 
1147  var accountnumber = accountSearchMtb.raw().trim();
1148  if (accountnumber == "") {
1149  OpenFailDialog("Account number is required.", "Account Search Failed");
1150  return false;
1151  }
1152 
1153  var parameters = {accountnumber: accountnumber, payload: "<?php echo $payload; ?>", isPrimary: "Y"};
1154  showWaitWindow();
1155  $.post("<?php echo $self; ?>&operation=getAccountFromCore", parameters, function(data) {
1156  hideWaitWindow();
1157  if (data.error.length > 0) {
1158  userSupportContents.newAccountInfo = [];
1159  userSupportContents.newSubaccountInfo = [];
1160  OpenFailDialog(data.error, "Account Search Failed");
1161  } else {
1162  userSupportContents.newAccountInfo = data.accountInfo;
1163  userSupportContents.newSubaccountInfo = data.subaccountInfo;
1164  OpenAccountSearchResults();
1165  }
1166  $.homecuValidator.setup({formValidate:'emptyForm', formStatusField: 'accessControlErrorDiv'});
1167  });
1168  return false;
1169  }}
1170  ],
1171  open: function() {
1172  $("#memAccountDialog").data("invalid", true);
1173  if (window.activeWindows != null) {
1174  window.activeWindows.push(this);
1175  }
1176  },
1177  close: function() {
1178  if (window.activeWindows != null) {
1179  window.activeWindows.pop();
1180  }
1181  },
1182  show: function() {
1183  $("#memAccountDialog [name='accountSearch']").focus();
1184  },
1185  visible: false,
1186  modal: true
1187  }).data("kendoDialog");
1188 
1189  <?php // If allow zeroes, then it is normal.
1190  if ($allowZeroes) { ?>
1191  <?php // IE 11 doesn't like the javascript repeat function which is clearer than just a string. ?>
1192  var mask = "<?php echo str_repeat('0', 12); ?>";
1193 
1194  accountSearchMtb = $("#memAccountDialog [name='accountSearch']").kendoMaskedTextBox({
1195  mask: mask,
1196  unmaskOnPost: true
1197  }).data("kendoMaskedTextBox");
1198  <?php // Else, there are slighly more rules.
1199  } else { ?>
1200  <?php // IE 11 doesn't like the javascript repeat function which is clearer than just a string. ?>
1201  var mask = "~<?php echo str_repeat('0', 11); ?>";
1202 
1203  accountSearchMtb = $("#memAccountDialog [name='accountSearch']").kendoMaskedTextBox({
1204  mask: mask,
1205  rules: {
1206  "~": /[1-9]/ <?php // zero isn't allowed. ?>
1207  },
1208  unmaskOnPost: true
1209  }).data("kendoMaskedTextBox");
1210 
1211  <?php // Kendo wraps the input in a span. Make sure it doesn't look weird. ?>
1212  $(accountSearchMtb.wrapper).css("width", "100%");
1213  <?php } ?>
1214 
1215  }
1216 
1217  $("#memAccountDialog [name='accountSearch']").val(null);
1218  $("#memAccountDialog [name='accountSearch']").removeClass("k-invalid");
1219  memAccountDialog.open();
1220  }
1221 
1222  <?php
1223  /**
1224  * function OpenPleaseSelectDialog()
1225  * This one would be the dialog that forces you to select one or more subaccounts.
1226  */
1227  ?>
1228  function OpenPleaseSelectDialog() {
1229  var pleaseSelectDialog = $("#pleaseSelectDialog").data("kendoDialog");
1230  if (pleaseSelectDialog == null) {
1231  pleaseSelectDialog = $("<div id='pleaseSelectDialog' class='accessDialog'></div>").appendTo("body").kendoDialog({
1232  title: "Please Select",
1233  content: "Please select one or more subaccounts to add.",
1234  actions: [
1235  {text: "Cancel"},
1236  {text: "Retry", primary: true, action: function() {
1237  pleaseSelectDialog.close();
1238  var dialog = $("#subaccountSelectDialog").data("kendoDialog");
1239  if (dialog != null) {
1240  dialog.open();
1241  }
1242  return false;
1243  }}
1244  ],
1245  open: function() {
1246  if (window.activeWindows != null) {
1247  window.activeWindows.push(this);
1248  }
1249  },
1250  close: function() {
1251  if (window.activeWindows != null) {
1252  window.activeWindows.pop();
1253  }
1254  },
1255  visible: false,
1256  modal: true,
1257  width: 350
1258  }).data("kendoDialog");
1259  }
1260 
1261  pleaseSelectDialog.open();
1262  }
1263 
1264  <?php
1265  /**
1266  * function OpenFailDialog(errors, title)
1267  * This one would open a dialog with an error message.
1268  *
1269  * @param errors -- the errors (Will be put in the body.)
1270  * @param title -- the title of this dialog.
1271  */
1272  ?>
1273  function OpenFailDialog(errors, title) {
1274  var failDialog = $("#failDialog").data("kendoDialog");
1275  if (failDialog == null) {
1276  failDialog = $("<div id='failDialog' class='accessDialog'></div>").appendTo("body").kendoDialog({
1277  actions: [
1278  <?php if ($readData["isPrimary"] && !$isBatch) { ?>
1279  {text: "Cancel"},
1280  {text: "Search Again", primary: true, action: function() {
1281  failDialog.close();
1282  OpenNewAccountDialog();
1283  return false;
1284  }}
1285  <?php } else { ?>
1286  {text: "Cancel", primary: true}
1287  <?php } ?>
1288  ],
1289  open: function() {
1290  if (window.activeWindows != null)
1291  window.activeWindows.push(this);
1292  },
1293  close: function() {
1294  if (window.activeWindows != null)
1295  window.activeWindows.pop();
1296  },
1297  visible: false,
1298  modal: true,
1299  width: 300
1300  }).data("kendoDialog");
1301  }
1302 
1303  var content = errors == null ? "" : (typeof(errors) == "string" ? errors.trim() :
1304  (errors.length <= 1 ? errors.join("").trim() : "<ul><li>" + errors.join("</li><li>") + "</li></ul>"));
1305  failDialog.title(title).content(content).open();
1306  }
1307 
1308  <?php
1309  /**
1310  * function OpenAccountSearchResults()
1311  * This one would be the one that shows that the account exists.
1312  */
1313  ?>
1314  function OpenAccountSearchResults() {
1315  var accountSearchDialog = $("#accountSearchDialog").data("kendoDialog");
1316  if (accountSearchDialog == null) {
1317  accountSearchDialog = $("<div id='accountSearchDialog' class='accessDialog'></div>").appendTo("body").kendoDialog({
1318  title: "Account Found",
1319  actions: [
1320  {text: "Cancel"},
1321  {text: "Continue", primary: true, action: function() {
1322  accountSearchDialog.close();
1323  OpenSubaccountSearchResults(true);
1324  return false;
1325  }}
1326  ],
1327  open: function() {
1328  if (window.activeWindows != null) {
1329  window.activeWindows.push(this);
1330  }
1331  },
1332  close: function() {
1333  if (window.activeWindows != null) {
1334  window.activeWindows.pop();
1335  }
1336  },
1337  visible: false,
1338  modal: true,
1339  maxWidth: 500
1340  }).data("kendoDialog");
1341 
1342  var toolTipProps = homecuTooltip.defaults;
1343  toolTipProps.filter = ".showEllipsis:visible:overflown";
1344  toolTipProps.content = function(e) {
1345  return $(e.target).text().trim();
1346  };
1347 
1348  $("#accountSearchDialog").kendoTooltip(toolTipProps);
1349  }
1350 
1351  if (userSupportContents.newSubaccountInfo.length == 0) {
1352  OpenFailDialog("No account found.", "No Records Found");
1353  } else {
1354  if (userSupportContents.newAccountInfo[0].name) {
1355  var template = kendo.template($("#accountFoundTemplate").html());
1356  accountSearchDialog.content(template(userSupportContents.newAccountInfo[0])).open();
1357  } else {
1358  var template = kendo.template($("#accountFoundTemplateNoMir").html());
1359  accountSearchDialog.content(template(userSupportContents.newAccountInfo[0])).open();
1360  }
1361 
1362  }
1363  }
1364 
1365  <?php
1366  /**
1367  * function OpenSubaccountsDirectly(isPrimary)
1368  * This function will open the subaccounts without opening the account dialog.
1369  *
1370  * @param boolean isPrimary -- this determines how the data will be retrieved.
1371  */
1372  ?>
1373  function OpenSubaccountsDirectly(isPrimary) {
1374  var parameters = {accountnumber: $(".userAccessControlDiv .breadcrumb .active").text().trim(),
1375  payload: "<?php echo $payload; ?>", isPrimary: isPrimary ? "Y" : "N"};
1376  showWaitWindow();
1377  $.post("<?php echo $self; ?>&operation=getAccountFromCore", parameters, function(data) {
1378  hideWaitWindow();
1379  if (data.error.length > 0) {
1380  userSupportContents.newAccountInfo = [];
1381  userSupportContents.newSubaccountInfo = [];
1382  OpenFailDialog(data.error, "Sub-account Search Failed");
1383  } else {
1384  userSupportContents.newSubaccountInfo = data.subaccountInfo;
1385  OpenSubaccountSearchResults(false);
1386  }
1387  });
1388  }
1389 
1390  <?php
1391  /**
1392  * function OpenSubaccountSearchResults(isFullAccountSearch)
1393  * This one will show the subaccounts available for that account.
1394  *
1395  * @param isFullAccountSearch -- if showing the account or just the subaccounts.
1396  */
1397  ?>
1398  function OpenSubaccountSearchResults(isFullAccountSearch) {
1399  var subaccountSelectDialog = $("#subaccountSelectDialog").data("kendoDialog");
1400  var subaccountSelectGrid = $("#subaccountSelectGrid").data("kendoGrid");
1401  if (subaccountSelectDialog == null) {
1402  subaccountSelectDialog = $("<div id='subaccountSelectDialog' class='fusedGridDialog accessDialog'></div>").appendTo("body").kendoDialog({
1403  content: "<div class='hcu-secondary'><div class='small vsgSecondary'><p>Click on a row to select sub-account.</p>"
1404  + "<p>Click on the header to select all sub-accounts.</p>"
1405  + "</div></div><div id='subaccountSelectGrid'></div>",
1406  actions: [
1407  {text: "Cancel"},
1408  {text: "Add Sub-Account(s)", primary: true, action: function() {
1409  subaccountSelectDialog.close();
1410  var data = $("#subaccountSelectGrid").data("kendoGrid").dataSource.data();
1411  var isFullAccountSearch = $("#subaccountSelectGrid").data("isFullAccountSearch");
1412  var neededData = [];
1413  for(var i = 0; i != data.length; i++) {
1414  var item = data[i];
1415  if (item.checked) {
1416  neededData.push({accounttype: item.accounttype, certnumber: item.certnumber, description: item.description, recordtype: item.recordtype,
1417  canIntDeposit: item.canIntDeposit, canExtDeposit: item.canExtDeposit,
1418  canIntWithdraw: item.canIntWithdraw, canExtWithdraw: item.canExtWithdraw});
1419  }
1420  }
1421  if (neededData.length == 0) {
1422  OpenPleaseSelectDialog();
1423  } else {
1424  var accountSearchMtb = $("#memAccountDialog [name='accountSearch']").data("kendoMaskedTextBox");
1425  var parameters = {accountnumber: isFullAccountSearch ? accountSearchMtb.raw().trim() :
1426  $(".userAccessControlDiv .breadcrumb .active").text().trim(),
1427  subaccounts: kendo.stringify(neededData), payload: "<?php echo $payload; ?>", latestKendoid: userSupportContents.latestKendoid};
1428  showWaitWindow();
1429  $.post("<?php echo $self; ?>&operation=createSubaccounts", parameters, function(data) {
1430  hideWaitWindow();
1431  if (data.error.length > 0) {
1432  OpenFailDialog(data.error, "Sub-Account Search Failed.");
1433  } else { <?php // Probably need a successful message, add new records to both grids and restore dirty flags to the active grid. ?>
1434  userSupportContents.latestKendoid = data.latestKendoid;
1435  var successM = isFullAccountSearch ? "Accounts and sub-accounts were successfully added." : "Sub-accounts were successfully added.";
1436  $.homecuValidator.displayMessage(successM, $.homecuValidator.settings.statusInfo );
1437  SaveDirtyFlags(isFullAccountSearch);
1438 
1439  if (data.dontShowAddNewAccount) {
1440  $(".addNewAccountBtn").hide();
1441  }
1442 
1443  if (data.newAccounts.length > 0) {
1444  for(var i = 0; i != data.newAccounts.length; i++) {
1445  CreateAccountSnapshot(data.newAccounts[i]);
1446  userSupportContents.accountData.push(data.newAccounts[i]);
1447  }
1448  userSupportContents.accountData = new kendo.data.ObservableArray(userSupportContents.accountData);
1449  $("#accountGrid").data("kendoGrid").dataSource.data(userSupportContents.accountData);
1450  }
1451 
1452  var depositReactivated = false;
1453  var loanReactivated = false;
1454  for(var i = 0; i != data.newSubaccounts.length; i++) {
1455  var row = data.newSubaccounts[i];
1456  CreateSubaccountSnapshot(row);
1457  userSupportContents.subaccountData.push(row);
1458 
1459  if (row.recordTypeFilter == "D" && !depositReactivated) {
1460  $("#subaccountGridDeposit .allCheckbox").prop("disabled", false);
1461  depositReactivated = true;
1462  }
1463 
1464  if (row.recordTypeFilter == "L" && !loanReactivated) {
1465  $("#subaccountGridLoan .allCheckbox").prop("disabled", false);
1466  loanReactivated = true;
1467  }
1468  }
1469 
1470  $("#subaccountGridDeposit").data("kendoGrid").dataSource.read();
1471  $("#subaccountGridLoan").data("kendoGrid").dataSource.read();
1472 
1473  RestoreDirtyFlags(isFullAccountSearch);
1474  }
1475  });
1476  }
1477  return false;
1478  }}
1479  ],
1480  open: function() {
1481  if (window.activeWindows != null) {
1482  window.activeWindows.push(this);
1483  }
1484  var maxHeight1 = 800;
1485  var maxHeight2 = $(window).height() - 150;
1486  var maxHeight = maxHeight2 >= maxHeight1 ? maxHeight1 : maxHeight2;
1487  $("#subaccountSelectDialog").css({maxHeight: maxHeight, overflowY: "auto", overflowX: "hidden"});
1488  },
1489  close: function() {
1490  if (window.activeWindows != null) {
1491  window.activeWindows.pop();
1492  }
1493  },
1494  visible: false,
1495  modal: true,
1496  width: 700
1497  }).data("kendoDialog");
1498 
1499  subaccountSelectGrid = $("#subaccountSelectGrid").kendoGrid({
1500  dataSource: {
1501  transport: {
1502  read: function(options) {
1503  options.success(userSupportContents.newSubaccountInfo);
1504  subaccountSelectDialog.toFront();
1505  }
1506  },
1507  schema: {
1508  model: {
1509  id: "kendoId",
1510  fields: {
1511  kendoId: {type: "number"},
1512  accounttype: {type: "string"},
1513  certnumber: {type: "string"},
1514  description: {type: "string"},
1515  checked: {type: "boolean"},
1516  recordtype: {type: "string"},
1517  isDeposit: {type: "boolean"},
1518  canIntDeposit: {type: "boolean"},
1519  canExtDeposit: {type: "boolean"},
1520  canIntWithdraw: {type: "boolean"},
1521  canExtWithdraw: {type: "boolean"},
1522  perm_account_sort: {type: "string"},
1523  perm_type_sort: {type: "number"}
1524  }
1525  }
1526  },
1527  sort: [{field: "isDeposit", "dir": "desc"}, {field: "perm_account_sort", dir: "asc"},
1528  {field: "perm_type_sort", dir: "asc"}, {field: "accounttype", dir: "asc"}]
1529  },
1530  columns: [
1531  {headerTemplate: "<input type='checkbox' class='allCheckbox'>", template: "<input type='checkbox' class='rowCheckbox'>",
1532  width: 45, attributes: {"class": "checkboxTD"},
1533  headerAttributes: {"class": "checkboxTD"}},
1534  {title: "Sub-Account", field: "accounttype", attributes: {"class": "showEllipsis"}, width: 150},
1535  {title: "Type", field: "isDeposit", template: "# if (isDeposit) { #Deposit# } else { #Loan# } #", width: 80},
1536  {title: "Display Name", field: "description", attributes: {"class": "showEllipsis"}, template: "<span class='vsgDisabled'> #:description# </span>"}
1537  ],
1538  autoBind: false
1539  }).data("kendoGrid");
1540 
1541  <?php printCheckboxEvents("#subaccountSelectGrid"); ?>
1542 
1543  $("#subaccountSelectGrid tbody, #subaccountSelectGrid thead").addClass("showClickable");
1544  $("#subaccountSelectGrid").on("click", "tbody tr, thead tr", function(e) {
1545  if ($(e.target).is("[type='checkbox']")) {
1546  return;
1547  }
1548  $(this).find("[type='checkbox']").click();
1549  });
1550 
1551  var toolTipProps = homecuTooltip.defaults;
1552  toolTipProps.filter = ".showEllipsis:visible:overflown";
1553  toolTipProps.content = function(e) {
1554  return $(e.target).text().trim();
1555  };
1556 
1557  $("#subaccountSelectGrid").kendoTooltip(toolTipProps);
1558  }
1559 
1560  if (userSupportContents.newSubaccountInfo.length == 0) {
1561  OpenFailDialog("No unused sub-accounts found.", "No Records Found");
1562  } else {
1563  $("#subaccountSelectGrid .allCheckbox").prop("checked", false);
1564  subaccountSelectGrid.dataSource.read();
1565  var title = "Sub-Accounts Found For #" + userSupportContents.newSubaccountInfo[0].accountnumber;
1566  subaccountSelectDialog.title(title).open();
1567  $("#subaccountSelectGrid").data("isFullAccountSearch", isFullAccountSearch);
1568  }
1569  }
1570 
1571  <?php
1572  /**
1573  * SaveToUpperManagement(accountnumber)
1574  * Need to save it somewhere because it goes away.
1575  *
1576  * @param accountnumber -- the account number
1577  */ ?>
1578  function SaveToUpperManagement(accountnumber) {
1579  userSupportContents.subaccountData = $.grep(userSupportContents.subaccountData, function(n,i) { return n.accountnumber != accountnumber});
1580  var data = $("#subaccountGridDeposit").data("kendoGrid").dataSource.data();
1581  for (var i = 0, length = data.length; i != length; i++) {
1582  userSupportContents.subaccountData.push(data[i]);
1583  }
1584  var data = $("#subaccountGridLoan").data("kendoGrid").dataSource.data();
1585  for (var i = 0, length = data.length; i != length; i++) {
1586  userSupportContents.subaccountData.push(data[i]);
1587  }
1588  }
1589 
1590  Init();
1591  </script>
1592  <script type="text/x-kendo-template" id="accountFoundTemplate">
1593  <?php printHubLabelBlock(array("Account \\#" => "#: accountnumber #", "Name" => "#: name #",
1594  "DOB" => "# if (birthday == '') { # &nbsp; # } else { # #= kendo.toString(new Date(birthday), 'd') # # } #", "Phone" => "#: primaryPhone #")); ?>
1595  </script>
1596  <script type="text/x-kendo-template" id="accountFoundTemplateNoMir">
1597  No user information has been found for <b>Account \\# #: accountnumber #</b>.
1598  Please verify this is the correct account when choosing the sub-accounts.
1599  </script>
1600  <script type="text/x-kendo-template" id="findAccountTemplate">
1601  <form id='accountSearchForm' action='javascript:void(0);'>
1602  <div class='container hcu-all-100'>
1603  <div class='row'>
1604  <div id='accountDialogValidateDiv' class='col-xs-12 k-block k-error-colored formValidateDiv' style='display:none;'></div>
1605  <?php if (!$allowZeroes) { ?>
1606  <div class="row vsgSecondary">
1607  <div class="col-xs-12 hcu-secondary">
1608  Enter account number without leading zeroes.
1609  </div>
1610  </div>
1611  <?php } ?>
1612  <div class='row'>
1613  <div class='col-xs-12'>
1614  <input name='accountSearch' type='text' class='k-input k-textbox'>
1615  </div>
1616  </div>
1617  </div>
1618  </form>
1619  </script>
1620  <style>
1621  #auto-add-access {
1622  margin-top: -4px;
1623  <?php // Correct misalignment ?>
1624  }
1625  .marginLeft2em {
1626  margin-left: 2em;
1627  <?php // Inline styles are frowned upon ?>
1628  }
1629  </style>
1630 
1631  <form id="emptyForm"></form>
1632  <div class="container userAccessControlDiv vsgPrimary hcu-template hcu-all-100">
1633  <div class="row notificationRow hcuSpacer"></div>
1634  <div class="row">
1635  <div id="accessControlErrorDiv" class="k-block k-error-colored formValidateDiv" style="display:none"></div>
1636  </div>
1637  <div class="row">
1638  <ul class="breadcrumb">
1639  <li class="active">Accounts</li>
1640  </ul>
1641  </div>
1642  <div class="1">
1643  <div class="row">
1644  <a href="#" class="addNewAccountBtn">Add New Account</a>
1645  </div>
1646  <div class="row">
1647  <div id="accountGrid" class="checkExpandGrid overrideGridHeight hcu-all-100"></div>
1648  </div>
1649  </div>
1650  <div class="2" style="display:none;">
1651  <div class="row hcuSpacer">
1652  <a href="#" class="addNewSubaccountsBtn">Add New Sub-Accounts</a>
1653  <span class="hcu-secondary marginLeft2em">
1654  <span class="vsgSecondary">
1655  <?php // Always have to do two levels because I was in charge with naming the class
1656  // and they apparently didn't like that name.
1657  // VSG: visual style guide which initially had the opacity level. ?>
1658  <label for="auto-add-access">Auto-Add</label>
1659  <span class="show-autoadd-help" data-role="tooltip" data-position="top">
1660  <span class="fa fa-info-circle fa-1"></span>
1661  </span>
1662  <input type="checkbox" name="access" id="auto-add-access">
1663  </span>
1664  </span>
1665  </div>
1666  <div class="row hcuSpacer">
1667  <span class="h4">Deposits</span>
1668  </div>
1669  <div class="row hcuSpacer">
1670  <div id="subaccountGridDeposit" class="subaccountGrid checkExpandGrid overrideGridHeight hcu-all-100"></div>
1671  </div>
1672  <div class="row hcuSpacer">
1673  <span class="h4">Loans</span>
1674  </div>
1675  <div class="row">
1676  <div id="subaccountGridLoan" class="subaccountGrid checkExpandGrid overrideGridHeight hcu-all-100"></div>
1677  </div>
1678  </div>
1679  <div class="hcu-edit-buttons k-state-default row">
1680  <span class="hcu-icon-delete" style="display:none;">
1681  <a class="deleteBtn" href="#"><i class="fa fa-trash-o fa-lg"></i> (selected)</a>
1682  </span>
1683  <a class="cancelBtn" href="#">Cancel</a>
1684  &nbsp;&nbsp;&nbsp;
1685  <a class="updateBtn k-button k-primary" href="#"><i class="fa fa-check"></i>Update</a>
1686  </div>
1687  </div>
1688 <?php }
Definition: User.php:7