Odyssey
aGroupUsers.prg
1 <?php
2 /**
3  * @package GroupHub
4  * @author MGHandy
5  *
6  * @uses use this script to interact with the Group Settings feature of the Group Hub.
7  * This script allows for printing of the needed html/javascript content, and
8  * manipulation of the group information data such as group profile, and group name.
9  *
10  * @param operation string : determines what action to take with the script.
11  * operation = "" will print the needed html/javascript content.
12  * @param payload string : string containing the encrypted group data
13  * needed by each of the different actions.
14  * @param gSettings string : json encoded string of data to be updated. Updates to group name and * profile happend all at one time.
15  *
16  * @return json encoded data
17  */
18 
19 require_once("$admLibrary/aGroupSupport.i");
20 
21 try {
22  $admVars = array();
23  $admOk = array(
24  "operation" => array("filter" => FILTER_SANITIZE_STRING),
25  "payload" => array("filter" => FILTER_SANITIZE_STRING),
26  "gRefresh" => array("filter" => FILTER_SANITIZE_STRING),
27  "gPrimary" => array("filter" => FILTER_SANITIZE_STRING),
28  );
29  HCU_ImportVars($admVars, "GROUP_USERS", $admOk);
30 
31  $uOperation = isset($admVars["GROUP_USERS"]["operation"]) ? $admVars["GROUP_USERS"]["operation"] : null;
32  $uPayload = isset($admVars["GROUP_USERS"]["payload"]) ? $admVars["GROUP_USERS"]["payload"] : null;
33  $uRefresh = isset($admVars["GROUP_USERS"]["gRefresh"]) ? $admVars["GROUP_USERS"]["gRefresh"] : null;
34  $uPrimary = isset($admVars["GROUP_USERS"]["gPrimary"]) ? $admVars["GROUP_USERS"]["gPrimary"] : null;
35 
36  // decrypt payload only if there is one
37  // payload won't exist if operation is empty
38  // operation empty means just load card content
39  $uGroup = $uPayload ?
40  GroupDecrypt($SYSENV, $Cu, $uPayload) :
41  null;
42 
43  // load context depending on payload existence.
44  $uContext = $uPayload ?
45  GroupContext($SYSENV, $Cu, $uGroup['group']) :
46  GroupContext($SYSENV, $Cu);
47 
48  $aryResult = array();
49  $aryReply = array();
50 
51  switch ($uOperation) {
52  case "":
53  PrintGroupUsers();
54  break;
55  case "groupReadUsers":
56  header('Content-type: application/json');
57  $gUsers = GroupReadUsers($SYSENV, $dbh, $uContext);
58 
59  $aryResult['data']['users'] = $gUsers['users'];
60  GroupReply($aryResult, $aryReply, $uOperation);
61  break;
62  case "groupCleanUser":
63  header('Content-type: application/json');
64  $gValidate = GroupValidateUsers($SYSENV, $uRefresh);
65  $gUser = GroupCleanUser($SYSENV, $dbh, $uContext, $gValidate['user']);
66  $gUsers = GroupReadUsers($SYSENV, $dbh, $uContext);
67  $aryResult['data']['users'] = $gUsers['users'];
68  $aryResult['info'][] = $gUser['message'];
69  GroupReply($aryResult, $aryReply, $uOperation);
70  break;
71  case "groupUpdatePrimary":
72  header('Content-type: application/json');
73  $gValidate = GroupValidateUsers($SYSENV, $uPrimary);
74 
75  if ($gValidate['primary']['mpl']) {
76  // clean up multiple primary users
77  $gPrimary = GroupCleanPrimary($SYSENV, $dbh, $uContext, $gValidate['primary']);
78  } else {
79  // set primary user
80  $gPrimary = GroupUpdatePrimary($SYSENV, $dbh, $uContext, $gValidate['primary']);
81  }
82 
83  // read users again to get correct sub account access readings
84  // for new primary user.
85  $gUsers = GroupReadUsers($SYSENV, $dbh, $uContext);
86  $aryResult['data']['users'] = $gUsers['users'];
87  $aryResult['info'][] = $gPrimary['message'];
88 
89  // reselect group for correct primary user
90  $uContext['g_name'] = $uGroup['group']['g_name'];
91  $gGroup = GroupSelect($SYSENV, $dbh, $uContext);
92  $gEncrypt = GroupEncrypt($SYSENV, $Cu, $uGroup);
93  $aryResult['data']['group'] = $gGroup;
94  $aryResult['data']['encrypt'] = $gEncrypt;
95 
96  GroupReply($aryResult, $aryReply, $uOperation);
97  break;
98  default:
99  throw new Exception("Unknown server request: " . $uOperation);
100  break;
101  }
102 
103 } catch (Exception $e) {
104  $aryReply['errors'][] = $e->getMessage();
105  $aryResult['data'] = array();
106  $aryResult['info'] = array();
107 
108  GroupReply($aryResult, $aryReply, $uOperation);
109  exit;
110 }
111 
112 /**
113  * GroupValidateInfo:
114  * @uses validate the incoming data to be updated. this function will take the incoming
115  * old/new primary users and set them to valid values
116  * to be inserted or updated int the database.
117  *
118  * @param $pEnv array : environment variable for debugging
119  * @param $pInfo string : json encoded data to be updated
120  *
121  * @return $vInfo array : array of savable data seperated into individual update values.
122  */
123 function GroupValidateUsers($pEnv, $pUsers) {
124  $gUsers = html_entity_decode($pUsers, ENT_QUOTES);
125  $gUsers = json_decode($gUsers, true);
126  $vUsers = array();
127 
128  if (isset($gUsers['uId'])) {
129  $vUsers['user'] = intval($gUsers['uId']);
130  }
131 
132  if (isset($gUsers['uPrimary'])) {
133  $vUsers['primary']['new'] = "";
134  $vUsers['primary']['old'] = "";
135 
136  foreach ($gUsers['uPrimary']['uNew'] as $key => $value) {
137  $vUsers['primary']['new'] .= $value;
138  $vUsers['primary']['new'] .= ",";
139  }
140 
141  foreach ($gUsers['uPrimary']['uOld'] as $key => $value) {
142  $vUsers['primary']['old'] .= $value;
143  $vUsers['primary']['old'] .= ",";
144  }
145 
146  $vUsers['primary']['new'] = rtrim($vUsers['primary']['new'], ",");
147  $vUsers['primary']['old'] = rtrim($vUsers['primary']['old'], ",");
148  $vUsers['primary']['mpl'] = $gUsers['uPrimary']['uMpl'] ? true : false;
149  }
150 
151  return $vUsers;
152 }
153 
154 /**
155  * GroupCleanPrimary:
156  * @uses this function is used to clean up the primary users if there are multiple for this group.
157  * the only action taken is to set only a single primary user selected by the admin,
158  * and set the rest to false.
159  *
160  * @param $pEnv array : environment variable for debugging
161  * @param $pDbh object : database access
162  * @param $pContext array : array containing decrypted group data and table identifiers.
163  * @param $pPrimary array : array of validated data containing new and old primary users.
164  *
165  * @return $sqlReturn array : new primary user data
166  */
167 function GroupCleanPrimary($pEnv, $pDbh, $pContext, $pPrimary) {
168  if ($pPrimary == null || $pPrimary == "") { return array(); }
169 
170  $gId = $pContext['g_id'];
171  $pId = $pContext['p_id'];
172  $cuTable = $pContext['cu_table'];
173  $cuCode = $pContext['cu_code'];
174 
175  $uOldId = $pPrimary['old'];
176  $uNewId = $pPrimary['new'];
177 
178  // cleaning up only requires that we set a single primary user
179  // and releive all others of their status of primary.
180  $sqlReturn = array();
181  $sqlUpdate = "
182  UPDATE {$cuTable}user
183  SET is_group_primary = 'TRUE'
184  WHERE user_id IN ($uNewId);
185 
186  UPDATE {$cuTable}user
187  SET is_group_primary = 'FALSE'
188  WHERE user_id IN ($uOldId);";
189  $sqlUpdateRs = db_query($sqlUpdate, $pDbh);
190  if (!$sqlUpdateRs) {
191  throw new Exception("Failed to correct the primary user status.");
192  }
193 
194  $sqlReturn['message'] = "Primary owner status has been corrected successfully.";
195  return $sqlReturn;
196 }
197 
198 /**
199  * GroupUpdatePrimary:
200  * @uses this function allows for updating a group's primary user. The update will
201  * take all sub-accounts the current primary user has and copy them to the new primary.
202  * All group account rights from the current primary will also be copied and given to the
203  * new primary after the new primary has been relieved of their current group rights.
204  *
205  * The primary flags for both users will then be swapped.
206  *
207  * @param $pEnv array : environment variable for debugging
208  * @param $pDbh object : database access
209  * @param $pContext array : array containing decrypted group data and table identifiers.
210  * @param $pPrimary array : array of validated data containing new and old primary users.
211  *
212  * @return $sqlReturn array : new primary user data
213  */
214 function GroupUpdatePrimary($pEnv, $pDbh, $pContext, $pPrimary) {
215  if ($pPrimary == null || $pPrimary == "") { return array(); }
216 
217  $gId = $pContext['g_id'];
218  $pId = $pContext['p_id'];
219  $cuTable = $pContext['cu_table'];
220  $cuCode = $pContext['cu_code'];
221 
222  $uOldId = $pPrimary['old'];
223  $uNewId = $pPrimary['new'];
224 
225  // get all rows from the old primary user,
226  // label the rows that exist in the new as _update
227  // label the rows that do not exists in new as _insert
228  $sqlReturn = array();
229  $sqlColumnsUnique = "
230  accountnumber, accounttype, certnumber, recordtype";
231  $sqlColumns = "
232  display_name,display_order,display_qty,display_qty_type,
233  int_deposit,int_withdraw,ext_deposit,ext_withdraw,
234  view_balances,view_transactions";
235  $sqlWhere = "
236  SELECT $sqlColumnsUnique
237  FROM {$cuTable}useraccounts
238  WHERE user_id = $uNewId";
239  $sqlSelect = "
240  SELECT '_update' AS action, $sqlColumnsUnique, $sqlColumns
241  FROM {$cuTable}useraccounts
242  WHERE user_id = $uOldId
243  AND ($sqlColumnsUnique) IN ($sqlWhere)
244 
245  UNION
246 
247  SELECT '_insert' AS action, $sqlColumnsUnique, $sqlColumns
248  FROM {$cuTable}useraccounts
249  WHERE user_id = $uOldId
250  AND ($sqlColumnsUnique) NOT IN ($sqlWhere)";
251  $sqlSelectRs = db_query($sqlSelect, $pDbh);
252  if (!$sqlSelectRs) {
253  $pEnv['logger']->error(db_last_error());
254  throw new Exception("Failed to read user accounts.");
255  }
256 
257  // build query to update/insert rows to not primary user
258  // from old primary user.
259  $sqlAcctInsert = "";
260  $sqlAcctUpdate = "";
261  if (db_fetch_all($sqlSelectRs)) {
262  foreach (db_fetch_all($sqlSelectRs) as $key => $value) {
263 
264  $sqlAction = $value['action'];
265 
266  $sqlValuesUnique = "";
267  $sqlValuesUnique .= "'". prep_save($value['accountnumber'], 12) ."',";
268  $sqlValuesUnique .= "'". prep_save($value['accounttype'], 25) ."',";
269  $sqlValuesUnique .= intval($value['certnumber']) .",";
270  $sqlValuesUnique .= "'". prep_save($value['recordtype'], 1) ."'";
271 
272  $sqlValues = "";
273  $sqlValues .= "'". prep_save($value['display_name'], 255) ."',";
274  $sqlValues .= intval($value['display_order']) .",";
275  $sqlValues .= intval($value['display_qty']) .",";
276  $sqlValues .= "'". prep_save($value['display_qty_type'], 1) ."',";
277  $sqlValues .= $value['int_deposit'] == "t" ? "TRUE," : "FALSE,";
278  $sqlValues .= $value['int_withdraw'] == "t" ? "TRUE," : "FALSE,";
279  $sqlValues .= $value['ext_deposit'] == "t" ? "TRUE," : "FALSE,";
280  $sqlValues .= $value['ext_withdraw'] == "t" ? "TRUE," : "FALSE,";
281  $sqlValues .= $value['view_balances'] == "t" ? "TRUE," : "FALSE,";
282  $sqlValues .= $value['view_transactions'] == "t" ? "TRUE" : "FALSE";
283 
284  if ($sqlAction == "_insert") {
285  $sqlAcctInsert .= "
286  INSERT INTO {$cuTable}useraccounts (user_id, $sqlColumnsUnique, $sqlColumns)
287  VALUES ($uNewId, $sqlValuesUnique, $sqlValues);";
288  } else if ($sqlAction == "_update") {
289  $sqlAcctUpdate .= "
290  UPDATE {$cuTable}useraccounts
291  SET ($sqlColumns) = ($sqlValues)
292  WHERE (user_id, $sqlColumnsUnique) = ($uNewId, $sqlValuesUnique);";
293  }
294  }
295  }
296 
297  // delete all member account rights for this user.
298  $sqlMbrRightsDelete = "
299  DELETE FROM {$cuTable}memberacctrights
300  WHERE user_id = $uNewId";
301 
302  // set member account rights from old primary to new primary.
303  $sqlMbrRightsUpdate = "
304  UPDATE {$cuTable}memberacctrights
305  SET (user_id) = ($uNewId)
306  WHERE user_id = $uOldId";
307 
308  // set primary flag for new user to true.
309  $sqlNewPrimaryUpdate = "
310  UPDATE {$cuTable}user
311  SET (is_group_primary) = ('TRUE')
312  WHERE user_id = $uNewId";
313 
314  // set primary flag for old user to false.
315  $sqlOldPrimaryUpdate = "
316  UPDATE {$cuTable}user
317  SET (is_group_primary) = ('FALSE')
318  WHERE user_id = $uOldId";
319 
320  // begin transaction
321  // on failure will reset all altered data.
322  try {
323  $sqlTrans = "BEGIN TRANSACTION";
324  $sqlTransRs = db_query($sqlTrans, $pDbh);
325 
326 
327  if (trim($sqlAcctInsert) != "") {
328  $sqlAcctInsertRs = db_query($sqlAcctInsert, $pDbh);
329  if (!$sqlAcctInsertRs) {
330  $pEnv['logger']->error(db_last_error());
331  throw new Exception("Failed to add sub-accounts for the selected user.");
332  }
333  }
334 
335  if (trim($sqlAcctUpdate) != "") {
336  $sqlAcctUpdateRs = db_query($sqlAcctUpdate, $pDbh);
337  if (!$sqlAcctUpdateRs) {
338  $pEnv['logger']->error(db_last_error());
339  throw new Exception("Failed to update sub-accounts for the selected user.");
340  }
341  }
342 
343  $sqlMbrRightsDelete = db_query($sqlMbrRightsDelete, $pDbh);
344  if (!$sqlMbrRightsDelete) {
345  $pEnv['logger']->error(db_last_error());
346  throw new Exception("Failed to delete member account rights for the selected user.");
347  }
348 
349  $sqlMbrRightsUpdate = db_query($sqlMbrRightsUpdate, $pDbh);
350  if (!$sqlMbrRightsUpdate) {
351  $pEnv['logger']->error(db_last_error());
352  throw new Exception("Failed to update member account rights for the selected user.");
353  }
354 
355  $sqlOldPrimaryUpdate = db_query($sqlOldPrimaryUpdate, $pDbh);
356  if (!$sqlOldPrimaryUpdate) {
357  $pEnv['logger']->error(db_last_error());
358  throw new Exception("Failed to update current primary user status to non-primary user.");
359  }
360 
361  $sqlNewPrimaryUpdate = db_query($sqlNewPrimaryUpdate, $pDbh);
362  if (!$sqlNewPrimaryUpdate) {
363  $pEnv['logger']->error(db_last_error());
364  throw new Exception("Failed to update selected user status to primary user.");
365  }
366 
367 
368 
369  $sqlTrans = "COMMIT TRANSACTION";
370  $sqlTransRs = db_query($sqlTrans, $pDbh);
371  } catch (Exception $e) {
372  $pEnv['logger']->error(db_last_error());
373  // transaction failed, rollback
374  $sqlTrans = "ROLLBACK TRANSACTION";
375  $sqlTransRs = db_query($sqlTrans, $pDbh);
376  throw new Exception($e->getMessage());
377  }
378 
379  $sqlReturn['message'] = "Primary user has been updated successfully.";
380  return $sqlReturn;
381 }
382 
383 /**
384  * GroupCleanUser:
385  * @uses this function is used to clean up a user with more account access
386  * than the current primary user. if the selected user has access to more sub-accounts
387  * than the current primary user, the accounts will be removed from this user leaving only
388  * those which the primary has access to.
389  *
390  * @param $pEnv array : environment variable for debugging
391  * @param $pDbh object : database access
392  * @param $pContext array : array containing decrypted group data and table identifiers.
393  * @param $pUser array : the user to be cleaned.
394  *
395  * @return $sqlReturn array : new primary user data
396  */
397 function GroupCleanUser($pEnv, $pDbh, $pContext, $pUser) {
398  if ($pUser == null || $pUser == "") { return array(); }
399 
400  $gId = $pContext['g_id'];
401  $pId = $pContext['p_id'];
402  $cuTable = $pContext['cu_table'];
403  $cuCode = $pContext['cu_code'];
404  $cuUser = $pUser;
405 
406  $sqlReturn = array();
407  $sqlSub = "
408  SELECT sa.accountnumber, sa.accounttype, sa.certnumber
409  FROM ${cuCode}useraccounts sa
410  INNER JOIN ${cuCode}user su
411  ON su.user_id = sa.user_id
412  AND su.group_id = $gId
413  AND su.is_group_primary = 'TRUE'";
414  $sqlDelete = "
415  DELETE FROM ${cuCode}useraccounts a
416  WHERE user_id = $cuUser
417  AND (a.accountnumber, a.accounttype, a.certnumber) NOT IN ($sqlSub)";
418  $sqlDeleteRs = db_query($sqlDelete, $pDbh);
419  if (!$sqlDeleteRs) {
420  throw new Exception("Failed to reset this user's account access.");
421  }
422 
423  $sqlReturn['message'] = "User account access has been successfully cropped.";
424  return $sqlReturn;
425 }
426 
427 /**
428  * GroupReadUsers:
429  * @uses this function allows for reading list of users that belong to this group.
430  * this will also gather a list fo each users accounts to determine if one has more
431  * access than the current primary user.
432  *
433  * @param $pEnv array : environment variable for debugging
434  * @param $pDbh object : database access
435  * @param $pContext array : array containing decrypted group data and table identifiers.
436  *
437  * @return $sqlReturn array : list of users in this group
438  */
439 function GroupReadUsers($pEnv, $pDbh, $pContext) {
440  $gId = $pContext['g_id'];
441  $pId = $pContext['p_id'];
442  $cuTable = $pContext['cu_table'];
443  $cuCode = $pContext['cu_code'];
444 
445  $sqlReturn = array();
446  $sqlData = array();
447  $sqlColumns = "
448  u.user_id AS u_id,
449  u.user_name AS u_name,
450  u.is_group_primary AS u_primary";
451  $sqlSelect = "SELECT $sqlColumns
452  FROM {$cuTable}user u
453  WHERE u.group_id = $gId
454  ORDER BY u.user_name";
455  $sqlSelectRs = db_query($sqlSelect, $pDbh);
456  if (!$sqlSelectRs) {
457  $pEnv['logger']->error(db_last_error());
458  throw new Exception("Failed to read group users.");
459  }
460  $sqlData['users'] = db_fetch_all($sqlSelectRs);
461  $sqlData['primary'] = array();
462  if (count($sqlData['users']) > 0) {
463  foreach ($sqlData['users'] as $keyU => $valueU) {
464  if ($valueU['u_primary'] == "t") {
465  $sqlData['primary'][] = $valueU['u_id'];
466  }
467  $sqlData['users'][$keyU]['a_count'] = 0;
468  $uPayload = readUserSearch($pDbh, $cuCode, array(
469  "a" => array ("username"=>$valueU['u_name'])
470  ));
471  $sqlData['users'][$keyU]['u_payload'] = urlencode($uPayload['encryption']);
472  }
473 
474  $aCount = 0;
475  $cCount = 0;
476  foreach ($sqlData['users'] as $keyU => $valueU) {
477  if ($valueU['u_primary'] == "t") {
478 
479  } else {
480  foreach ($sqlData['primary'] as $keyP => $valueP) {
481  $sqlColumns = "
482  accountnumber,
483  accounttype,
484  recordtype";
485  $sqlSub = "
486  SELECT $sqlColumns
487  FROM {$cuTable}useraccounts
488  WHERE user_id = '$valueP'";
489  $sqlSelect = "
490  SELECT COUNT(*)
491  FROM {$cuTable}useraccounts
492  WHERE user_id = '{$valueU['u_id']}'
493  AND ($sqlColumns) NOT IN ($sqlSub)";
494 
495  $sqlSelectRs = db_query($sqlSelect, $pDbh);
496  if (!$sqlSelectRs) {
497  $pEnv['logger']->error(db_last_error());
498  throw new Exception("Failed to read account access between primary and non-primary users.");
499  }
500  $cCount += db_fetch_assoc($sqlSelectRs, 0)['count'];
501  $aCount += $cCount;
502  $sqlData['users'][$keyU]['a_count'] = $cCount;
503  }
504  $cCount = 0;
505  }
506  }
507 
508  foreach ($sqlData['users'] as $key => $value) {
509  $sqlData['users'][$key]['o_count'] = $aCount;
510  }
511  }
512  unset($sqlData['primary']);
513  $sqlReturn['users'] = $sqlData['users'];
514  return $sqlReturn;
515 }
516 ?>
517 <?php
518 /**
519  * PrintGroupSettings:
520  * @uses this function allows for printing the html/javascript content needed to interact
521  * with the group settings feature.
522  */
523 function PrintGroupUsers() { ?>
524 <div id="guUsers">
525  <div id="status"></div>
526  <div class="col-sm-12">&nbsp;</div>
527  <div class="well well-sm col-sm-12">
528  <div data-bind="visible: showPrimaryWarning">
529  <p>
530  <span class="fa fa-exclamation-triangle" style="color: #ff9800;"></span>
531  This group has multiple primary users. Please correct this by selecting a single user below.
532  </p>
533  </div>
534  <div data-bind="visible: showAccessWarning">
535  <p>
536  <span class="fa fa-exclamation-triangle" style="color: #ff9800;"></span>
537  This group has users with access to sub-accounts which the primary owner does not have. Please correct this by clicking the crop button to the right of each row.
538  </p>
539  </div>
540  <div id="guUserGrid"
541  data-role="grid"
542  data-selectable="row"
543  data-no-records="No users were found for this group"
544  data-bind="
545  source: users,
546  events: { change: change, dataBound: grid }"
547  data-columns="[
548  { field: 'u_name', title: 'User Name',
549  template: '<a href=\'main.prg?ft=22&payload=#= u_payload #\'>#= u_name # <i class=\'fa fa-user\'></i></a>' },
550  { field: 'u_primary', title: 'Primary User',
551  template: '<input id=\'USER_#=u_id#\' type=\'checkbox\' style=\'margin-top: -2px;\'>'},
552  { title: ' ',
553  attributes: { class: 'text-right' },
554  template: '#if(a_count > 0 && !u_primary){#<button class=\'k-button fa fa-crop\' style=\'min-width: 25px;\'></button>#}#' }
555  ]">
556  </div>
557  </div>
558 
559  <div class="hcu-template">
560  <div class="hcu-edit-buttons k-state-default">
561  <span class="hcu-icon-delete"></span>
562  <a href="##" id="lnkCancel">Cancel</a>
563  &ensp;
564  <a href="##" id="btnUpdate" class="k-button k-primary">
565  <i class="fa fa-check fa-lg"></i>
566  Update
567  </a>
568  </div>
569  </div>
570 </div>
571 
572 <div id="guDiscard"></div>
573 <div id="guNotifyPrimary"></div>
574 <div id="guNotifyRefreshFail"></div>
575 <div id="guNotifyRefresh"></div>
576 <?php
577 /**
578  * @package GroupUsers:
579  * @uses This object is used to display and interact with the group settings feature.
580  *
581  * @var Init public: public call to initialize data/view/action objects
582  * @var Data public: public call to set/reset encrypted data
583  * @var Open public: public call to open the group rights module/window
584  * @var Close public: public call to close the group rights module/window
585  *
586  * @var InitDataSources private: initialize all needed data sources/objects
587  * @var InitDataViews private: initialize all data views/html elements
588  * @var InitDataActions private: initialize all user actions on html.
589  *
590  * @var EventOpenDialog private: open kendoDialog/kendoWindow objects
591  * @var EventClosedialog private: close kendoDialog/kendoWindow objects
592  * @var EventPopDialog private: remove the correct window from the window stack.
593  *
594  * @var EventOpenInfo private: send request to read/open group info
595  * @var EventCancelInfo private: close group rights window, canceling changes
596  * @var EventUpdateInfo private: send crud request for group info, profile and primary
597  * user updates.
598  * @var Event* private: the other event functions not listed above are custom
599  * calls for kendo bjects and other helper functions that are explained by the
600  * function name.
601  *
602  * @var Validate* private: these functions facilitate validation of particular
603  * pieces of the interface. Uses explained by function name.
604  *
605  * @var DataBuild* private: these functions facilitate re-constructing data for
606  * proper use in the other js functions and html displays.
607  *
608  * @var Action* private: these functions are calls from kendoDialog actions
609  * uses explained by function name.
610  *
611  * @var ClearGroupInfo private: clear information displayed in the information bar.
612  * @var ShowGroupInfo private: show any information return by the server.
613  */
614 ?>
615 <script type="text/javascript">
616 //# sourceURL=groupUsers.js
617 
618 var GroupUsers = function() {
619  var guCardContainer = null;
620  var guCardWindows = null;
621 
622  var guPayload = null;
623  var guGroup = null;
624  var guCall = null;
625  var guAction = null;
626  var guDataSource = null;
627 
628  var guUsers = null;
629  var guDiscard = null;
630  var guNotifyPrimary = null;
631  var guNotifyRefresh = null;
632  var guNotifyRefreshFail = null;
633  var guObserve = null;
634  var guTooltip = null;
635 
636  var DataBuildUsers = function(data) {
637  var list = [];
638  var build = {
639  o_primary: [],
640  e_primary: []
641  };
642  for (var i = 0; i < data.length; i++) {
643  var user = {
644  u_id: parseInt(data[i].u_id),
645  u_name: data[i].u_name ? data[i].u_name.trim() : "",
646  u_payload: data[i].u_payload ? data[i].u_payload.trim() : "",
647  u_primary: data[i].u_primary == "t" ? true : false,
648  a_count: parseInt(data[i].a_count),
649  o_count: parseInt(data[i].o_count)
650  };
651 
652  if (user.u_primary) {
653  build.o_primary.push(user.u_id);
654  build.e_primary.push(user.u_id);
655  }
656 
657  list.push(user);
658  }
659 
660  guObserve.set("source", build);
661  guObserve.set("users", list);
662  guObserve.set("showPrimaryWarning", (build.o_primary.length > 1));
663  if (list.length > 0) {
664  guObserve.set("showAccessWarning", (list[0].o_count > 0));
665  }
666  }
667 
668  var ValidateUsers = function() {
669  var source = guObserve.source;
670  var user_e = source.e_primary;
671  var user_o = source.o_primary;
672 
673  source.e_dirty = false;
674  for (var i = 0; i < user_o.length; i++) {
675  if ($.inArray(user_o[i], user_e) == -1) {
676  source.e_dirty = true;
677  break;
678  }
679  }
680 
681  return !source.e_dirty;
682  }
683 
684  var EventShowTip = function(e) {
685  var targetContent = "This user cannot be selected as a primary group owner.";
686 
687  return targetContent;
688  }
689 
690  var EventCheckboxChange = function(e) {
691  var box = $(e);
692  var boxValue = $(box).prop("checked");
693  var boxId = box.attr("id");
694  var uId = boxId.substring(5, boxId.length);
695  uId = parseInt(uId);
696 
697  if (boxValue || guObserve.source.e_primary.length > 1) {
698  guObserve.source.e_primary = [];
699  guObserve.source.e_primary.push(uId);
700 
701  $("#guUserGrid input[type=checkbox]").each(function() {
702  $(this).prop("checked", false);
703  });
704  }
705 
706  if (guObserve.source.e_primary.length > 1) {
707  $(box).prop("checked", true);
708  } else if (boxValue) {
709  $(box).prop("checked", boxValue);
710  } else {
711  $(box).prop("checked", !boxValue);
712  }
713 
714  ValidateUsers();
715  if (guObserve.source.e_dirty &&
716  guObserve.source.e_primary.length == 1) {
717  guNotifyPrimary.open();
718  }
719  }
720 
721  var EventUpdateUsers = function() {
722  var groupData = {};
723  var source = guObserve.source;
724 
725  if (!ValidateUsers()) {
726  // change to primary user
727  if (source.e_dirty) {
728  groupData.uPrimary = {
729  uMpl: source.o_primary.length > 1,
730  uNew: source.e_primary,
731  uOld: source.o_primary.filter(function(e) {
732  return source.e_primary.indexOf(e) < 0;
733  })
734  };
735  }
736 
737  var groupRequest = {
738  operation: "groupUpdatePrimary",
739  payload: guPayload,
740  gPrimary: JSON.stringify(groupData)
741  };
742 
743  guDataSource.transport.options.read.type = "POST";
744  guDataSource.read(groupRequest);
745  }
746  }
747 
748  var EventOpenWindow = function(e) {
749  var windowElement = this.element[0];
750  var windowId = windowElement.id;
751 
752  switch (windowId) {
753 
754  }
755 
756  guCardWindows.push(this);
757  }
758 
759  var EventCloseWindow = function(e) {
760  var windowElement = this.element[0];
761  var windowId = windowElement.id;
762 
763  switch (guAction) {
764  case "discardConfirm":
765  EventPopWindow(windowId);
766 
767  var sourceUsers = guObserve.source;
768 
769  // reset users
770  sourceUsers.e_primary = sourceUsers.o_primary;
771 
772  guAction = null;
773  guUsers.close();
774  break;
775  case "notifyRefresh":
776  EventPopWindow(windowId);
777 
778  var groupRequest = {
779  operation: "groupCleanUser",
780  payload: guPayload,
781  gRefresh: JSON.stringify({uId: guObserve.refreshUser.u_id})
782  };
783 
784  guDataSource.transport.options.read.type = "POST";
785  guDataSource.read(groupRequest);
786  break;
787  default:
788  if (windowId == "guUsers") {
789  if (!ValidateUsers()) {
790  e.preventDefault();
791  guDiscard.open();
792  } else {
793  EventPopWindow(windowId);
794  // reset validator for hub script
795  $.homecuValidator.setup({
796  formStatusField: "formStatus",
797  formValidate: "cardContainerDiv"
798  });
799  }
800  } else {
801  EventPopWindow(windowId);
802  }
803  break;
804  }
805 
806  guAction = null;
807  }
808 
809  var EventPopWindow = function(windowId) {
810  var popIndex = -1;
811  for (var i = 0; i < guCardWindows.length; i++) {
812  var openWindow = guCardWindows[i].element[0];
813  var openId = openWindow.id;
814 
815  if (openId == windowId) {
816  popIndex = i;
817  break;
818  }
819  }
820 
821  if (popIndex > -1) {
822  guCardWindows.splice(popIndex, 1);
823  }
824  }
825 
826  var InitDataSources = function() {
827  guDataSource = new kendo.data.DataSource({
828  transport: {
829  read: {
830  url: "main.prg",
831  dataType: "json",
832  contentType: "application/x-www-form-urlencoded",
833  type: "GET",
834  data: {
835  ft: "102105"
836  },
837  cache: false
838  }
839  },
840  requestStart: function(request) {
841  showWaitWindow();
842  },
843  requestEnd: function(response) {
844  setTimeout(hideWaitWindow, 500);
845  if (response.hasOwnProperty("response")) {
846  if (response.response.hasOwnProperty("Results")) {
847  var results = response.response.Results;
848 
849  if (results.hasOwnProperty("error")) {
850  $.homecuValidator.homecuResetMessage = true;
851  $.homecuValidator.displayMessage(results.error, $.homecuValidator.settings.statusError);
852  } else if (results.hasOwnProperty("info")) {
853  $.homecuValidator.homecuResetMessage = true;
854  $.homecuValidator.displayMessage(results.info, $.homecuValidator.settings.statusSuccess);
855  }
856  } else {
857  $.homecuValidator.displayMessage("Error Parsing Server", $.homecuValidator.settings.statusError);
858  }
859  } else {
860  $.homecuValidator.displayMessage("Error Parsing Server", $.homecuValidator.settings.statusError);
861  }
862  },
863  schema: {
864  parse: function(response) {
865 
866  var results = null;
867  var resultData = null;
868  var resultOperation = null;
869 
870  if (response.hasOwnProperty("Results")) {
871  results = response.Results;
872  resultData = results.data;
873  resultOperation = results.operation;
874  }
875 
876  if (results.hasOwnProperty("errors")) {
877  return [];
878  }
879 
880  if (resultData == undefined || resultData == null) {
881  return [];
882  }
883 
884  setTimeout(function() {
885  switch (resultOperation) {
886  case "groupReadUsers":
887  DataBuildUsers(resultData.users);
888  var template= kendo.template($("#titleTemplate").html());
889  guGroup.cardTitle= "Group Users";
890  guUsers.title(template(guGroup)).center().open();
891  break;
892  case "groupCleanUser":
893  DataBuildUsers(resultData.users);
894  break;
895  case "groupUpdatePrimary":
896  DataBuildUsers(resultData.users);
897 
898  guPayload = resultData.encrypt;
899  guGroup = resultData.group.group;
900  guCall("updateGroupInfo", resultData.group);
901  guCall("updateGroupEncrypt", resultData.encrypt);
902 
903  // reset primary user for validation
904  guObserve.source.o_primary = guObserve.source.e_primary;
905  ValidateUsers();
906  break;
907  }
908  }, 500);
909 
910  return [];
911  }
912  }
913  });
914  }
915 
916  var InitDataViews = function() {
917  guUsers = $("#guUsers").kendoWindow({
918  title: "Group Users",
919  width:"75%",
920  minWidth: "300px",
921  maxWidth: "750px",
922  modal: true,
923  visible: false,
924  resizable: false,
925  activate: EventOpenWindow,
926  close: EventCloseWindow,
927  open: function() {
928  this.wrapper.css({ top: 100 });
929  }
930  }).data("kendoWindow");
931 
932  guObserve = new kendo.observable({
933  refreshUser: null,
934  showPrimaryWarning: false,
935  showAccessWarning: false,
936  source: null,
937  users: [],
938  grid: function() {
939  $('#guUserGrid input[type=checkbox]').off();
940  $('#guUserGrid input[type=checkbox]').css("cursor", "pointer");
941  $('#guUserGrid input[type=checkbox]').change(function(e) {
942  EventCheckboxChange(e.target);
943  });
944 
945  $("#guUserGrid tr").each(function(i) {
946  if (i > 0) {
947  var row = $(this);
948  var rowItem = $("#guUserGrid").data("kendoGrid").dataItem(row);
949 
950  // set primary to checked
951  if (rowItem.u_primary) {
952  row.find("input[type=checkbox]").prop("checked", true);
953  }
954 
955  // set disabled if primary count is above 1 or
956  // set disabled if account access is wack
957  // set click event for refresh button
958  if (!rowItem.u_primary) {
959  if ((guObserve.source.o_primary.length > 1 || rowItem.o_count > 0)) {
960  row.addClass("cleanup");
961  row.find("td:eq(1)").css("cursor", "not-allowed"); <?php // Let's only prevent this on the column of the primary user. ?>
962  row.find("input[type=checkbox]").prop("disabled", true);
963  row.find("input[type=checkbox]").css("cursor", "not-allowed");
964  row.find("button").on("click", function(e) {
965  // cannot reset user account access if multiple
966  // primary owners exist
967  if (guObserve.source.e_primary.length > 1) {
968  guNotifyRefreshFail.open();
969  } else {
970  guObserve.set("refreshUser", rowItem);
971  guNotifyRefresh.open();
972  }
973  });
974  }
975  }
976  }
977  });
978  },
979  change: function() {
980  var grid = $("#guUserGrid").data("kendoGrid");
981  var row = grid.select();
982 
983  var box = row.find("input[type=checkbox]");
984  $(box).trigger("click");
985 
986  row.removeClass("k-state-selected");
987  }
988  });
989 
990  kendo.bind("#guUsers", guObserve);
991 
992  guDiscard = $("#guDiscard").kendoDialog({
993  title: "Discard Changes",
994  content: "<div class='col-sm-12'>"
995  + "<p>This group's information has been changed.</p>"
996  + "<p>Do you wish to discard the changes?</p>"
997  + "</div>",
998  modal: true,
999  minWidth: 300,
1000  maxWidth: 500,
1001  visible: false,
1002  resizable: false,
1003  show: EventOpenWindow,
1004  close: EventCloseWindow,
1005  actions: [
1006  { text: "No",
1007  action: function() { guAction = "discardDeny"; }
1008  },
1009  { text: "Yes", primary: true,
1010  action: function() { guAction = "discardConfirm"; }
1011  }
1012  ]
1013  }).data("kendoDialog");
1014 
1015  guNotifyPrimary = $("#guNotifyPrimary").kendoDialog({
1016  title: "Primary User",
1017  content: "<div class='col-sm-12'>"
1018  + "<p>By changing the primary user, the selected user will take on the rights and access of the current primary user.</p>"
1019  + "<p>This action cannot be undone except by changing the rights per sub-account.</p>"
1020  + "</div>",
1021  modal: true,
1022  minWidth: 300,
1023  maxWidth: 500,
1024  visible: false,
1025  resizable: false,
1026  show: EventOpenWindow,
1027  close: EventCloseWindow,
1028  actions: [
1029  { text: "Ok", primary: true,
1030  action: function() { guAction = "notifyPrimary"; }
1031  }
1032  ]
1033  }).data("kendoDialog");
1034 
1035  guNotifyRefreshFail = $("#guNotifyRefreshFail").kendoDialog({
1036  title: "Reset Account Access",
1037  content: "<div class='col-sm-12'>"
1038  + "<p>This user's sub-account access cannot be reset because there are multiple primary owners for this group.</p>"
1039  + "<p>Please update the group by selecting a single primary owner before trying to reset this user's sub-account access.</p>"
1040  + "</div>",
1041  modal: true,
1042  minWidth: 300,
1043  maxWidth: 500,
1044  visible: false,
1045  resizable: false,
1046  show: EventOpenWindow,
1047  close: EventCloseWindow,
1048  actions: [
1049  { text: "Ok", primary: true,
1050  action: function() { guAction = "notifyRefreshFail"; }
1051  }
1052  ]
1053  }).data("kendoDialog");
1054 
1055  guNotifyRefresh = $("#guNotifyRefresh").kendoDialog({
1056  title: "Reset Account Access",
1057  content: '<div class="col-sm-12">'
1058  + '<p>By cropping this user\'s sub-account access, you will be removing access to the sub-accounts which the current primary user does not access.</p>'
1059  + '<p>Other sub-accounts which the primary owner also has access to will remain for this user.</p>'
1060  + '</div>',
1061  modal: true,
1062  minWidth: 300,
1063  maxWidth: 500,
1064  visible: false,
1065  resizable: false,
1066  show: EventOpenWindow,
1067  close: EventCloseWindow,
1068  actions: [
1069  { text: "Ok", primary: true,
1070  action: function() { guAction = "notifyRefresh"; }
1071  }
1072  ]
1073  }).data("kendoDialog");
1074 
1075  guStatus = $("#guStatus");
1076  guStatus.hide();
1077 
1078  guTooltip = homecuTooltip.defaults;
1079  guTooltip.filter = ".cleanup td:eq(1)"; <?php // Let's just put this on the column of the primary user. ?>
1080  guTooltip.content = EventShowTip,
1081  $("#guUsers").kendoTooltip(guTooltip);
1082  }
1083 
1084  var InitDataActions = function() {
1085  $("#btnUpdate").on("click", function() {
1086  EventUpdateUsers();
1087  });
1088  $("#lnkCancel").on("click", function() {
1089  guUsers.close();
1090  });
1091  }
1092 
1093  this.Open = function(windowStack) {
1094  // setup validator
1095  $.homecuValidator.setup({
1096  formStatusField: "status",
1097  formValidate: "guUsers"
1098  });
1099 
1100  guCardWindows = windowStack;
1101  var groupRequest = {
1102  operation: "groupReadUsers",
1103  payload: guPayload
1104  };
1105 
1106  guDataSource.transport.options.read.type = "POST";
1107  guDataSource.read(groupRequest);
1108  }
1109 
1110  this.Close = function() {
1111  guUsers.destroy();
1112  }
1113 
1114  this.Data = function(payload, group) {
1115  guPayload = payload;
1116  guGroup = group;
1117  }
1118 
1119  this.Init = function(hubCall, cardContainer) {
1120  guCall = hubCall;
1121  guCardContainer = cardContainer;
1122 
1123  InitDataSources();
1124  InitDataViews();
1125  InitDataActions();
1126 
1127  guCall("GroupUsers", this);
1128  }
1129 }
1130 </script>
1131 <?php }