Odyssey
aMemberSearch.prg
1 <?php
2 /**
3  * @package MemberHub
4  * @author MGHandy
5  *
6  * @uses admin member search
7  * * search for member by strict member account number: meaning there will be no
8  * partial searches or full searches because of the possibility of thousands of results.
9  *
10  * @var string $mOperation: requested search action
11  * @var string $mParameters: json string of form fields submitted by user
12  * @var string $mMember: requested member number
13  */
14 
15 require_once("$admLibrary/aMemberSupport.i");
16 
17 try {
18  $admVars = array();
19  $admOk = array(
20  "operation" => array("filter" => FILTER_SANITIZE_STRING),
21  "mParameters" => array("filter" => FILTER_SANITIZE_STRING)
22  );
23 
24  HCU_ImportVars($admVars, "MEMBER_SEARCH", $admOk);
25 
26  $sOperation = isset($admVars["MEMBER_SEARCH"]["operation"]) ? $admVars["MEMBER_SEARCH"]["operation"] : null;
27  $sParameters = isset($admVars["MEMBER_SEARCH"]["mParameters"]) ? $admVars["MEMBER_SEARCH"]["mParameters"] : null;
28 
29  $aryResult = array();
30  $aryReply = array();
31 
32  switch ($sOperation) {
33  case "":
35  break;
36  case "memberSearch":
37  header('Content-type: application/json');
38 
39  $sValidate = MemberValidate($SYSENV, $sParameters, true);
40  $sContext = MemberContext($SYSENV, $Cu, $sValidate);
41  $sMembers = MemberSearch($SYSENV, $dbh, $sContext);
42 
43  if ($sMembers['members'] && count($sMembers['members']) == 1) {
44  // single member found
45  $sMember = $sMembers['members'][0];
46 
47  // validate member
48  // update context
49  // select display information
50  // encrypt member
51  $sMemberValidate = MemberValidate($SYSENV, $sMember);
52  $sMemberContexet = MemberContext($SYSENV, $Cu, $sMemberValidate);
53  $sMemberSelect = MemberSelect($SYSENV, $dbh, $sMemberContexet);
54  $sMemberEncrypt = MemberEncrypt($SYSENV, $Cu, $sMemberSelect);
55 
56  $aryResult['data']['member'] = $sMemberSelect;
57  $aryResult['data']['encrypt'] = $sMemberEncrypt;
58  } else {
59  $aryResult['data']['members'] = $sMembers['members'];
60  }
61  MemberReply($aryResult, $aryReply, $sOperation);
62  break;
63  default:
64  throw new Exception("Unknown server request: " . $sOperation);
65  break;
66  }
67 
68 } catch (Exception $e) {
69  $aryReply['errors'][] = $e->getMessage();
70  $aryResult['data'] = array();
71  $aryResult['info'] = array();
72  MemberReply($aryResult, $aryReply, $sOperation);
73 }
74 
75 /**
76  * MemberSearch:
77  * @uses search for member by list of parameters:
78  * * member account number
79  *
80  * @param $pEnv array: environment object for debugging
81  * @param $pDbh object: database access object
82  * @param $pContext array: context variable holding decrypted info and cu codes
83  * for use to access tables and values.
84  * @param $pParameters array: list of data fields to search on, validated for
85  * proper database use.
86  *
87  * @return $sqlReturn array: list of members matching the search criteria
88  */
89 function MemberSearch($pEnv, $pDbh, $pContext) {
90  $cuTable = $pContext['cu_table'];
91  $cuCode = $pContext['cu_code'];
92  $cuAccount = $pContext['m_account'];
93 
94  $sqlReturn = array();
95  $sqlColumns = "
96  accountnumber AS m_account";
97  $sqlSelect = "
98  SELECT $sqlColumns
99  FROM {$cuTable}memberacct
100  WHERE accountnumber = '$cuAccount'";
101 
102  $sqlSelectRs = db_query($sqlSelect, $pDbh);
103  if (!$sqlSelectRs) {
104  $pEnv['logger']->error(db_last_error());
105  throw new Exception("Failed to read members.");
106  }
107 
108  $sqlReturn['members'] = db_fetch_all($sqlSelectRs);
109  return $sqlReturn;
110 }
111 ?>
112 
113 <?php
114 /**
115  * @package PrintMemberSearch
116  * @uses print neccessary html/javascript to run the selected card
117  */
118 function PrintMemberSearch() { ?>
119 <div id="search">
120  <div id="status"></div>
121  <div class="row hcuSpacer">
122  <div class="col-sm-5">
123  <label for="inpMbrAccount"> Account #</label>
124  </div>
125  <div class="col-sm-7">
126  <input type="text" class="k-input k-textbox hcu-all-100" id="inpMbrAccount" name="inpMbrAccount"
127  maxlength="12"
128  homecu-maxlen="12"
129  data-homecuCustomMaxLen-msg="Account number must be at most 12 characters"
130  data-required-msg="Account number is required"
131  required>
132  </div>
133  </div>
134 </div>
135 
136 <div id="noResults" class="row">
137  <div class="col-sm-12">
138  <p>No accounts were found.</p>
139  </div>
140 </div>
141 
142 <?php
143 /**
144  * @package MemberSearch
145  * @uses this object is used to display and interact with the member searchfeature.
146  *
147  * @var Init public: call to initialize data/view/action objects
148  * @var Open public: call to open the mamber search module/window
149  * @var Close public: call to close the member search module/window
150  * @var Data public: call to load payload and member display into
151  * MemberRelated object for later use.
152  *
153  * @var InitDataSources private: initialize all data sources/objects
154  * @var InitDataViews private: initialize all data views/objects
155  * @var InitDataActions private: initialize all user actions on html.
156  *
157  * @var EventOpenWindow private: open kendoDialog/kendoWindow objects
158  * @var EventCloseWindow private: close kendoDialog/kendoWindow objects
159  * @var EventPopWindow private: remove the correct window from the window stack.
160  *
161  * @var Event* private: other event functions explained by name.
162  * Some are entensions of kendo objects, others just help with events of html objects.
163  *
164  * @var Validate* private: validation functions for fors and other user
165  * input interactions.
166  */
167 ?>
168 <script type="text/javascript">
169 
170 var MemberSearch = function() {
171  var msCardContainer = null;
172  var msCardWindows = null;
173 
174  var msCall = null;
175  var msAction = null;
176 
177  var msSearch = null;
178  var msNoResults = null;
179  var msDataSource = null;
180 
181  var mrInputMember = null;
182 
183  var ValidateSearch = function() {
184  var memberValue = mrInputMember.val().trim();
185  var memberLength = memberValue.length;
186 
187  if (memberLength == 0) {
188  mrInputMember.addClass("k-invalid");
189  mrInputMember.focus();
190 
191  return false;
192  } else {
193  mrInputMember.removeClass("k-invalid");
194  return true;
195  }
196  }
197 
198  var EventSendSearch = function() {
199  var memberValue = mrInputMember.val();
200  var memberData = {
201  m_account: memberValue
202  };
203 
204  var memberString = JSON.stringify(memberData);
205  var memberRequest = {
206  operation: "memberSearch",
207  mParameters: memberString
208  };
209 
210  msDataSource.transport.options.read.type = "POST";
211  msDataSource.read(memberRequest);
212  }
213 
214  var EventOpenWindow = function(e) {
215  var windowElement = this.element[0];
216  var windowId = windowElement.id;
217 
218  switch (windowId) {
219  case "search":
220  mrInputMember.removeClass("k-invalid");
221  mrInputMember.val("");
222  mrInputMember.focus();
223  break;
224  }
225 
226  msCardWindows.push(this);
227  }
228 
229  var EventCloseWindow = function(e) {
230  var windowElement = this.element[0];
231  var windowId = windowElement.id;
232 
233  switch (msAction) {
234  case "searchSubmit":
235  if ($.homecuValidator.validate()) {
236  EventSendSearch();
237  } else {
238  e.preventDefault();
239  }
240  break;
241  case "searchStart":
242  EventPopWindow(windowId);
243  msSearch.open();
244  break;
245  default:
246  EventPopWindow(windowId);
247  break;
248  }
249 
250  msAction = null;
251  }
252 
253  var EventPopWindow = function(windowId) {
254  var popIndex = -1;
255  for (var i = 0; i < msCardWindows.length; i++) {
256  var openWindow = msCardWindows[i].element[0];
257  var openId = openWindow.id;
258 
259  if (openId == windowId) {
260  popIndex = i;
261  break;
262  }
263  }
264 
265  if (popIndex > -1) {
266  msCardWindows.splice(popIndex, 1);
267  }
268  }
269 
270  var InitDataSources = function() {
271  msDataSource = new kendo.data.DataSource({
272  transport: {
273  read: {
274  url: "main.prg",
275  dataType: "json",
276  contentType: "application/x-www-form-urlencoded",
277  type: "GET",
278  cache: false,
279  data: {
280  ft: "103102"
281  }
282  }
283  },
284  requestStart: function(request) {
285  showWaitWindow();
286  },
287  requestEnd: function(response) {
288  setTimeout(hideWaitWindow, 500);
289 
290  if (response.hasOwnProperty("response")) {
291  if (response.response.hasOwnProperty("Results")) {
292  var results = response.response.Results;
293 
294  if (results.hasOwnProperty("error")) {
295  $.homecuValidator.homecuResetMessage = true;
296  $.homecuValidator.displayMessage(results.error, $.homecuValidator.settings.statusError);
297  } else if (results.hasOwnProperty("info")) {
298  $.homecuValidator.homecuResetMessage = true;
299  $.homecuValidator.displayMessage(results.info, $.homecuValidator.settings.statusSuccess);
300  }
301  } else {
302  $.homecuValidator.displayMessage("Error Parsing Server", $.homecuValidator.settings.statusError);
303  }
304  } else {
305  $.homecuValidator.displayMessage("Error Parsing Server", $.homecuValidator.settings.statusError);
306  }
307  },
308  schema: {
309  parse: function(response) {
310 
311  var results = null;
312  var resultData = null;
313  var resultOperation = null;
314 
315  if (response.hasOwnProperty("Results")) {
316  results = response.Results;
317  resultData = results.data;
318  resultOperation = results.operation;
319  } else {
320  return [];
321  }
322 
323  if (results.hasOwnProperty("errors")) {
324  return [];
325  }
326 
327  if (resultData == undefined || resultData == null) {
328  return [];
329  }
330 
331  setTimeout(function() {
332  switch (resultOperation) {
333  case "memberSearch":
334  if (resultData.encrypt) {
335  // single member found
336  msCall("updateMemberInfo", resultData.member);
337  msCall("updateMemberEncrypt", resultData.encrypt);
338  } else {
339  if (resultData.members) {
340  // if any results
341  } else {
342  msNoResults.open();
343  }
344  }
345  break;
346  }
347  }, 500);
348 
349  return [];
350  }
351  }
352  });
353  }
354 
355  var InitDataViews = function() {
356  msSearch = msCardContainer.find("#search").kendoDialog({
357  title: "Account Search",
358  modal: true,
359  minWidth: 300,
360  maxWidth: 900,
361  visible: false,
362  resizable: false,
363  show: EventOpenWindow,
364  close: EventCloseWindow,
365  actions: [
366  { text: "Cancel",
367  action: function() { msAction = "searchCancel"; }
368  },
369  { text: "Search", primary: true,
370  action: function() { msAction = "searchSubmit"; }
371  }
372  ]
373  }).data("kendoDialog");
374 
375  msNoResults = msCardContainer.find("#noResults").kendoDialog({
376  title: "Select Account",
377  modal: true,
378  minWidth: 300,
379  maxWidth: 900,
380  maxHeight: 500,
381  visible: false,
382  resizable: false,
383  show: EventOpenWindow,
384  close: EventCloseWindow,
385  actions: [
386  { text: "Cancel",
387  action: function() { msAction = "searchCancel"; }
388  },
389  { text: "Start Over", primary: true,
390  action: function() { msAction = "searchStart"; }
391  }
392  ]
393  }).data("kendoDialog");
394 
395  mrInputMember = $("#inpMbrAccount");
396  }
397 
398  var InitDataActions = function() {
399  mrInputMember.on("keyup", function(e) {
400  if (e.keyCode == 13) {
401  msAction = "searchSubmit";
402  msSearch.close();
403  }
404  });
405  }
406 
407  this.Open = function(windowStack) {
408  msCardWindows = windowStack;
409  msSearch.open();
410 
411  // setup validator on open
412  $.homecuValidator.setup({
413  formStatusField: "status",
414  formValidate: "search"
415  });
416  }
417 
418  this.Close = function() {
419  msSearch.destroy();
420  msNoResults.destroy();
421 
422  $.homecuValidator.setup({
423  formStatusField: "formStatus",
424  formValidate: "cardContainerDiv"
425  });
426  }
427 
428  this.Init = function(hubCall, cardContainer) {
429  msCall = hubCall;
430  msCardContainer = cardContainer;
431 
432  InitDataSources();
433  InitDataViews();
434  InitDataActions();
435  }
436 }
437 </script>
438 <?php }