Odyssey
lnappentry.i
1 <?php
2  /*
3  * NOTES FOR SETTING UP THE FieldAttr column of the {}schemadetail
4  *
5  * Here are the optional pieces that may be in the FieldAttr
6  *
7  * hidden - {1, 0} This is valid for GT fieldtypes, it will change the field
8  * to be a hidden field rather than textbox
9  * maxlength - This will set the maxlength property of a textbox
10  * size - This will set the size property of the textbox
11  * helpurl - This will be used to create a 'helpurl', this will be the link for the destination
12  * { this will be a two part field} in the following format
13  * "helpurl":{"href":"@url", "display":"Link Text"}
14  * egtext - This will create a example text next to the text box (ONLY APPLIES TO GT)
15  * appendnextfield - {1,0} when this is set the next field will be concantenated on the same row
16  *
17  * fieldcorearrayindex - This is for sending information to the core.. This is a key value that is
18  * used as the index of the data when the application is prepared to send
19  * fieldcorename - This is the key value for the application field when sending to the core
20  * - This may be a comma separated list. Each element will be submitted
21  * - to the loan site, each will get the same value - HOWEVER THIS MAY ONLY
22  - be a list when localfieldonly is 0
23  * * NOTE: NO SPACES BETWEEN NAMES
24  *
25  * fieldcombinelocal - This field should contain a list of fields as specificed by their 'Core Field Name' separated by :
26  * ex. :dms_coappref1city::dms_coappref1st::dms_coappref1zip:
27  * When submitting to the core, the fields will be combined in order using the value in
28  * 'fieldcombinelocaldelim' .
29  *
30  * fieldcombinelocaldelim - This value defines the delim between the fields
31  * Default is a space ' '.
32  *
33  * fieldcombineskipblank - If this value is set (on the field being included), and the value is empty ''. Then it will be
34  * skipped in the field
35  *
36  * validation_require - Values are: {1, 2}, NOT SET
37  * NOT SET, the field is NOT required to Save or Submit
38  * 1 - The field is required to Submit the Application ONLY
39  * 2 - The field is required to Save AND Submit the Application
40  *
41  * validation_match - Possible values are: {date, ssn, phone, url, email, usd, integer, number, zip}
42  * // If a custom regex is required set the validation_custom field
43  * validation_custom - This is set for a custom matching format
44  * validation_desc - When using either validation_match or validation_desc this field can be used
45  * to customize the validation error description
46  * validation_range - This field is used to give limitations to teh data that can be in the field.
47  * ie., Less Than, Less Than Equal, Greater than, etc.. Here are the different options,
48  * the options are separated with a | {PIPE}
49  * LT|{VALUE} -- Field value is LESS THAN {VALUE}
50  * LE|{VALUE} -- Field value is LESS THAN OR EQUAL TO {VALUE}
51  * GT|{VALUE} -- Field value is GREATER THAN {VALUE}
52  * GE|{VALUE} -- Field value is GREATER THAN OR EQUAL TO {VALUE}
53  * RG|{VALUE1}|{VALUE2} -- Field value is in the Range from {VALUE1} to {VALUE2}
54  * validation_require_numeric_range_chk {0, 1} Is the amount for this field constrained by either a min or max { 1 - yes: 0 (default) - no}
55  * ONLY applies to type usd/number -- when selected this will always validate independent of validation_require options
56  * validation_require_numeric_range [min max]
57  * the min and max for the valid range. One must be entered. A non value indicates no limit
58  * value >= min value <= max
59  * FOLLOWING TWO FIELDS WORK IN CONJUCTION WITH ONE ANOTHER
60  * validation_conditionname -- This property will allow other fields to test
61  * for a valid value in order to be required
62  * This is a self created unique name that will be used to
63  * identify the field later where fields will be required,
64  * but only when this matches a certain value
65  * validation_require_conditional -- This is a two part value.. It is setup in
66  * the following format
67  * field -- this will specify a field on the form that will find a field
68  * on the form that matches it's property set with validation_conditionname
69  * value -- When the specified field has this value, then this field will be required
70  * append_class - This will append the specified class to the field.
71  * localfieldonly - This field will NOT be included in the packet of information sent to the core
72  * submitstatement - Use the default value of this field as the Submit Certify statement
73  * autofillfromcore - For NEW entries by Home Banking login members.
74  * When this value is populated, the value from the coreAutoFill array
75  * will be used to load the field.. There is a separate loop to create this
76  * JSON data
77 
78  */
79 
80  // * Determine the following
81  // NEW -- Starting a NEW LOan
82  // LOAD -- Loading a previously saved loan
83  // POST -- Form was POSTED to save/submit?
84 
85 try {
86 
87  $FORM_VALIDATION_ERROR = "";
88  $JSON_FormFields = ""; // JSON Formatted form fields Variable
89  $core_values_array = ""; // Core Application to be sent
90  $l_ShowDisclosure = false; // ** SET THIS TO FALSE -- The Disclosure script MAY set this
91  $l_ShowSecurity = false; // ** Set this to fals -- When showing the security script this is set to true
92 
93  // * LOAD EXPECTED VALUES FROM _POST OR _GET *
94  $loadedValues['lnappentry'] = Array();
95  $loadFields = Array("btnFormPost" => array('filter' => FILTER_SANITIZE_STRING),
96  "btnFormDisclosure" => array('filter' => FILTER_SANITIZE_STRING),
97  "btnSubmitNow" => array('filter' => FILTER_SANITIZE_STRING),
98  "btnFinishLater" => array('filter' => FILTER_SANITIZE_STRING),
99  "loanid" => array('filter' => FILTER_SANITIZE_NUMBER_INT),
100  "respid" => array('filter' => FILTER_SANITIZE_NUMBER_INT),
101  "new" => array('filter' => FILTER_SANITIZE_NUMBER_INT),
102  "load" => array('filter' => FILTER_SANITIZE_NUMBER_INT),
103  "confid" =>array('filter' => FILTER_SANITIZE_STRING)
104  );
105  HCU_ImportVars($loadedValues, "lnappentry", $loadFields);
106 
107  $Cu = $HB_ENV['Cu'] ?? '';
108 
109  // ** This array will define the formatting for the information coming from the core.
110  // ** we can not depend on the format returned by the cores, so in some cases,
111  // * any potential formatting will be stripped and correct formatting added
112  /*
113  * Structure - Key is the value referenced when configuring a loan application
114  * format - This is the format type for the value so any formatting can
115  * be done
116  * mir_key - This is the key to use from the mir data retrieved with
117  * GetMemberInfo
118  */
119  $coreAutoFillFormat = Array("AccountNumber" => Array('format' => 'none', 'mir_key' => 'accountnumber'),
120  "FirstName" => Array('format' => 'none', 'mir_key' => 'firstname'),
121  "MiddleName" => Array('format' => 'none', 'mir_key' => 'middlename'),
122  "LastName" => Array('format' => 'none', 'mir_key' => 'lastname'),
123  "Email" => Array('format' => 'none', 'mir_key' => 'email'),
124  "HomePhone" => Array('format' => 'phone', 'mir_key' => 'homephone'),
125  "WorkPhone" => Array('format' => 'phone', 'mir_key' => 'workphone'),
126  "CellPhone" => Array('format' => 'phone', 'mir_key' => 'cellphone'),
127  "Fax" => Array('format' => 'phone', 'mir_key' => 'fax'),
128  "SSN" => Array('format' => 'ssn', 'mir_key' => 'ssn'),
129  "Address1" => Array('format' => 'none', 'mir_key' => 'address1'),
130  "Address2" => Array('format' => 'none', 'mir_key' => 'address2'),
131  "City" => Array('format' => 'none', 'mir_key' => 'city'),
132  "State" => Array('format' => 'none', 'mir_key' => 'state'),
133  "Zip" => Array('format' => 'zip', 'mir_key' => 'zip'),
134  "CC" => Array('format' => 'none', 'mir_key' => 'cc'),
135  "DOB" => Array('format' => 'date', 'mir_key' => 'dob'));
136 
137 
138  $coreAutoFillInfo = Array(); // ** This will be 'info' portion of the array returned from the MIR packet request GetMemberInfo, containing values from the core
139  $defaultItemsFromCore = false; // ** This value is just a boolean, so I know later, whether I should be creating the field for displaying default values
140  $valuesItemsFromCore = Array();
141  $Master_LoanID = 0;
142  $App_RespID = -1;
143  $App_Confirm = false; // ** assume guilty.. prove innocence
144  $setInputMaskEntry = ''; // These are JQUERY COMMANDS To offer more support in formatting date fields
145  $setExtraValidityCmds = ''; // These are EXTRA jquery validity commands that will be verified on submit - If set they must always be met, not dependent on other validation fields
146  if (HCU_array_key_exists('load', $loadedValues['lnappentry'])) {
147  $loadLoanId = intval($loadedValues['lnappentry']['load']);
148  // ** Check to be certain the user is loading one of their own
149  $sql = "SELECT *
150  FROM {$DB_TABLE_PREFIX}userresponse
151  WHERE respid = " . $loadLoanId . "
152  AND userid = " . intval($DMSAPP_CURRENTUSERID);
153 
154  $app_rs = db_query($sql, $dbh);
155  $app_row = db_fetch_assoc($app_rs);
156  if ($app_row) {
157  // ** Loan found -- Load the data
158  $Master_LoanID = $app_row['loanid'];
159  $App_RespID = $app_row['respid'];
160 
161  if ($app_row['respsubmiton'] != '') {
162  $FORM_VALIDATION_ERROR = "<li>The loan you are trying to edit was submitted on {$app_row['respsubmiton']} and may not be modified.</li>";
163  // *set this back to nothing to prevent it from being loaded
164  $Master_LoanID = "";
165  } else {
166  // ** To EDIT any loan the SSN, Name, DOB must be confirmed.
167  // * this will be done by checking the contents of confid which will be
168  // sha1($DMSAPP_SECRET_KEY . {FIRSTNAME} . {LASTNAME} . {SSN} . {DOB})
169 
170  // * Create the value to check
171  if (HCU_array_key_exists('confid', $loadedValues['lnappentry'])) {
172  $l_cookiename = ReturnDeviceCookieName($DMSAPP_CURRENTCUCODE, $DMSAPP_LOGINTYPE, $DMSAPP_CURRENTEMAIL, $DMSAPP_CURRENTUSERID);
173  // ** Get Cookie Contents and include it with the value being crypted
174  $l_cookieval = $_COOKIE[$l_cookiename];
175 
176  // $RecordVal = sha1($DMSAPP_SECRET_KEY . strtolower(trim($app_row['respfname'])) . strtolower(trim($app_row['resplname'])) . trim($app_row['respssn']) . date('mdY', strtotime($app_row['respdob'])) . $l_cookieval);
177  $RecordVal = sha1($DMSAPP_SECRET_KEY . trim($app_row['respssn']) . date('mdY', strtotime($app_row['respdob'])) . $l_cookieval);
178 
179  if (crypt($RecordVal, $loadedValues['lnappentry']['confid']) == $loadedValues['lnappentry']['confid']) {
180  $App_Confirm = true;
181  // ** Allow them to Load
182  } else {
183  // ** they failed credential check
184  $FORM_VALIDATION_ERROR = "<li>The answers you provided did not match with what we have on file for this loan. Please try again.</li>";
185  }
186  }
187  if (!$App_Confirm) {
188  //** Application confirm FAILED
189  // ** Either Include Script or redirect
190 
191  // ** Create redirect option
192  $lnapp_security_return_form_code = $form_code;
193  $lnapp_security_params = "load=" . $loadLoanId;
194  $lnapp_security_respid = "";
195  // ** Either case --
196 
197  include_once($inc_path . "lnappsecurity.i");
198  /// ** Hide the menu when showing the disclosure
199  print <<< HIDEMENU
200  <script>
201  $(document).ready(function() {
202  $('#body-wrapper').addClass('no-show-menu');
203  })
204  </script>
205 HIDEMENU;
206  $l_ShowSecurity = true;
207  }
208  }
209  } else {
210  // ** Something wrong.. loan not found..
211  $FORM_VALIDATION_ERROR = "<li>The loan you are trying to load was not found.</li>";
212  }
213  } else if (HCU_array_key_exists('new', $loadedValues['lnappentry'])) {
214  // ** Need to check if there is a LOAN Application Disclsoure to display
215  //
216  // ** IF there IS a disclosure AND the Approve Disclosure Value is NOT set then redirect to disclosure
217  if (HCU_array_key_exists('btnFormDisclosure', $loadedValues['lnappentry']) != 'entry') {
218  $lnapp_disclosure_loanid = intval($loadedValues['lnappentry']['new']);
219  include_once($inc_path . "lnappdisclosure.i");
220  // ** NOW check to see if disclosure display is set, if it is then set our
221  // * Local value to be the same -- Use the local value in this script
222 
223  if (isset($lnapp_disclosure_display)) {
224  $l_ShowDisclosure = $lnapp_disclosure_display;
225  if ($l_ShowDisclosure) {
226  /// ** Hide the menu when showing the disclosure
227  print <<< HIDEMENU
228  <script>
229  $(document).ready(function() {
230  $('#body-wrapper').addClass('no-show-menu');
231  })
232  </script>
233 HIDEMENU;
234  }
235  }
236 
237  }
238  // ** Start a NEW Loan
239  $Master_LoanID = intval($loadedValues['lnappentry']['new']);
240  } else if (HCU_array_key_exists('btnFormPost', $loadedValues['lnappentry'])) {
241  // * We will try to save information.. Save ONLY or also submit
242  $Master_LoanID = intval(HCU_array_key_value('loanid', $loadedValues['lnappentry']));
243  $App_RespID = intval(HCU_array_key_value('respid', $loadedValues['lnappentry']));
244  } else {
245  // There is something wrong.. we may need to exit -- the sql will fail and will most likely fail there
246  }
247 
248  $App_SchemaDetail = Array();
249  $App_SchemaFields = Array();
250  $App_AnswerDetail = Array();
251  $App_ConditionalFields = Array(); // ** this is the list of conditional fields on the posted form..
252 
253  if (!$l_ShowDisclosure && !$l_ShowSecurity) {
254  // * BEFORE I DO anything, I will create some arrays of the loan being viewed/saved
255  if ($Master_LoanID > 0) {
256  $sql = "SELECT schemadetail.*
257  FROM {$DB_TABLE_PREFIX}schemadetail as schemadetail
258  JOIN {$DB_TABLE_PREFIX}schemamaster as schemamaster ON
259  schemamaster.loanid = schemadetail.loanid
260  WHERE schemadetail.loanid = " . intval($Master_LoanID) . "
261  AND schemamaster.cu = '$DMSAPP_CURRENTCUCODE'
262  ORDER BY schemadetail.loanid, schemadetail.pageid, schemadetail.groupid, schemadetail.lineid
263  ";
264  $loan_rs = db_query($sql, $dbh);
265  // ** IF NO RECORD
266 
267  if ($loan_rs && db_num_rows($loan_rs) > 0) {
268  $loan_idx = 0;
269  while ($loan_row = db_fetch_assoc($loan_rs, $loan_idx++)) {
270  // ** Need to create the Loan Master Schema Array
271  // ** Make the detailid the key so I can look it up quickly
272  $App_SchemaDetail[$loan_row['detailid']] = $loan_row;
273 
274  // ** The Haystack was in the wrong position for the function
275  if (strpos(":YNR:YNR01:YNS:YNS01:GN:GA:GT:AS:AR:", ":" . trim($loan_row['fieldtype']) . ":") !== false) {
276  // * This appears to be a valid type... This is a field that should be saved
277  // to the database field response
278  // ** All fields save will be the field name "formfield_{detailid}"
279  $fieldname = "formfield_" . $loan_row['detailid'];
280  $App_SchemaFields[$fieldname] = "";
281 
282  // ** If we are posting the form.. There are situations that I want to
283  // ** record something.. This is when
284  if (isset($_POST['btnFormPost'])) {
285  $fieldattr = json_decode($App_SchemaDetail[$loan_row['detailid']]['fieldattr'], true);
286  if (HCU_array_key_value('validation_conditionname', $fieldattr) != '') {
287 
288  // This value is set as a conditional value -- I will set the value in the array here
289  if (HCU_array_key_exists($fieldname, $_POST)) {
290  $App_ConditionalFields[$fieldattr['validation_conditionname']] = trim($_POST[$fieldname]);
291  }
292  }
293  }
294  }
295  }
296  } elseif ($FORM_VALIDATION_ERROR != '') {
297  // ** PROBLEM LOADING MASTER SCHEMA -- If validation error is not set, then set something
298  // $FORM_VALIDATION_ERROR = "<li>A problem was encountered that is preventing the loan application from loading.</li>";
299  throw new Exception ("A problem was encountered that is preventing the loan application from loading.");
300  } else {
301  /* GENERAL ERROR */
302  throw new Exception ("A loan matching the specified criteria was not found.");
303  }
304  }
305 
306  if (isset($_POST['btnFormPost'])) {
307  //isset($_POST['btnSubmitNow']) || isset($_POST['btnFinishLater'])) {
308  // ** We have data.. we want to post... We need to validate data...
309  // ** we also will need to
310 
311  // ** Cookie val set.. see if can get it tow ork
312  // * the purpose is to prevent users from pressing F5 -- I will instead
313  // * reload the form, with NO Saving
314  if (!HCU_array_key_value('cookieval_' . intval($_COOKIE['ENTRYCOOKIE']), $_POST) == "SET") {
315  $FORM_VALIDATION_ERROR = "<li>Unable to process request. Do not use F5 or reload screen. Use the buttons provided on the bottom of the application</li>.";
316  }
317 
318  // ** If I have an object prepared with all the records, then I can loop
319  // ** through each item, and each one that has the required attribute set
320  // ** then I can
321 
322  $Custom_Resp_Field = Array();
323  // * *BUild the object for repopulating the form FROM posted values
324  $respLoanTitle = "";
325  if ($FORM_VALIDATION_ERROR == "") {
326  // ** I KNOW THE FORMS FIELDS I Will be posting -- so loop through them here
327  // * and validate based on their type
328  $FormPopulate = array();
329  foreach ($App_SchemaFields as $fields_key=>$fields_value) {
330 
331  $field_detailid = substr($fields_key, strlen("formfield_") );
332 
333  $fieldattr = json_decode($App_SchemaDetail[$field_detailid]['fieldattr'], true);
334 
335  $fieldval = trim(HCU_array_key_value($fields_key, $_POST));
336  // ** Here I want to handle special exceptions for values.. If the
337  // * value is of a certain type I will replace the field.
338  // * exceptions are currently
339  // * %timestamp% -- replace with current time
340 
341  if ($fieldval == '%timestamp%') {
342  $fieldval = date('m/d/Y');
343  }
344  // * Determine if the field is required -- ONLY REQUIRE FOR Button Submit NOW
345  if ((isset($_POST['btnFormPost']) && $_POST['btnFormPost'] == 'Submit') || isset($_POST['btnFormPost']) && $_POST['btnFormPost'] == 'Save') {
346  if (isset($fieldattr['validation_require']) && $fieldval == '' && (intval(HCU_array_key_value('hidden', $fieldattr)) != 1)) {
347  if (($_POST['btnFormPost'] == 'Submit' && $fieldattr['validation_require'] > 0) || ($_POST['btnFormPost'] == 'Save' && $fieldattr['validation_require'] == 2)) {
348  // ** Check to see if this has a conditional requirement
349  if (HCU_array_key_exists('validation_require_conditional',$fieldattr)) {
350  if ($fieldattr['validation_require_conditional'] != '') {
351  // ** now we will test to see if the condition is met.
352  // ** Posted Conditional values are saved in the App_ConditionalFields array
353  // ** the Required condition is saved in the validation_require_conditional attribute as a json object array [field=>'', value='']
354  if (isset($fieldattr['validation_require_conditional']['field']) && isset($fieldattr['validation_require_conditional']['value'])) {
355  // If both values are set then proceed with conditional requirement
356  if (HCU_array_key_value($fieldattr['validation_require_conditional']['field'], $App_ConditionalFields) == trim($fieldattr['validation_require_conditional']['value']) && $fieldval == '') {
357  $FORM_VALIDATION_ERROR .= "<li>" . $App_SchemaDetail[$field_detailid]['fieldvalue'] . " is a required field to submit this application.</li>";
358  }
359  }
360  } else {
361  // ** There is NO conditional requirement -- Always require
362  $FORM_VALIDATION_ERROR .= "<li>" . $App_SchemaDetail[$field_detailid]['fieldvalue'] . " is a required field to submit this application.</li>";
363  }
364  }
365  }
366  }
367  }
368 
369  // ** check for data type
370  //print "<br>Test fieldval -- " . $App_SchemaDetail[$field_detailid]['fieldtype'] . " :: [$fieldval] :: strlen ::" . strlen($fieldval);
371  if (strlen($fieldval) > 0) {
372  // ** data type
373 
374  // print "<br>Test fieldval -- " . $App_SchemaDetail[$field_detailid]['fieldtype'];
375  switch ($App_SchemaDetail[$field_detailid]['fieldtype']) {
376  case "YNR":
377  case "YNS":
378  // ** Values may be Y / N or Blank
379  //print "fieldval -- $fieldval";
380  if (!strstr(":Y:N:", $fieldval) && $fieldval != "") {
381  $FORM_VALIDATION_ERROR .= "<li>" . $App_SchemaDetail[$field_detailid]['fieldvalue'] . " contains an invalid option.</li>";
382  }
383  break;
384  case "YNR01":
385  case "YNS01":
386  // ** Values may be 1 / 0 or Blank
387  //print "fieldval -- $fieldval";
388  if (!strstr(":1:0:", $fieldval) && $fieldval != "") {
389  $FORM_VALIDATION_ERROR .= "<li>" . $App_SchemaDetail[$field_detailid]['fieldvalue'] . " contains an invalid option.</li>";
390  }
391  break;
392  case "AS":
393  case "AR":
394  // ** THESE COULD BE NUMERIC OR TEXT -- Teh ultimate test is to know the type and look it up as a valid option
395  // ** values may be an integer only -- not larger than???
396  // if (!is_int($fieldval)) {
397  // $FORM_VALIDATION_ERROR .= "<li>" . $App_SchemaDetail[$field_detailid]['fieldvalue'] . " contains an invalid option.</li>";
398  // }
399  break;
400  // ** GN AND GA types may be phased out
401  case "GN":
402  // ** value must be numeric
403  case "GA":
404  // ** value must be an amount
405  case "GT":
406  // ** value is a generic text
407  // ** The data type is determined by validation_match under the fieldattr object
408  if (isset($fieldattr['validation_match'])) {
409  switch ($fieldattr['validation_match']) {
410  case "date":
411  // ** MUST BE VALID DATE AND in the FORMAT MM/DD/YYYY
412  if (!(validateDate($fieldval) || preg_match('/^((0?\d)|(1[012]))\/([012]?\d|30|31)\/\d{4}$/', $fieldval))) {
413  $FORM_VALIDATION_ERROR .= "<li>" . $App_SchemaDetail[$field_detailid]['fieldvalue'] . " is not a valid date ##/##/####.</li>";
414  }
415  break;
416  case "ssn":
417  if (!preg_match('/^[\d]{3}-[\d]{2}-[\d]{4}$/', $fieldval)) {
418  $FORM_VALIDATION_ERROR .= "<li>" . $App_SchemaDetail[$field_detailid]['fieldvalue'] . " is not a valid ssn ###-##-####.</li>";
419  }
420  break;
421  case "phone":
422  if (!preg_match('/\d{3}[-\s.]\d{3}[-\s.]\d{4}/x', $fieldval)) {
423  $FORM_VALIDATION_ERROR .= "<li>" . $App_SchemaDetail[$field_detailid]['fieldvalue'] . " is not a valid phone ###-###-####.</li>";
424  }
425  break;
426  case "url":
427  // ** at this time, the db does not care too much.. use the client side validation.. below we will be checking for max length
428  break;
429  case "email":
430  if (!validateEmail($fieldval)) {
431  $FORM_VALIDATION_ERROR .= "<li>" . $App_SchemaDetail[$field_detailid]['fieldvalue'] . " is not a valid email.</li>";
432  }
433  break;
434  case "usd":
435  // if (!preg_match('/^([1-9][0-9]*|0)(\.[0-9]{2})?$/', $fieldval))
436  if (!preg_match('/^\$?((\d{1,3}(,\d{3})*)|\d+)(\.(\d{2})?)?$/', $fieldval)) {
437  $FORM_VALIDATION_ERROR .= "<li>" . $App_SchemaDetail[$field_detailid]['fieldvalue'] . " is not a valid dollar amount.</li>";
438  } else {
439  /* Validate dollar range */
440  $FORM_VALIDATION_ERROR .= ValidateRange($App_SchemaDetail[$field_detailid]['fieldvalue'], $fieldattr, $fieldval);
441  }
442  break;
443  case "integer":
444  // print "HERE -- " . $fieldval . "<br>";
445  if (!is_numeric($fieldval)) {
446  $FORM_VALIDATION_ERROR .= "<li>" . $App_SchemaDetail[$field_detailid]['fieldvalue'] . " is not a valid integer.</li>";
447  }
448  break;
449  case "number":
450  if (!preg_match('/^([1-9][0-9]*|0)(\.[0-9]{2})?$/', $fieldval)) {
451  $FORM_VALIDATION_ERROR .= "<li>" . $App_SchemaDetail[$field_detailid]['fieldvalue'] . " is not a valid number.</li>";
452  } else {
453  /* Validate dollar range */
454  $FORM_VALIDATION_ERROR .= ValidateRange($App_SchemaDetail[$field_detailid]['fieldvalue'], $fieldattr, $fieldval);
455  }
456 
457  break;
458  default:
459  // ** NEEDED??
460  }
461  }
462  // $('input.date').match('date', '#{field} is not a valid date.');
463  // $('input.ssn').match(/^\d{3}-\d{2}-\d{4}$/, "#{field} needs to be in the format of a Social Security Number.");
464  // $('input.phone').match('phone', '#{field} must be formatted as a phone number ###-###-####.');
465  // $('input.email').match('email', '#{field} must be formatted as an email.');
466 
467  // ** Be sure the field is NOT too large
468  if (isset($fieldattr['maxlength'])) {
469  if (strlen($fieldval) > intval($fieldattr['maxlength']) && intval($fieldattr['maxlength']) > 0) {
470  $FORM_VALIDATION_ERROR .= "<li>" . $App_SchemaDetail[$field_detailid]['fieldvalue'] . " has exceeded the max length of " . intval($fieldattr['maxlength']) . ".</li>";
471  }
472  } else {
473  // ** Max length not set.. sort of required for text input..
474  }
475 
476  }
477  // ** This field is entered.. Verify if it has an attribute of 'responsefield'
478  // * if so this value will be saved to that particular field
479  if (HCU_array_key_value('responsetablefield', $fieldattr) != '') {
480  $Custom_Resp_Field[$fieldattr['responsetablefield']] = $fieldval;
481  }
482  if (stripos(':P:H:L:', ':' . $App_SchemaDetail[$field_detailid]['fieldtype']. ':') === false) {
483  $App_SchemaFields[$fields_key] = $fieldval;
484  }
485  } else {
486  }
487 
488  // ** ONLY Add the VALUE if NOT P, H OR L
489  // * Page
490  // * Header
491  // * Label
492  // If field type is FOUND then do NOT include, if NOT FOUND then I assume this is a valid entry field
493  $FormPopulate[$fields_key] = $fieldval;
494  }
495 
496  $JSON_FormPopulate = json_encode($FormPopulate);
497  }
498 
499  // ** Otherwise, prepare all the posted fields for saving.
500  // ** Tasks
501  // ** INSERT INFORMATION into the userresponse table
502  // ** CAll the interface and retrieve the loan_app_id
503  $JSON_FormFields = json_encode($App_SchemaFields);
504  if ($FORM_VALIDATION_ERROR == "") {
505  if (intval($_POST['respid']) >= 0) {
506  // ** THIS WILL BE AN UPDATE
507  $sql = "UPDATE {$DB_TABLE_PREFIX}userresponse
508  SET
509  respamt = " . number_format(FormatDateForSubmit($Custom_Resp_Field['respamt'], "usd"), 2, ".", "") . ",
510  respcomments = '',
511  respmodifiedon = now(),
512  resplname = '". save_text(HCU_array_key_value('resplname', $Custom_Resp_Field), 55) . "',
513  respfname = '". save_text(HCU_array_key_value('respfname', $Custom_Resp_Field), 25) . "',
514  respmname = '". save_text(HCU_array_key_value('respmname', $Custom_Resp_Field), 25) . "',
515  respssn = '". save_text(HCU_array_key_value('respssn', $Custom_Resp_Field), 11) . "',
516  respdob = '". save_text(HCU_array_key_value('respdob', $Custom_Resp_Field), 10) . "',
517  respmember = '". save_text(HCU_array_key_value('respmember', $Custom_Resp_Field), 15) . "',
518  respphone = '". save_text(HCU_array_key_value('respphone', $Custom_Resp_Field), 15) . "',
519  respapplication = '". save_text($JSON_FormFields) . "'
520  WHERE respid = " . intval($_POST['respid']) . "
521  AND userid = " . intval($DMSAPP_CURRENTUSERID);
522 
523  $response_id = intval($_POST['respid']);
524  } else {
525  // ** Create inserted values..
526  //
527  $sql = "SELECT nextval('{$DB_TABLE_PREFIX}userresponse_respid_seq'::text) as responseid ";
528  $id_rs = db_query($sql, $dbh);
529  list($response_id) = db_fetch_array($id_rs);
530  db_free_result($id_rs);
531 
532  // ** This is a NEW INSERT --
533  $sql_respstatus = "0";
534  $sql = "INSERT INTO {$DB_TABLE_PREFIX}userresponse
535  (respid, userid, loanid, respstatus, respamt,
536  respcomments, respcoreloanappid, respstarton, respsubmiton,
537  respmodifiedon, resplname, respfname, respmname, respssn,
538  respdob, respmember, respphone, respapplication)
539  VALUES
540  ($response_id, $DMSAPP_CURRENTUSERID, $Master_LoanID, $sql_respstatus, " . number_format(FormatDateForSubmit(HCU_array_key_value('respamt', $Custom_Resp_Field), "usd"),2,".","") . ",
541  '', -1, now(), null, null, '". save_text(HCU_array_key_value('resplname', $Custom_Resp_Field), 55) . "', '" . save_text(HCU_array_key_value('respfname', $Custom_Resp_Field), 25) . "',
542  '". save_text(HCU_array_key_value('respmname', $Custom_Resp_Field), 25) . "', '". save_text(HCU_array_key_value('respssn', $Custom_Resp_Field), 11) . "',
543  '". save_text(HCU_array_key_value('respdob', $Custom_Resp_Field), 10) . "', '". save_text(HCU_array_key_value('respmember', $Custom_Resp_Field), 15) . "',
544  '". save_text(HCU_array_key_value('respphone', $Custom_Resp_Field), 10) . "', '" . save_text($JSON_FormFields) . "')";
545  }
546 
547  //'{$Custom_Resp_Field['respdob']}'
548  // print " Form to save<Br><br> $sql <br><br>";
549  if ($resp_rs = db_query($sql, $dbh)) {
550  // print "SUCCESS";
551  // ** Need to post the information to the core.. then records its responses
552  // * back to the database
553  /*
554  * Add a message that using the browsers back button will resubmit the loan application.
555  */
556  $submit_note = "<br/><br/><span class='submit-note'>WARNING: Usage of the browser's back button may result in additional applications being submitted.</span>";
557  if (isset($_POST['btnFormPost']) && $_POST['btnFormPost'] == 'Submit') {
558  //isset($_POST['btnSubmitNow'])) {
559  // ** SEND THE INFORMATION TO THE CORE...
560 
561  // ** For live, I will post to the core and record the response,
562  // ** For batch, I will simply save and send notices
563  list($app_submitted, $app_desc) = (SubmitApplication($HB_ENV, $response_id, $JSON_FormFields, HCU_array_key_value("respmember", $Custom_Resp_Field)));
564 
565  if ($app_submitted) {
566  // ** SUCCESS
567  // ** Go back to portal screen..
568  // ** NEed to pass along the description...
569  $app_desc = "Your application was sent to the credit union and returned with the following message:<br>$app_desc{$submit_note}";
570 
571  // Send an email to the CU informing them of the submitted application
572  // 06-19 note that "onldepnotify" does not refer to admin email notifications for online
573  // deposits. This key is only used for loan app submission notifications.
574  $sql = "SELECT email
575  FROM cuadmnotify
576  WHERE role = 'onldepnotify' AND cu = '$DMSAPP_CURRENTCUCODE' ";
577  $not_rs = db_query($sql, $dbh);
578  list($adm_email) = db_fetch_array($not_rs,0);
579  $adm_email = trim(preg_replace("/ +$/","",$adm_email));
580 
581  db_free_result($not_rs);
582 
583  /* ** NOTIFY NAME / MEMBER NBR ** */
584  $notifyName = trim($Custom_Resp_Field['respfname']) . " " . trim($Custom_Resp_Field['resplname']);
585  $notifyMbr = (trim($Custom_Resp_Field['respmember']) == '' ? '' : "\nMember Number: {$Custom_Resp_Field['respmember']}");
586 
587  if ($adm_email != "") {
588  $loanDescTitle = '';
589  if (array_key_exists('resploandesc', $Custom_Resp_Field)) {
590  $loanDescTitle = " (" . trim($Custom_Resp_Field['resploandesc']) . ")";
591  }
592  // ** PREPARE TO SEND THE MAIL
593  $mail_message = "";
594  $ATTN = "Online Loan Application{$loanDescTitle} from {$notifyName}";
595  $mail_message = "\t$Cu ONLINE LOAN APPLICATION\n\nA new online loan application was submitted to your home banking.\nLogin to admin to view.\n\nPrimary Applicant: {$notifyName}\n{$notifyMbr}\n";
596 
597 
598  $notify = new ErrorMail;
599  $notify->mailto=$adm_email; // Set to transfer email setup in CU Admin
600  $notify->replyto="nobody@homecu.com";
601  $notify->subject=$ATTN;
602  $notify->msgbody = $mail_message;
603  $notify->file = __FILE__;
604  $notify->cu = $Cu;
605  $notify->SendMail();
606 
607  }
608  // ** END of sending email
609  header("HTTP/1.1 303 See Other"); // Try setting the 303 response -- this directive should allow the redirect page to NOT be part of the history.. it is the preferred method for Post/Redirect/Get
610  header("Location: {$self}f=portal&msg=" . urlencode($app_desc));
611  exit;
612  } else {
613  // ** FAILURE
614  $app_desc = "Your application was sent to the credit union and returned with the following message:<br>$app_desc";
615 
616  $FORM_VALIDATION_ERROR = "<li>$app_desc</li>";
617  // header("Location: {$self}f=portal&msg=" . urlencode($app_desc));
618  // exit;
619  }
620 
621  /*
622  * THESE fields will be updated by post_application in throtlpkt.i
623  $sql = "UPDATE {$DB_TABLE_PREFIX}userresponse
624  SET respsubmiton = now(),
625  respstatus = '',
626  respcomments = ''
627  WHERE respid = $response_id ";
628  */
629  } else {
630  // ** FORM WAS SAVED FOR LATER
631  $app_msg = "Your application was successfully saved. At any time you may finish the application by using the 'Edit' option";
632  header("HTTP/1.1 303 See Other"); // Try setting the 303 response -- this directive should allow the redirect page to NOT be part of the history.. it is the preferred method for Post/Redirect/Get
633  header("Location: {$self}f=portal&msg=" . urlencode($app_msg));
634  exit;
635  }
636 
637  } else {
638  $FORM_VALIDATION_ERROR = "An unexpected error occurred while saving your application.";
639  }
640  } else {
641  // ** VALIDATION ERROR - RELOAD FORM
642  }
643  } else {
644  // ** ALLOW FORMS TO BE RELOADED
645 
646  if ($Master_LoanID > 0 && isset($app_row)) {
647 
648  // ** Load data
649  $JSON_FormPopulate = $app_row['respapplication'];
650  } elseif (HCU_array_key_exists('new', $loadedValues['lnappentry'])) {
651  if ($DMSAPP_ONLINE == "1" && $DMSAPP_MODE_ARY['offline'] && $DMSAPP_FETCHMIR == 1) {
652  // ** We want to try and load the MIR packet from the core
653  // ** If the app is ONLINE AND HomeBanking Login (H) or MIR Login (N)
654  // ** Need to get the account value from the lnappuser table
655 
656  $sql = "SELECT session_account
657  FROM {$DB_TABLE_PREFIX}user
658  WHERE (userlogintype = 'H' OR userlogintype = 'N')
659  AND userid = " . intval($DMSAPP_CURRENTUSERID) . " ";
660  $user_rs = db_query($sql, $dbh);
661  $user_row = db_fetch_assoc($user_rs, 0);
662  if ($user_row['session_account'] != '') {
663 
664  $member = $user_row['session_account'];
665 
666  $mirResp = GetMemberInfo($HB_ENV, array("member" => $member));
667 
668  $coreAutoFillInfo = Array();
669  if ($mirResp['code'] == '000') {
670 
671  // ** Data was found.
672  // ** Tranlate the key values from the keys Odyssey uses to the keys the Loan system uses
673 
674  $mirData = $mirResp['data'];
675 
676  foreach ($coreAutoFillFormat as $coreKey => $coreAttr) {
677  // ** Loop through each known mir value and set the value for usage later
678  $coreAutoFillInfo[$coreKey] = HCU_array_key_value($coreAttr['mir_key'], $mirData);
679  }
680 
681  /*
682  * FOR TESTING DEFAULT SSN to 000-00-0000 dob to 01/01/1984
683  *
684  $coreAutoFillInfo['SSN'] = '000-00-0001';
685  $coreAutoFillInfo['DOB'] = '01/01/1984';
686  *
687  */
688 
689  $defaultItemsFromCore = true;
690  }
691 
692  }
693 
694  }
695  }
696  }
697 
698  // ** Retrieve loan records - In order.. Now start displaying
699  // * information
700 
701 
702  // * some thoughts. If I can truly create the <div> tags how I envision,
703  // Then i should be able to create the menu div section as I go, then the
704  // style sheet can decide where to place this information
705  $PageTagOpen = False;
706  $GroupTagOpen = False;
707  $LineTagOpen = False;
708  $HoldLineOpen = False;
709 
710  $LAYOUT_PAGE = 1;
711  $LAYOUT_GROUP = 2;
712  $LAYOUT_LINE = 3;
713 
714  $CURRENT_LAYOUT = 0;
715  $PAGE_COUNT = 0;
716  $GROUP_COUNT = 0;
717 
718  // * This will be the left menu built on the left side for navigatino
719  $Build_CSS_Menu = "";
720 
721  // What is the bootstrap class used by a label
722  $inputLabelBsClass = " col-md-3 ";
723  // What is the bootstrap class used by the input field
724  $inputFieldBsClass = " col-md-9 ";
725  // Variable for full width input -- Doesn't have to be specified, could be used later programmatically
726  $inputBsFullWidth = " col-xs-12 ";
727 
728  // ** Loan Information
729  ?>
730  <style>
731 
732  #menu-items .local-menu-error {
733  display: none;
734  }
735  #menu-items .grouperror .local-menu-error {
736  color: #D80000;
737  margin-right: 10px;
738  display: inline-block;
739  }
740 
741  .k-datepicker.k-header .k-picker-wrap {
742  border: none;
743  }
744  .k-datepicker .k-picker-wrap .k-select .k-icon {
745  margin: -8px -8px 0;
746  }
747 
748  #linkBack {
749  margin-top: 6em;
750  }
751 
752  </style>
753  <?php
754  /**
755  * <!-- START OF HTML -->
756  */
757  print "<form id='appentry' name='appentry' action='{$self}f=Entry' method='post'>
758  <input type='hidden' name='respid' value='$App_RespID'>
759  <input type='hidden' name='loanid' value='$Master_LoanID'>
760  <input type='hidden' name='cookieval_$random' value='SET'>
761 
762  <div id='appcontent' class='container-fluid'>";
763  // while ($loan_row = db_fetch_array($loan_rs, $loan_idx++))
764  $form_build_required_list = ""; // * this is the required list that will be included on the form for when the user SUBMITS to the core
765  $form_build_mandatory_list = "";
766  $loop_required_list = ""; // * used locally in loop to place the required information in the correct variable
767  $AppCertifyStatement = ""; // This value will be loaded from the loan layout where the submitstatement is set to 1
768  foreach ($App_SchemaDetail as $Detail_key => $Detail_value) {
769 
770  $fieldtype = $Detail_value['fieldtype'];
771  $fieldvalue = disp_text($Detail_value['fieldvalue']);
772  // ** LOAD ThE JSON Object
773  $fieldattr = HCU_jsondecode($Detail_value['fieldattr'], false, false);
774 
775 
776  $formfieldname = "formfield_" . $Detail_key;
777 
778  $formconditionalname = "";
779 
780  $formfieldrequired = GetClassPropertyVal($fieldattr, 'validation_require') >= 1 ? "<em class='hcu-required-field'>*</em>" : "";
781  $formfieldegtext = "";
782  $formfieldhelpurl = "";
783 
784  /* *
785  * Assign the loop_required_list to the address of the appropriate list
786  *
787  * form_build_mandatory_list will contain a list of required fields that are ALWAYS required, event to save the loan for later
788  *
789  * form_build_required_list will contain a list of required fields that are ONLY required for submitting the loan
790  */
791  if (GetClassPropertyVal($fieldattr, 'validation_require') == 2) {
792  // ** use the mandatory list
793  $loop_required_list =& $form_build_mandatory_list;
794  } else {
795  // ** Default
796  $loop_required_list =& $form_build_required_list;
797  }
798 
799  // // ** Based on the Field type we will do differen things..
800  // if ($loan_row['fieldtype'] == "P") {
801  // // ** PAGE HEADER
802  // } elseif ($loan_row['fieldtype'] == "H") {
803  // // ** Section Header
804  // } elseif ($loan_row['fieldtype']
805  //print "WHILE LOOP - $loan_idx";
806  $field_class = "";
807  // if ($fieldattr->validation_require) {
808  // $form_build_required_list .= "$('#{$formfieldname}').require()\n";
809  // }
810 
811 
812  if (property_exists($fieldattr, 'append_class')) {
813  // * we are validating that it will match a certain type.. set the class info
814  $field_class .= $fieldattr->append_class;
815  }
816  if (property_exists($fieldattr, 'egtext')) {
817  $formfieldegtext = $fieldattr->egtext;
818  }
819  if (property_exists($fieldattr, 'helpurl')) {
820  // ** Create the help url link here
821  $formfieldhelpurl = "&nbsp;<a href='" . $fieldattr->helpurl->href . "' class='' target=_NEW>" . $fieldattr->helpurl->display . "</a>";
822  }
823 
824  if (GetClassPropertyVal($fieldattr, 'submitstatement') == 1) {
825  $AppCertifyStatement = GetClassPropertyVal($fieldattr, 'defaultval');
826  }
827 
828 
829  // Property MUST exist to continue
830  if (GetClassPropertyVal($fieldattr, 'autofillfromcore') !== false && HCU_array_key_exists(GetClassPropertyVal($fieldattr, 'autofillfromcore') , $coreAutoFillInfo) && $defaultItemsFromCore) {
831  $coreValue = '';
832  switch (HCU_array_key_value(GetClassPropertyVal($fieldattr, 'autofillfromcore') , $coreAutoFillInfo)) {
833  case "phone":
834  // ** Keep ONLY numeric values
835  $phone = preg_replace("/[^0-9 ]/", "", $coreAutoFillInfo[$fieldattr->autofillfromcore]);
836 
837  $coreValue = preg_replace("/([0-9]{3})([0-9]{3})([0-9]{4})/", "$1-$2-$3", $phone);
838  break;
839  case "zip":
840  $zip = preg_replace("/[^0-9 ]/", "", $coreAutoFillInfo[$fieldattr->autofillfromcore]);
841 
842  if (strlen($zip) > 5) {
843  $coreValue = preg_replace("/([0-9]{5})([0-9]{4})/", "$1-$2", $zip);
844  } else {
845  $coreValue = $zip;
846  }
847  break;
848  case "ssn":
849  $ssn = preg_replace("/[^0-9 ]/", "", $coreAutoFillInfo[$fieldattr->autofillfromcore]);
850 
851  $coreValue = preg_replace("/([0-9]{3})([0-9]{2})([0-9]{4})/", "$1-$2-$3", $ssn);
852 
853  break;
854  case "date":
855  // ** dates can be returned differently
856  //** MM/DD/YYYY
857  //** YYYYDDMM
858  $coreValue = date("m/d/Y", strtotime($coreAutoFillInfo[$fieldattr->autofillfromcore]));
859  break;
860  default:
861  $coreValue = $coreAutoFillInfo[$fieldattr->autofillfromcore];
862  break;
863  }
864 
865  // Found a default item
866  $valuesItemsFromCore['formfield_' . $Detail_key] = $coreValue;
867  }
868  // ** READONLY?
869  $fieldSetReadOnly = (intval(GetClassPropertyVal($fieldattr, 'readonly')) == 1 ? ' readonly ' : '');
870 
871  switch ($fieldtype) {
872  case "P":
873  // Page Header
874  // * Check to see if we need to Close any tags
875  $PAGE_COUNT++;
876 
877  StartDMSTag ($LAYOUT_PAGE, $PAGE_COUNT, $fieldvalue);
878  print "<h1 class='page-header'>$fieldvalue</h1>";
879  break;
880  case "H":
881  // Section Header
882 
883  $GROUP_COUNT++;
884  StartDMSTag($LAYOUT_GROUP, 0,$fieldvalue);
885  print "<legend>$fieldvalue</legend>";
886  break;
887  case "L":
888  // Label
889  if (GetClassPropertyVal($fieldattr, 'hidden') != 1) {
890 
891  print <<< APP_LABEL
892  <div class="form-group {$field_class}">
893  <!--<label class="{$inputLabelBsClass} control-label"></label>-->
894  <div class="{$inputBsFullWidth}">
895  <p class="form-control-static">$fieldvalue{$formfieldhelpurl}</p>
896  </div>
897  </div>
898 APP_LABEL;
899  }
900  break;
901  case "YNR":
902  case "YNR01":
903  $yesVal = ($fieldtype == "YNR01" ? "1" : "Y");
904  $noVal = ($fieldtype == "YNR01" ? "0" : "N");
905 
906  if (isset($fieldattr->hidden) && $fieldattr->hidden == 1) {
907  print "<input type='hidden' id='$formfieldname' group='group_{$GROUP_COUNT}' name='$formfieldname' value='" . GetClassPropertyVal($fieldattr, 'defaultval') . "'>";
908  } else {
909  // Yes/No Radio buttons
910  // radioChecked
911  StartDMSTag($LAYOUT_LINE);
912  if (GetClassPropertyVal($fieldattr, 'validation_require')) {
913  if (GetClassPropertyVal($fieldattr, 'validation_require_conditional') != '') {
914  // ** There is a conditional requirement for this to be required..
915  $loop_required_list .= "if (\$('input:radio[conditional=" . $fieldattr->validation_require_conditional->field . "]:checked').val()== '" . $fieldattr->validation_require_conditional->value . "') {\$(\"input[id='{$formfieldname}']\").radioNotChecked('', 'Yes/No reply is required.');}\n";
916  } else {
917 
918  $loop_required_list .= "$(\"input[id='{$formfieldname}']\").radioNotChecked('', 'Yes/No reply is required.');\n";
919  }
920  }
921 
922  if (GetClassPropertyVal($fieldattr, 'validation_conditionname') != '') {
923  $formconditionalname = " conditional='{$fieldattr->validation_conditionname}' ";
924  }
925 
926  print <<< APP_YNR
927  <div class="form-group {$field_class}">
928  <label for='$formfieldname' class="{$inputLabelBsClass} control-label $field_class">$fieldvalue $formfieldrequired</label>
929  <div class="{$inputFieldBsClass}">
930  <label class="radio-inline">
931  <input type='radio' group='group_{$GROUP_COUNT}' id='$formfieldname' name='$formfieldname' $formconditionalname value='$yesVal'/> Yes
932  </label>
933  <label class="radio-inline">
934  <input type='radio' id='$formfieldname' name='$formfieldname' $formconditionalname value='$noVal' title='$fieldvalue'/> No
935  </label>
936  <span id='error_$formfieldname' class=''></span>
937  <span>
938  {$formfieldhelpurl}
939  </span>
940  </div>
941  </div>
942 APP_YNR;
943 
944  }
945  break;
946  case "YNS":
947  case "YNS01":
948  $yesVal = ($fieldtype == "YNS01" ? "1" : "Y");
949  $noVal = ($fieldtype == "YNS01" ? "0" : "N");
950  // Yes/No Select Option
951 
952  if (GetClassPropertyVal($fieldattr, 'validation_require')) {
953  if (GetClassPropertyVal($fieldattr, 'validation_require_conditional') != '') {
954  // ** There is a conditional requirement for this to be required..
955  $loop_required_list .= "if (\$('input:radio[conditional=" . $fieldattr->validation_require_conditional->field . "]:checked').val()== '" . $fieldattr->validation_require_conditional->value . "') {\$('#{$formfieldname}').require();}\n";
956  } else {
957  $loop_required_list .= "$('#{$formfieldname}').require();\n";
958  }
959  }
960  if (GetClassPropertyVal($fieldattr, 'validation_conditionname') != '') {
961  $formconditionalname = " conditional='{$fieldattr->validation_conditionname}' ";
962  }
963 
964  $setInputMaskEntry .= "\n" . '$("#' . $formfieldname . '").kendoDropDownList();';
965 
966  StartDMSTag($LAYOUT_LINE);
967  print <<< YNS
968  <div class="form-group {$field_class}">
969  <label for='$formfieldname' class="{$inputLabelBsClass} control-label">$fieldvalue $formfieldrequired</label>
970  <div class="{$inputFieldBsClass}">
971  <select id='$formfieldname' $formconditionalname group='group_{$GROUP_COUNT}' name='$formfieldname' title='$fieldvalue' class='input-select-100'>
972  <option value=''></option>
973  <option value='$yesVal'>Yes</option>
974  <option value='$noVal'>No</option>
975  </select>
976  <span id='error_$formfieldname' class=''></span>
977  <span>
978  {$formfieldhelpurl}
979  </span>
980  </div>
981  </div>
982 YNS;
983  break;
984  case "GT":
985  $inputType = "text";
986  /**
987  * By default ALWAYS print the k-textbox class for the input
988  * However, for some masking elements this can cause unwanted double borders
989  * Remove the k-textbox by setting printKTextbox to false
990  */
991  $printKTextbox = true;
992  // General Text (Reg Input)
993  // ** validate changes based on the type of information we want
994  if (isset($fieldattr->hidden) && $fieldattr->hidden == 1) {
995  print "<input type='hidden' id='$formfieldname' group='group_{$GROUP_COUNT}' name='$formfieldname' value='" . GetClassPropertyVal($fieldattr, 'defaultval') . "'>";
996  } else {
997  StartDMSTag($LAYOUT_LINE);
998  if (GetClassPropertyVal($fieldattr, 'validation_match')) {
999  /*
1000  * Kendo maxskedTextBox has an issue if the maxlength of the original field is set and is the length of the mask.
1001  * If a mask is set, then set maxlength to <empty>
1002  */
1003 
1004  // * we are validating that it will match a certain type.. set the class info
1005  $field_class .= " " . $fieldattr->validation_match;
1006  if (GetClassPropertyVal($fieldattr, 'validation_match') === 'date') {
1007  /*
1008  * 6/12/2018 - For now use the html5 date entry field. It does what we need. Looks decent.
1009  *
1010  * Using simple mask for date - the dateinput widget does not have smooth data entry from one segment to the next *
1011  //
1012  //$setInputMaskEntry .= "\n" . '$("#' . $formfieldname . '").kendoMaskedTextBox({mask:"##/##/####"});';
1013  */
1014  /*
1015  * Technically the double kendo widget create a slight issue, but the user experience is slightly better.
1016  * Added styles in form to remove the double input border (k-picker-wrap).
1017  * The validity-erroneous creates a border around the inner input field rather than the outer field.
1018  */
1019  $setInputMaskEntry .= "\n" . '$("#' . $formfieldname . '").kendoDatePicker({format:"MM/dd/yyyy"});';
1020  $setInputMaskEntry .= "\n" . '$("#' . $formfieldname . '").kendoMaskedTextBox({mask: "00/00/0000",promptChar: "_"});';
1021  $fieldattr->maxlength = '';
1022  //$inputType = "date";
1023  } elseif (GetClassPropertyVal($fieldattr, 'validation_match') === 'phone') {
1024  $setInputMaskEntry .= "\n" . '$("#' . $formfieldname . '").kendoMaskedTextBox({mask:"###-###-####"});';
1025  $fieldattr->maxlength = '';
1026  $inputType = "phone";
1027  } elseif (GetClassPropertyVal($fieldattr, 'validation_match') === 'ssn') {
1028  $setInputMaskEntry .= "\n" . '$("#' . $formfieldname . '").kendoMaskedTextBox({mask:"###-##-####"});';
1029  $fieldattr->maxlength = '';
1030  $inputType = "ssn";
1031  } elseif (GetClassPropertyVal($fieldattr, 'validation_match') === 'usd' || GetClassPropertyVal($fieldattr, 'validation_match') === 'number') {
1032  $printKTextbox = false;
1033  $inputFmt = "#";
1034  $inputType = "number";
1035  if (GetClassPropertyVal($fieldattr, 'validation_match') === 'usd') {
1036  $inputFmt = "c2";
1037  }
1038 
1039  $widgetConfigOptions = '';
1040 
1041  // ** For usd or number, check to see if they have a range limit
1042  if (GetClassPropertyVal($fieldattr, 'validation_require_numeric_range_chk')) {
1043  if (GetClassPropertyVal($fieldattr, 'validation_require_numeric_range_chk') == 1) {
1044  // ** Either a min or max is set -- Determine what the values are and set the validity command
1045  if (GetClassPropertyVal($fieldattr, 'validation_require_numeric_range')) {
1046  if (GetClassPropertyVal($fieldattr->validation_require_numeric_range, 'min')) {
1047  $value = $fieldattr->validation_require_numeric_range->min;
1048  if ($value > 0) {
1049  $widgetConfigOptions .= "min: $value,";
1050  }
1051  }
1052  if (GetClassPropertyVal($fieldattr->validation_require_numeric_range, 'max')) {
1053  $value = $fieldattr->validation_require_numeric_range->max;
1054  if ($value > 0) {
1055  $widgetConfigOptions .= "max: $value,";
1056  }
1057  }
1058  }
1059  }
1060  }
1061 
1062  $setInputMaskEntry .= "\n" . '$("#' . $formfieldname . '").kendoNumericTextBox({format:"' . $inputFmt . '",spinners: false, ' . $widgetConfigOptions . '});';
1063 
1064  }
1065  }
1066 
1067  if (GetClassPropertyVal($fieldattr, 'validation_require')) {
1068  if (GetClassPropertyVal($fieldattr, 'validation_require_conditional') != '') {
1069  // ** There is a conditional requirement for this to be required..
1070  $loop_required_list .= "if (\$('input:radio[conditional=" . GetClassPropertyVal($fieldattr->validation_require_conditional, 'field') . "]:checked').val()== '" . GetClassPropertyVal($fieldattr->validation_require_conditional, 'value') . "') {\$('#{$formfieldname}').require();}\n";
1071  } else {
1072  // ** Field is ALWAYS required
1073  $loop_required_list .= "$('#{$formfieldname}').require();\n";
1074  }
1075  }
1076  $localDefVal = GetClassPropertyVal($fieldattr, 'defaultval');
1077 
1078  $printMaxLength = GetClassPropertyVal($fieldattr, 'maxlength');
1079  $printEgText =($formfieldegtext != '' ? $formfieldegtext : '');
1080 
1081  $kTextboxOut = ($printKTextbox ? "k-textbox" : "");
1082  print <<< APP_GENERAL
1083  <div class="form-group {$field_class}">
1084  <label class='{$inputLabelBsClass} control-label' for='$formfieldname'>$fieldvalue $formfieldrequired</label>
1085  <div class="{$inputFieldBsClass}">
1086  <input type='{$inputType}' id='$formfieldname' group='group_{$GROUP_COUNT}' name='$formfieldname' class='$kTextboxOut hcu-all-100 $field_class' value='{$localDefVal}'
1087  maxlength='{$printMaxLength}' $fieldSetReadOnly title='$fieldvalue' data-toggle='tooltip' data-placement='right' placeholder='$printEgText' novalidate>
1088  {$formfieldhelpurl}
1089  <span id='error_$formfieldname' class=''></span>
1090  </div>
1091  </div>
1092 APP_GENERAL;
1093  }
1094  break;
1095  case "CB":
1096  // ** Create a checkbox
1097  $localDefVal = GetClassPropertyVal($fieldattr, 'defaultval');
1098  if (isset($fieldattr->hidden) && $fieldattr->hidden == 1) {
1099  // *IF this field is HIDDEN, then simply create a hidden field with the value specified
1100  print "<input type='hidden' id='$formfieldname' group='group_{$GROUP_COUNT}' name='$formfieldname' value='{$fieldattr->defaultval}'>";
1101  } else {
1102  StartDMSTag($LAYOUT_LINE);
1103 
1104  if (GetClassPropertyVal($fieldattr, 'validation_require')) {
1105  if (GetClassPropertyVal($fieldattr, 'validation_require_conditional') != '') {
1106 
1107  // ** There is a conditional requirement for this to be required..
1108  $loop_required_list .= "if (\$('input:radio[conditional=" . $fieldattr->validation_require_conditional->field . "]:checked').val()== '" . $fieldattr->validation_require_conditional->value . "') {\$('#{$formfieldname}').checkboxChecked('', 'Confirm $formfieldname');}\n";
1109  } else {
1110 $loop_required_list .= "$('#{$formfieldname}').checkboxChecked('', 'Confirm $formfieldname');\n";
1111  }
1112  }
1113 
1114  print <<< APP_CB
1115  <div class="form-group {$field_class}">
1116  <label for='$formfieldname' class="{$inputLabelBsClass} control-label $field_class">$fieldvalue $formfieldrequired</label>
1117  <div class="{$inputFieldBsClass}">
1118  <label class="checkbox-inline">
1119  <input type='checkbox' id='$formfieldname' group='group_{$GROUP_COUNT}' name='$formfieldname' class='$field_class' value='{$localDefVal}' title='$fieldvalue' /> &nbsp;
1120  </label>
1121  <label class="checkbox-inline">
1122  {$formfieldhelpurl}
1123  </label>
1124  <span id='error_$formfieldname' class=''></span>
1125  </div>
1126  </div>
1127 APP_CB;
1128 
1129  }
1130 
1131  break;
1132  case "AS":
1133  // Answer Lookup (Select Display)
1134  StartDMSTag($LAYOUT_LINE);
1135  if (GetClassPropertyVal($fieldattr, 'validation_require')) {
1136  if (GetClassPropertyVal($fieldattr, 'validation_require_conditional') != '') {
1137  // ** There is a conditional requirement for this to be required..
1138  $loop_required_list .= "if (\$('input:radio[conditional=" . GetClassPropertyVal($fieldattr->validation_require_conditional, 'field') . "]:checked').val()== '" . GetClassPropertyVal($fieldattr->validation_require_conditional, 'field') . "') {\$('#{$formfieldname}').require();}\n";
1139  } else {
1140  $loop_required_list .= "$('#{$formfieldname}').require();\n";
1141  }
1142  }
1143  if (GetClassPropertyVal($fieldattr, 'validation_conditionname') != '') {
1144  $formconditionalname = " conditional='" . GetClassPropertyVal($fieldattr, 'validation_conditionname') . "' ";
1145  }
1146 
1147 
1148  print <<< PRINT_SCRIPT
1149  <div class="form-group {$field_class}">
1150  <label for='$formfieldname' class="{$inputLabelBsClass} control-label $field_class">$fieldvalue $formfieldrequired</label>
1151  <div class="{$inputFieldBsClass}">
1152 PRINT_SCRIPT;
1153  print Display_AnswerList($fieldattr->fieldansid, $formfieldname, "S", $fieldvalue, '', (isset($fieldattr->defaultval) ? $fieldattr->defaultval : ''), $formconditionalname, $field_class);
1154  print <<< PRINT_SCRIPT
1155  <span>
1156  {$formfieldhelpurl}
1157  </span>
1158  </div>
1159  </div>
1160  <script>
1161  $(document).ready(function() {
1162  $("#{$formfieldname}").kendoDropDownList();
1163  });
1164  </script>
1165 PRINT_SCRIPT;
1166 
1167  break;
1168  case "AR":
1169 
1170  // Answer Lookup (Radio Option)
1171  StartDMSTag($LAYOUT_LINE);
1172  if (GetClassPropertyVal($fieldattr, 'validation_require')) {
1173  $tFieldLabel = ($fieldvalue != '' ? $fieldvalue : 'Answer');
1174  if (GetClassPropertyVal($fieldattr, 'validation_require_conditional') != '') {
1175  // ** There is a conditional requirement for this to be required..
1176  //$form_build_required_list .= "if ($('input[conditional='" . $fieldattr->validation_require_conditional->field . "']') == " . $fieldattr->validation_require_conditional->value . ") {\$('#{$formfieldname}').require();\}\n";
1177  $loop_required_list .= "if (\$('input:radio[conditional=" . $fieldattr->validation_require_conditional->field . "]:checked').val()== '" . $fieldattr->validation_require_conditional->value . "') {\$(\"input[id='{$formfieldname}']\").radioNotChecked('', '{$tFieldLabel} is required.');}\n";
1178  } else {
1179  $loop_required_list .= "$(\"input[id='{$formfieldname}']\").radioNotChecked('', '{$tFieldLabel} is required.');\n";
1180  }
1181 
1182  }
1183  if (GetClassPropertyVal($fieldattr, 'validation_conditionname') != '') {
1184  $formconditionalname = " conditional='{$fieldattr->validation_conditionname}' ";
1185  }
1186  $radioOptions = Display_AnswerList($fieldattr->fieldansid, $formfieldname, "R", $fieldvalue, '', '', $formconditionalname);
1187  print <<< APP_AR
1188  <div class="form-group {$field_class}">
1189  <label for='$formfieldname' class="{$inputLabelBsClass} control-label $field_class">$fieldvalue $formfieldrequired</label>
1190  <div class="{$inputFieldBsClass}">
1191  {$radioOptions}
1192  <span id='error_$formfieldname' class=''></span>
1193  <span>
1194  {$formfieldhelpurl}
1195  </span>
1196  </div>
1197  </div>
1198 APP_AR;
1199  break;
1200  default:
1201  }
1202 
1203  //StartDMSElement??
1204  //CloseDMSElement???
1205 
1206 
1207 
1208  }
1209  // ** -- Close the TAG??
1210  StartDMSTag($LAYOUT_PAGE, -1); // * This should close all the tags left open
1211 
1212  // Check if we recieved error, and need button back to menu
1213 
1214  if ($FORM_VALIDATION_ERROR != '' && (isset($app_row['respsubmiton']) && $app_row['respsubmiton'] != '')) {
1215  print <<< print_back
1216 
1217  <div class="container">
1218  <div class="row">
1219  <div class="col-xs-12 col-sm-6 col-md-4">
1220  <input type="button" class="k-button k-primary hcu-all-100" id='linkBack' value="Back" onclick="window.history.back()"></input>
1221  </div>
1222  </div>
1223  </div>
1224 print_back;
1225  } else {
1226 
1227  // ** CHECK to see if a disclosure exists -- If it does I want to add a link
1228  // * To review the disclosure
1229  $link_disclosure = '';
1230  if (Disclosure_Exists($Master_LoanID, -1)) {
1231  $link_disclosure = "<li class='list_nostyle'><a target='_NEW' href='{$self_full_url}?f=viewdisclosure&review={$Master_LoanID}'><i class='fa fa-file-text-o'></i> Review Disclosure</a></li><br>";
1232  }
1233  $AppCertifyStatement = ($AppCertifyStatement != '' ? "<br/>" . $AppCertifyStatement . "<br/>": "");
1234 
1235  print <<< print_submit
1236  <div class="row">
1237  <div class="col-xs-12 col-sm-6 col-md-4">
1238  <button class="k-button hcu-all-100" hrefx="#" id='btnNavPrev'><i class="fa fa-caret-left fa-2x" aria-hidden="true"></i><span class=" x-hidden-xs">&nbsp;<span id='btnSpanPrev'>Previous</span></span></button>
1239  </div>
1240  <div class="col-xs-12 col-sm-6 col-md-offset-4 col-md-4 x-col-xs-offset-4 text-right">
1241  <button class="k-button hcu-all-100" hrefx="#" id='btnNavNext'><span class="x-hidden-xs"><span id='btnSpanNext'>Next</span>&nbsp;</span></span><i class="fa fa-caret-right fa-2x" aria-hidden="true"></i></button>
1242  </div>
1243  </div>
1244 
1245  <div class="row">
1246  <div class="hidden-xs col-sm-12">
1247  <div class="control-group"><br/><br/></div>
1248  </div>
1249  </div>
1250 
1251  <div class="row">
1252  <div class="col-xs-12">
1253  <p class='h4'>Would you like to save this application and continue at a later time?</p>
1254  </div>
1255  </div>
1256  <div class="row">
1257  <div class="col-xs-12 col-sm-6 col-md-4">
1258  <input class="k-button hcu-all-100" href="#" id='linkFormPost' label='Save' value='Save For Later'></input>
1259  </div>
1260  </div>
1261 
1262  <div class="row">
1263  <div class="hidden-xs col-sm-12">
1264  <div class="control-group"><br/><br/></div>
1265  </div>
1266  </div>
1267 
1268  <div class="row">
1269  <div class="col-xs-12">
1270  <p class='h4'>Is your application complete and ready to be submitted to the credit union?</p>
1271  </div>
1272  </div>
1273 
1274  <div class="row">
1275  <div class="col-xs-12">
1276  $link_disclosure
1277  </div>
1278  </div>
1279  <div class="row">
1280  <div class="col-xs-12">
1281  <p class='h4'><span style='font-size:0.85em;'>{$AppCertifyStatement}</span></p>
1282  </div>
1283  </div>
1284  <div class="row">
1285  <div class="col-xs-12 col-sm-6 col-md-4">
1286  <input type="button" class="k-button k-primary hcu-all-100" href="#" id='linkFormPost' label='Submit' value="Submit Now"></input>
1287  </div>
1288  </div>
1289 
1290 print_submit;
1291  }
1292  print "</div>";
1293  if ($Build_CSS_Menu != '') {
1294  // SETUP AND print the left menu
1295  $Build_CSS_Menu = "
1296  <ul id='list-menu' class='nav root-nav-categories'>
1297  $Build_CSS_Menu
1298  </ul>";
1299  }
1300 
1301 ?>
1302 
1303  <div id="menu-items" style="display:none;">
1304  <?php echo $Build_CSS_Menu; ?>
1305  </div>
1306 
1307  <script>
1308  $(document).ready(function() {
1309 
1310  $('#sidebar-nav').append($('#menu-items'));
1311  $('#menu-items').show();
1312  });
1313  </script>
1314 
1315 <?php
1316 
1317  // ** put any preloaded information here.. it should be in json format..
1318  // ** do some checking
1319  if ($defaultItemsFromCore && count($valuesItemsFromCore) > 0) {
1320  $JSON_FormPopulate = json_encode($valuesItemsFromCore);
1321  }
1322  if (isset($JSON_FormPopulate) && $JSON_FormPopulate != '' ) {
1323  print <<< json_load
1324  <script language="javascript">
1325 
1326  $('#appentry').populate($JSON_FormPopulate);
1327 
1328  </script>
1329 json_load;
1330  }
1331  /**
1332  * <!-- END OF HTML -->
1333  */
1334  print "<input type='hidden' id='form_currentpage' name='form_currentpage' value='1'>";
1335  print "<input type='hidden' id='form_pagecount' name='form_pagecount' value='$PAGE_COUNT'>";
1336  print "<input type='hidden' id='btnFormPost' name='btnFormPost' value=''>";
1337  print "</form>";
1338 
1339 
1340 ?>
1341  <script type='text/javascript'>
1342  /* ** JAVASCRIPT VARIABLE DECLARATIONS ** */
1343  var pghdr_title = "";
1344  var target=null;
1345  var lastGroupGo = "";
1346  var lastSecurePage = "";
1347 
1348  /* ** VALIDITY DEFAULTS ** */
1349  var
1350  // Container contains the summary. This is the element that is shown or hidden.
1351  container = ".validity-summary-container",
1352 
1353  // Erroneous refers to an input with an invalid value,
1354  // not the error message itself.
1355  erroneous = "validity-erroneous",
1356 
1357  // Selector for erroneous inputs.
1358  errors = "." + erroneous,
1359 
1360  // The wrapper for entries in the summary.
1361  wrapper = "<li/>",
1362 
1363  // Buffer to contain all the error messages that build up during validation.
1364  // When validation ends, it'll be flushed into the summary.
1365  // This way, the summary doesn't flicker empty then fill up.
1366  buffer = [];
1367 
1368 
1369  /* **
1370  **
1371  **
1372  **
1373  ** */
1374  /* SET FIRST PAGE */
1375  window.onload = function FormOnLoad() {
1376  var vid_id = $("#securepage1");
1377  $('div[id^="securepage"]').hide();
1378  $(vid_id).show();
1379  AssignNavButton();
1380  };
1381 
1382  $(document).ready(function() {
1383 
1384  <?php // Library javascript functions
1385  getShowWaitFunctions(); ?>
1386 
1387  /* ** PAGINATION ** */
1388 
1389  /* ** ASIDE MENU CLICK ** */
1390  $('a[id^="page"]').click(function(event){
1391  // MWS DEBUG console.log("------- START PAGE CHANGE ----");
1392  var newTop = 0;
1393  event.preventDefault();
1394  var vid_id = $(this).attr("id").replace("page", "#securepage");
1395  var vid_html = $(this).attr("href").replace("#", "");
1396 
1397  var $contentContainer = null;
1398  if ($('#hcu-nav-toggle').css('display') !== 'none') {
1399  $contentContainer = $('#content-wrapper');
1400  } else {
1401  $contentContainer = $('#homecu-container');
1402  }
1403 
1404  $('div[id^="securepage"]').hide();
1405  $(vid_id).show();
1406  $contentContainer.scrollTop(0);
1407 
1408  $('#form_currentpage').val($(this).attr("id").replace("page", ""));
1409 
1410  if ($('.' + vid_html).length) {
1411  // MWS DEBUG console.log("GroupGo Found --- Set new top");
1412  // MWS DEBUG console.log(vid_html + " " + $('.' + vid_html).offset().top);
1413  newTop = $('.' + vid_html).offset().top;
1414  }
1415 
1416  // MWS DEBUG console.log("homecu-container Before: " + $('#homecu-container').scrollTop());
1417  // MWS DEBUG console.log ("Same Page :: " + vid_id + " :: " + lastSecurePage);
1418  if (vid_id == lastSecurePage && lastSecurePage != '') {
1419  // MWS DEBUG console.log('Same Page set scroll + offset');
1420  $contentContainer.scrollTop($contentContainer.scrollTop() + newTop);
1421  } else {
1422  // MWS DEBUG console.log('New Page set scrolltop to ' + newTop);
1423  $contentContainer.scrollTop(newTop);
1424 
1425  }
1426  // MWS DEBUG console.log("homecu-container After: " + $('#homecu-container').scrollTop());
1427 
1428 
1429  lastSecurePage = vid_id;
1430  lastGroupGo = vid_html;
1431  // MWS DEBUG console.log("------- END PAGE CHANGE ----");
1432 
1433  $('#body-wrapper').removeClass('collapse');
1434  $('#body-wrapper').removeClass('in');
1435 
1436  RefreshCookie();
1437 
1438  AssignNavButton();
1439  });
1440 
1441  /* ** PAGE BUTTON PRESS ** */
1442  $('button[id^=btnNav]').click(function(event) {
1443  event.preventDefault();
1444  target = $(this).html();
1445 
1446  var new_pg = Number($('#form_currentpage').val());
1447  if (this.id.match(/Next/)) {
1448  // if (target.match(/>Next/)) {
1449  new_pg = Number($('#form_currentpage').val()) + 1;
1450  // } else if (target.match(/>Prev/)) {
1451  } else if (this.id.match(/Prev/)) {
1452  new_pg = Number($('#form_currentpage').val()) - 1;
1453  }
1454 
1455  if (new_pg != $('#form_currentpage').val()) {
1456  $('div[id^="securepage"]').hide();
1457  $('#securepage' + new_pg).show();
1458 
1459  $('#form_currentpage').val(new_pg);
1460 
1461  AssignNavButton();
1462  }
1463  });
1464 
1465 
1466  /* ** CONFIGURE VALIDITY ** */
1467  $.validity.outputs.custom = {
1468  cssClass:"error",
1469 
1470  start:function() {
1471  // Remove all the existing error labels.
1472  $("." + $.validity.settings.cssClass)
1473  .remove();
1474 
1475  // ** Reset container errors
1476  $(errors).removeClass(erroneous);
1477  buffer = [];
1478  // ** reset Link Arrow Errors
1479  $('li[id ^= "group"]').removeClass('grouperror');
1480  $('span[id ^= "error_formfield"]').removeClass('error');
1481  $('span[id ^= "error_formfield"]').hide();
1482 
1483  },
1484 
1485  end:function(results) {
1486  // If not valid and scrollTo is enabled, scroll the page to the first error.
1487  if (!results.valid && $.validity.settings.scrollTo) {
1488  location.hash = $("." + $.validity.outputs.custom.cssClass + ":eq(0)").attr('for');
1489  }
1490  // ** SET the container to view Errors
1491  // If there are any errors at all:
1492  // (Otherwise the container shouldn't be shown):
1493  if (buffer.length) {
1494  // Use integer based iteration for solution to Issue 7.
1495 
1496  // * Use Validator message to show summary
1497  $.homecuValidator.displayMessage(buffer, $.homecuValidator.settings.statusError);
1498 
1499  // If scrollTo is enabled, scroll the page to the first error.
1500  if ($.validity.settings.scrollTo) {
1501  location.hash = $(errors + ":eq(0)").attr("id");
1502  }
1503  }
1504  },
1505 
1506  raise:function($obj, msg) {
1507 
1508  // ** Return if the id and name is blank
1509  if ($obj.attr('id') !== undefined || $obj.attr('name') !== undefined) {
1510  var labelSelector = "#error_" + getIdentifier($obj);
1511  }
1512  var field_msg = "";
1513  var re = new RegExp('is required.\$');
1514  if (msg.match(re)) {
1515  field_msg = "Required";
1516  } else {
1517  field_msg = msg;
1518  }
1519  field_msg = '<i class="fa fa-exclamation-triangle" aria-hidden="true"></i>&nbsp;' + field_msg;
1520  // If an error label already exists for the bad input just update its text:
1521  if ($(labelSelector).length) {
1522  //$(labelSelector).text(field_msg);
1523  // * Use html function to allow font awesome icon
1524  $(labelSelector).html(field_msg);
1525 
1526  $(labelSelector).addClass('error');
1527  $(labelSelector).show();
1528  }
1529 
1530  // Otherwize create a new one and stick it after the input:
1531  else {
1532 
1533  labelSelector = "." + $.validity.outputs.custom.cssClass + "[for='" + getIdentifier($obj) + "']";
1534  $("<label/>")
1535  .attr("for", "error_" + getIdentifier($obj))
1536  .attr("id", "error_" + getIdentifier($obj))
1537  .addClass($.validity.outputs.custom.cssClass)
1538  .html(field_msg)
1539  // .text(field_msg)
1540 
1541  // In the case that the element does not have an id
1542  // then the for attribute in the label will not cause
1543  // clicking the label to focus the element. This line
1544  // will make that happen.
1545  .click(function() {
1546  if ($obj.length) {
1547  $obj[0].select();
1548  }
1549  })
1550 
1551  .insertAfter($obj);
1552  //.appendTo($obj);
1553  }
1554 
1555  // ** Prepare the container information -- add message to the buffer of messages
1556  buffer.push(msg);
1557 
1558  /*
1559  * Add the erroneous class to the input -- Some elements may put this on alternate location
1560  */
1561  if ($obj.attr('data-role') === 'numerictextbox') {
1562  if ($obj.parent().parent('.k-numerictextbox').length > 0) {
1563  $obj.parent().parent('.k-numerictextbox').addClass(erroneous);
1564  } else {
1565  $obj.addClass(erroneous);
1566  }
1567  } else if ($obj.attr('data-role') === 'dropdownlist') {
1568  if ($obj.parent('.k-dropdown').children('.k-dropdown-wrap').length > 0) {
1569  $obj.parent('.k-dropdown').children('.k-dropdown-wrap').addClass(erroneous);
1570  } else {
1571  $obj.addClass(erroneous);
1572  }
1573  } else if ($obj.attr('data-role') === 'maskedtextbox') {
1574  if ($obj.parent().parent('.k-maskedtextbox').length > 0) {
1575  $obj.parent().parent('.k-maskedtextbox').addClass(erroneous);
1576  } else {
1577  $obj.addClass(erroneous);
1578  }
1579  } else {
1580  /*
1581  * DEFAULT error class
1582  */
1583  $obj.addClass(erroneous);
1584  }
1585  // ** Add arrow to the group link
1586  var field_attr = $obj.attr("group");
1587  // Find the object and add class of grouperror
1588  $('#' + field_attr).addClass('grouperror');
1589  },
1590 
1591  raiseAggregate:function($obj, msg) {
1592  // Just raise the error on the last input.
1593  this.raise($obj, msg);
1594  },
1595  container:function() {
1596 
1597  }
1598  };
1599 
1600  /* ** SETUP VALIDITY ** */
1601  $.validity.setup({ outputMode:'custom' });
1602 
1603  /*
1604  **
1605  ** SET FORM VALIDATION **
1606  **
1607  */
1608  $("#appentry").validity(function() {
1609 
1610  <?php echo $setExtraValidityCmds; ?>
1611 
1612  $('input.date').match('date', '#{field} is not a valid date ##/##/####.');
1613  $('input.ssn').match(/^\d{3}-\d{2}-\d{4}$/, "#{field} needs to be in the format of ###-##-####.");
1614  $('input.phone').match('phone', '#{field} must be formatted as ###-###-####.');
1615  $('input.email').match('email', '#{field} must be formatted as an email.');
1616  $('input.integer').match('integer', "#{field} must be a positive, whole number.");
1617  $('input.usd').match('usd', "#{field} must be formatted as a US Dollar amount.");
1618  $('input.url').match('url', "#{field} must be formatted as a URL.");
1619  $('input.number').match('number', "#{field} must be formatted as a number.");
1620  $('input.zip').match('zip', "#{field} must be formatted as a zipcode ##### or #####-####.");
1621 
1622 
1623  if (target == 'Submit') {
1624  <?php echo $form_build_required_list; ?>
1625  }
1626 
1627  <?php echo $form_build_mandatory_list; ?>
1628  });
1629 
1630  /* **
1631  *
1632  * INPUT MASK
1633  *
1634  */
1635  <?php echo $setInputMaskEntry; ?>
1636 
1637 
1638  /* ** CLEAR VALIDATION ERRORS ** */
1639  $("input[type='text'],input[type='phone'],input[type='ssn'],input[type='date']").change( function() {
1640 
1641  // ** RESET ANY CURRENT ERRORS
1642  var erroneous = "validity-erroneous",
1643  errors = "." + erroneous;
1644 
1645  var cur_elem_name = $(this).attr('name');
1646  if (cur_elem_name != '') {
1647  // ** Clear the error information for THIS field ONLY
1648  // ** REMOVE THE LABEL FIELD
1649  $('#error_' + cur_elem_name).removeClass('error');
1650  $('#error_' + cur_elem_name).hide();
1651  // ** REMOVE THE Error Class turning the field RED
1652 
1653 
1654  /*
1655  * Special handling section for properly setting the
1656  * erroneous class for more complicated input fields
1657  */
1658  /* numerictextbox */
1659  if ($(this).attr('data-role') === 'numerictextbox') {
1660  if ($(this).parent().parent('.k-numerictextbox').length > 0) {
1661  $(this).parent().parent('.k-numerictextbox').removeClass(erroneous);
1662  }
1663  } else {
1664 
1665  $(this).removeClass(erroneous);
1666  }
1667  }
1668  // ** ONLY REMOVE CLASS FOR CURRENT ITEM
1669  // $("." + \$.validity.settings.cssClass).remove();
1670  // $('li[id ^= "group"]').removeClass('grouperror');
1671  // $(errors).removeClass(erroneous);
1672  // $('span[id ^= "error_formfield"]').removeClass('error');
1673  // $('span[id ^= "error_formfield"]').hide();
1674 
1675 
1676 
1677  $('input.date').match('date', 'Invalid Format');
1678  $('input.ssn').match(/^\d{3}-\d{2}-\d{4}\$/, "Invalid Format");
1679  $('input.phone').match('phone', 'Invalid Format');
1680  $('input.email').match('email', 'Invalid Format');
1681  $('input.integer').match('integer', "Number Expected");
1682  $('input.usd').match('usd', "Dollar Amount Expected");
1683  $('input.url').match('url', "Invalid Format");
1684  $('input.number').match('number', "Invalid Format");
1685  $('input.zip').match('zip', "Invalid Format");
1686  });
1687 
1688  /* ** BUTTON CLICKS ** */
1689 
1690  $('a[id^=btnNav]').click(function() {
1691  RefreshCookie();
1692  });
1693 
1694  $('input[id^=linkFormPost]').click(function() {
1695 
1696  showWaitWindow();
1697 
1698  // ** Reduce double click on button
1699  $(this).attr("disabled", "disabled");
1700 
1701  // ** Set the target for proper validation
1702  target = $(this).attr("label");
1703 
1704  $('#btnFormPost').val(target);
1705 
1706  $("#appentry").submit();
1707 
1708  $(this).removeAttr("disabled");
1709 
1710  hideWaitWindow();
1711  });
1712 
1713 
1714  /* FORM ERRORS */
1715  <?php if ($FORM_VALIDATION_ERROR != '') { ?>
1716  $.homecuValidator.displayMessage('<?php echo addslashes($FORM_VALIDATION_ERROR); ?>', $.homecuValidator.settings.statusError);
1717  <?php } ?>
1718  });
1719 
1720 
1721  /*
1722  **
1723  ** JAVASCRIPT FUNCTION DECLARATIONS
1724  **
1725  ** */
1726  function AssignNavButton() {
1727  var cur_pg = $('#form_currentpage').val();
1728  var pg_cnt = $('#form_pagecount').val()
1729 
1730  if ( cur_pg == 1) {
1731  // ** Do not show the Previous Button
1732  $('#btnNavPrev').hide();
1733  $('#btnNavNext').show();
1734 
1735  pghdr_title = "pghdr_" + Number(Number(cur_pg) + 1);
1736 
1737  $('#btnSpanNext').html('' + $('div[id^=' + pghdr_title + ']').attr("title"));
1738  } else if (cur_pg < pg_cnt) {
1739  // ** Do not show the Previous Button
1740  $('#btnNavPrev').show();
1741  pghdr_title = "pghdr_" + Number(Number(cur_pg) - 1);
1742  $('#btnSpanPrev').html('' + $('div[id^=' + pghdr_title + ']').attr("title"));
1743 
1744  $('#btnNavNext').show();
1745  pghdr_title = "pghdr_" + Number(Number(cur_pg) + 1);
1746 
1747  $('#btnSpanNext').html('' + $('div[id^=' + pghdr_title + ']').attr("title"));
1748  } else if (cur_pg == pg_cnt) {
1749  $('#btnNavPrev').show();
1750  pghdr_title = "pghdr_" + Number(Number(cur_pg) - 1);
1751  $('#btnSpanPrev').html('' + $('div[id^=' + pghdr_title + ']').attr("title"));
1752 
1753  $('#btnNavNext').hide();
1754  } else {
1755  $('#btnNavPrev').show();
1756  $('#btnNavNext').show();
1757  pghdr_title = "pghdr_" + Number(Number(cur_pg) - 1);
1758  $('#btnSpanPrev').html('' + $('div[id^=' + pghdr_title + ']').attr("title"));
1759 
1760  pghdr_title = "pghdr_" + Number(Number(cur_pg) + 1);
1761  $('#btnSpanNext').html('' + $('div[id^=' + pghdr_title + ']').attr("title"));
1762  }
1763 
1764  }
1765 
1766  function getIdentifier($obj) {
1767  return $obj.attr('id') !== undefined && $obj.attr('id').length ? $obj.attr('id') : $obj.attr('name');
1768  }
1769 
1770  function RefreshCookie() {
1771  var refresh_url = "{$self_full_url}?f=refresh";
1772 
1773  var xmlhttp;
1774  xmlhttp = new XMLHttpRequest();
1775  xmlhttp.onreadystatechange=function() {
1776  if (xmlhttp.readyState==4 && xmlhttp.status==200) {
1777  // UPDATED
1778  //console.log(document.cookie);
1779  }
1780  };
1781  xmlhttp.open("GET",refresh_url,true);
1782  xmlhttp.send();
1783 
1784  }
1785  </script>
1786 
1787 <?php
1788  }
1789 } catch (Exception $ex) {
1790  print <<< formException
1791  <div class="col-lg-6">
1792  <div class="alert alert-danger " role="alert">
1793  <div>
1794  {$ex->getMessage()}
1795  </div>
1796  </div>
1797  </div>
1798 formException;
1799 }
1800 // * App_Response -- this is the applicatn response in an array based on fields..
1801  // * The array for CORE WILL BE BUILT HERE
1802  // * pApp_Response - This is the JSON object of all the key/value set
1803 function BuildSerialObject($pApp_Response_json) {
1804  global $App_SchemaDetail, $DB_TABLE_PREFIX, $DMSAPP_LOANDATAONLY;
1805 
1806  // ** core_values_array - These are the values being prepared and sent to the core
1807  $core_values_array = Array();
1808  // ** local_values_array - These values are being saved for reference later, THE NAMES must be unique
1809  // through the entire application. They do not use the fieldcorearrayindex value
1810  $local_values_array = Array();
1811  // ** combine_values_array - These values will be used to combine multiple local fields into one field in the core_values_array
1812  $combine_values_array = Array();
1813  // ** attr_values_array - This array will contain the attributes for all the fields for reference
1814  $attr_values_array = Array();
1815 
1816  $core_values_serial = "";
1817 
1818  $pApp_Response_Array = json_decode($pApp_Response_json);
1819  $localFieldsRegex = '/([\w]+)+/';
1820 
1821 
1822  // ** Need to assign
1823  foreach ($App_SchemaDetail as $schema_detailid => $schema_detailvalue) {
1824  // ** For each postable value -- Look up and assign the value on
1825  $fieldattr = json_decode($App_SchemaDetail[$schema_detailid]['fieldattr'], true);
1826  $fieldkey = "formfield_" . $schema_detailid;
1827 
1828  $localMatches = Array();
1829 
1830  // ** ONLY add this field if the fieldcorename is set
1831  if (HCU_array_key_value('fieldcorename', $fieldattr) != '' && HCU_array_key_value('localfieldonly', $fieldattr) != '1') {
1832  $attr_values_array[$fieldattr['fieldcorename']] = $fieldattr;
1833  // ** Assign the value -- There may be an Index associated with the row
1834  // ** IF so then assign that here
1835  // IF fieldcorename contains a ',' then I will explode the list out into an
1836  // array and call each each key to add it to the master list
1837 
1838  // ** Add the value to the core_values_array if it has DATA or DMSAPP_LOANDATAONLY != 1 (they did NOT choose to skip empty fields)
1839  // ** Use the NON-FORMATTED VALUE -- AS THIS IS THE ACTUAL USER INPUT
1840  if (trim($pApp_Response_Array->$fieldkey) != '' || ($DMSAPP_LOANDATAONLY != 1) || (intval(HCU_array_key_value('fieldcorealwayssend', $fieldattr)) == 1)) {
1841  // ** First FORMAT/MASSAGE the data
1842  $pApp_Response_Array->$fieldkey = FormatDateForSubmit($pApp_Response_Array->$fieldkey, HCU_array_key_value('validation_match', $fieldattr));
1843 
1844  if (strpos($fieldattr['fieldcorename'], ",") === FALSE) {
1845  if (isset($fieldattr['fieldcorearrayindex'])) {
1846  $core_values_array[$fieldattr['fieldcorearrayindex']][$fieldattr['fieldcorename']] = $pApp_Response_Array->$fieldkey;
1847  } else {
1848  $core_values_array[$fieldattr['fieldcorename']] = $pApp_Response_Array->$fieldkey;
1849  }
1850  } else {
1851  // The fieldcorename will be treated as a list
1852  $pieces = explode(",", $fieldattr['fieldcorename']);
1853  foreach ($pieces as $fieldcorename_piece) {
1854  $fieldcorename_piece = trim($fieldcorename_piece);
1855  if (isset($fieldattr['fieldcorearrayindex'])) {
1856  $core_values_array[$fieldattr['fieldcorearrayindex']][$fieldcorename_piece] = $pApp_Response_Array->$fieldkey;
1857  } else {
1858  $core_values_array[$fieldcorename_piece] = $pApp_Response_Array->$fieldkey;
1859  }
1860  }
1861  }
1862  }
1863  if (!empty($fieldattr['fieldcombinelocal']) ) {
1864  // * Split the fieldattr attribute into an array of the different fields to combine..
1865  preg_match_all($localFieldsRegex, $fieldattr['fieldcombinelocal'], $localMatches);
1866  if (count($localMatches) > 0) {
1867  // ** GET delimiter
1868  $delim = (!empty($fieldattr['fieldcombinelocaldelim']) ? $fieldattr['fieldcombinelocaldelim'] : ' ');
1869  $skipifblank = (isset($fieldattr['fieldcombineskipblankfield']) ? (intval($fieldattr['fieldcombineskipblankfield']) == 1 ? 1 : 0) : 0);
1870  // ** Matches were found, add to array for processing later
1871  $combine_values_array[$fieldattr['fieldcorename']]['fields2combine'] = $localMatches[0];
1872  $combine_values_array[$fieldattr['fieldcorename']]['fieldsdelim'] = $delim;
1873  $combine_values_array[$fieldattr['fieldcorename']]['fieldsskipifblank'] = $skipifblank;
1874  if (!empty($fieldattr['maxlength'])) {
1875  $combine_values_array[$fieldattr['fieldcorename']]['maxlength'] = $fieldattr['maxlength'];
1876  }
1877  if (!empty($fieldattr['fieldcorearrayindex'])) {
1878  $combine_values_array[$fieldattr['fieldcorename']]['fieldcorearrayindex'] = $fieldattr['fieldcorearrayindex'];
1879  }
1880  }
1881  }
1882  } elseif (HCU_array_key_value('localfieldonly', $fieldattr) == '1' &&
1883  HCU_array_key_value('fieldcorename', $fieldattr) != '') {
1884  $attr_values_array[$fieldattr['fieldcorename']] = $fieldattr;
1885  // * add to local values array
1886  $local_values_array[$fieldattr['fieldcorename']] = $pApp_Response_Array->$fieldkey;
1887  }
1888  }
1889 
1890  // ** This is sort of hard coded for now.. -- Be sure this is ONLY set for CU-CENTRIC
1891  // ** But I do NOT want to send a co-applicant if dmsapp_coapp_status is set to N
1892  if (HCU_array_key_value("dmsapp_coapp_status", $local_values_array) == "N") {
1893  // ** REMOVE the "C" co-applicant from array
1894  unset($core_values_array['C']);
1895  }
1896 
1897  // ** Loop through the combine_values_array to create one string to send to core
1898  if (is_array($combine_values_array)) {
1899  foreach ($combine_values_array as $coreFieldName => $localFieldsAry) {
1900  // combine_values_array has two elements
1901  // name - this is an array of local field names to concantenate
1902  // maxlength - this the maxlength of the field to be sent to the core
1903  // ** Look up the fields in the local_values_array
1904  $comboValue = '';
1905  // ** values must be an array for this to work, this should not have been done for ONE field
1906  if (is_array($localFieldsAry['fields2combine'])) {
1907  $allFieldsEmpty = true; // ** This will track if one of the fields being combined had 'actual' user input
1908  // * Unable to use the ending value as it may have added text
1909  for ($localIdx = 0; $localIdx < count($localFieldsAry['fields2combine']); $localIdx++) {
1910  $allFieldsEmpty = (trim($local_values_array[$localFieldsAry['fields2combine'][$localIdx]]) != '' ? false : $allFieldsEmpty);
1911  // FETCH skipblankfield value from the field BEING included.
1912  $skipfieldifblank = (isset($attr_values_array[$localFieldsAry['fields2combine'][$localIdx]]['fieldcombineskipblankfield']) ? (intval($attr_values_array[$localFieldsAry['fields2combine'][$localIdx]]['fieldcombineskipblankfield']) == 1 ? 1 : 0) : 0);
1913 
1914  if ($skipfieldifblank == 0 || (trim($local_values_array[$localFieldsAry['fields2combine'][$localIdx]]) != '')) {
1915  // ** Add delimiter
1916  $comboValue .= ($localIdx > 0 ? $localFieldsAry['fieldsdelim'] : '');
1917  // ** Add value from Local Array
1918  $comboValue .= $local_values_array[$localFieldsAry['fields2combine'][$localIdx]];
1919  }
1920  }
1921  }
1922  if ($comboValue != '') {
1923  // ** Value was created, make sure the maxlength meets the requirements if set
1924  if (!empty($localFieldsAry['maxlength'])) {
1925  $comboValue = substr($comboValue, 0, $localFieldsAry['maxlength']);
1926  }
1927  if ((trim($comboValue) != '' && !$allFieldsEmpty) || ($DMSAPP_LOANDATAONLY != 1) || isset($attr_values_array[$coreFieldName]['fieldcorealwayssend']) && (intval($attr_values_array[$coreFieldName]['fieldcorealwayssend']) == 1)) {
1928  // * SET the value in the main space
1929  if (!empty($localFieldsAry['fieldcorearrayindex'])) {
1930  // * Include the array index (CU-CENTRIC)
1931  $core_values_array[$localFieldsAry['fieldcorearrayindex']][$coreFieldName] = $comboValue;
1932  } else {
1933  $core_values_array[$coreFieldName] = $comboValue;
1934  }
1935  }
1936  }
1937  }
1938  }
1939 
1940  $loanformat = '';
1941  if (isset($GLOBALS['DMSAPP_LOANFORMAT'])) {
1942  $loanformat = $GLOBALS['DMSAPP_LOANFORMAT'];
1943  }
1944 
1945  switch ($loanformat) {
1946  case "JSON":
1947  $core_values_serial = json_encode($core_values_array);
1948  break;
1949  case "XML":
1950  $core_values_serial = generate_valid_xml_from_array($core_values_array, "NewLoanApplication");
1951  break;
1952  default:
1953  $core_values_serial = serialize($core_values_array);
1954  }
1955  return $core_values_serial;
1956 }
1957 
1958 // ** PostApplicationPacket - This will call the pieces needed to call the
1959  // ** Post packet
1960  // ** Parameters
1961  // * @param object pHbEnv - The HB_ENV environment
1962  // * pApp_RespID - Applicant Response ID Key (From respid field of table)
1963  // * pApp_Response - The JSON representation of the application Key=>value set
1964  // * pApp_RespMbr - Responsive Member
1965  // ** RETURNS
1966  // * This will return the following
1967  // ** ret_status - Which will be the
1968 function SubmitApplication($pHbEnv, $pApp_RespID, $pApp_Response, $pApp_RespMbr) {
1969 global $DB_TABLE_PREFIX, $DMSAPP_SUBMITMBR;
1970 global $dbh;
1971 
1972  // ** FOR ONLINE DO THE FOLLWOWING
1973  if ($GLOBALS['DMSAPP_ONLINE']) {
1974 
1975  if ($GLOBALS['DMSAPP_MODE_ARY']['offline']) {
1976  $CoreSerialValue = BuildSerialObject($pApp_Response);
1977 
1978  /* OLD ROUTINE
1979  list($ret_status, $ret_statusdesc) = post_application("{$DB_TABLE_PREFIX}userresponse", $pApp_RespID, "NEWAPP", "email", $CoreSerialValue, ($DMSAPP_SUBMITMBR == 1 ? $pApp_RespMbr : 'NULL'));
1980  //print " POST APPLICATION TO CORE";
1981  //list($ret_status, $ret_statusdesc) = array("000","12934");
1982 
1983  */
1984 
1985 
1986  /* Loan Submission Setup */
1987  $txnValues = array( "member" => ($DMSAPP_SUBMITMBR == 1 ? $pApp_RespMbr : 'NULL'),
1988  "type" => PACKET_REQUEST_NEWAPP,
1989  "pkt-type" => PACKET_REQUEST_NEWAPP,
1990  "tran_code" => 'NULL',
1991  "ref1" => $CoreSerialValue,
1992  "ref2" => 'NULL',
1993  "ref3" => '',
1994  "ref4" => 'NULL',
1995  "ref5" => 'NULL', // this could be 10/20 for checking/savings
1996  "amount" => 0.00,
1997  "tmemo" => '',
1998  "tauth" => 'NULL'
1999  );
2000 
2001  // Submit New App -- SEND AS POST
2002 
2003  $reqResult = PostTransactionRequest($pHbEnv, $txnValues, true);
2004 
2005 
2006  if (HCU_array_key_exists('code', $reqResult['data'])) {
2007  $ret_status = $reqResult['data']['code'];
2008  $ret_statusdesc = $reqResult['data']['desc'];
2009  $ret_apploanid = $reqResult['data']['seg1'];
2010  } else {
2011  $ret_status = '999';
2012  $ret_statusdesc = 'Unknown status';
2013  $ret_apploanid = -1;
2014  }
2015 
2016  $sql_set = '';
2017  switch (trim($ret_status)) {
2018  case "000":
2019  // ** NO ERROR -- Loan ACCEPTED -- UPDATE
2020  // * {respcoreloanappid}
2021  // * {respsubmiton}
2022  // * {respstatus}
2023  // * {respstatusdesc}
2024  $ret_statdesc = "Loan was successfully submitted.";
2025  $sql_set = "respcoreloanappid = " . intval($ret_apploanid) . ",
2026  respsubmiton = now(),
2027  respstatus = '000',
2028  resplastinquire = now(),
2029  respstatusdesc = '" . prep_save ($ret_statdesc) . "' ";
2030  break;
2031  case "020":
2032  // ** SUBMIT ERROR - Missing Field
2033  case "021":
2034  // ** SUBMIT ERROR - Invalid Member #
2035  case "022":
2036  // ** SUBMIT ERROR - Member # and SSN mismatch
2037 
2038  // ** Something was missing on the NEW LOAN -- Unable to retrieve a loanappid
2039  // * UPDATE THE FIELDS
2040  // * {respstatus}
2041  // * {respstatusdesc}
2042  $sql_set = "respstatus = '$ret_status',
2043  respstatusdesc = '" . prep_save($ret_statusdesc) . "' ";
2044  break;
2045  // ** 025, 026, 027, 028, 029 -- are relevent to an INQAPP request
2046  case "025":
2047  // ** Invalid Application ID
2048  // *nothing to do right now for this..
2049  break;
2050  case "027":
2051  // ** Application Approved -_ NEED APPROVAL DATE
2052  case "028":
2053  // ** Application Rejected -- NEED REJECTED DATE
2054  case "026":
2055  // ** Application Pending
2056  case "029":
2057  // ** Application Submitted -- Needs further review
2058  case "030":
2059  // ** Application Submitted -- Contact Credit Union for additional information
2060  $sql_set = "respcoreloanappid = " . intval($ret_apploanid) . ",
2061  respstatus = '$ret_status',
2062  respsubmiton = now(),
2063  resplastinquire = now(),
2064  respstatusdesc = '" . prep_save($ret_statusdesc) . "' ";
2065  break;
2066  case "999":
2067  // ** Unable to contact Credit Union
2068  $ret_status = "999";
2069  $ret_statdesc = "We are currently having problems communicating with the credit union. Please save your application and try to submit again later. <br>$ret_statusdesc";
2070  break;
2071  }
2072  if ($sql_set != '') {
2073  // ** Update the information on the {dmsapp}userresponse table
2074  $sql = "UPDATE {$DB_TABLE_PREFIX}userresponse
2075  SET $sql_set
2076  WHERE respid = " . intval($pApp_RespID);
2077  if (!$resp_rs = db_query($sql, $dbh)) {
2078  $ret_status = "999";
2079  $ret_statdesc = "An unknown error occurred. Please try again.";
2080  }
2081  }
2082 
2083  // ** Depending on the status -- I may want to do different things..
2084  // ** Go to Portal
2085  // ** Go back to screen
2086  switch($ret_status) {
2087  case "000":
2088  case "026":
2089  case "027":
2090  case "028":
2091  case "029":
2092  case "030":
2093 
2094  // ** SUCCESS -- LOAD PORTAL
2095  return array(true, $ret_statusdesc);
2096  break;
2097  default:
2098  // ** GO BACK TO SCREEN _-- with error message
2099  return array(false, $ret_statusdesc. "<br/>Your application has been saved. You may return later and submit your application.");
2100  }
2101  } else {
2102  // ** Offline -- post as such??
2103  return array(false, $GLOBALS['DMSAPP_MODE_ARY']['offlineDesc'] . "<br/>Your application has been saved. You may return later when the system is online and submit your application.");
2104  }
2105  } else {
2106  // ** OFFLINE -- LIKE BATCH -- ONLY SAVES FOR HomeCU Admin viewing. so I will save that here
2107  $ret_status = "029";
2108  $ret_statusdesc = "The loan was submitted for Credit Union review.";
2109  $sql = "UPDATE {$DB_TABLE_PREFIX}userresponse
2110  SET
2111  respsubmiton = now(),
2112  respstatus = '000',
2113  resplastinquire = now(),
2114  respstatusdesc = '" . prep_save ($ret_statusdesc) . "'
2115  WHERE respid = " . intval($pApp_RespID);
2116  if ($upd_rs = db_query($sql, $dbh)) {
2117  return array(true, $ret_statusdesc);
2118  } else {
2119  return array(false, "Unexpected error submitting application.");
2120  }
2121  }
2122 
2123 }
2124 function generate_xml_from_array($array, $node_name) {
2125  $xml = '';
2126 
2127  if (is_array($array) || is_object($array)) {
2128  foreach ($array as $key=>$value) {
2129  if (is_numeric($key)) {
2130  $key = $node_name;
2131  }
2132 
2133  $xml .= '<' . $key . '>' . generate_xml_from_array($value, $node_name) . '</' . $key . '>';
2134  }
2135  } else {
2136  $xml = htmlspecialchars($array, ENT_QUOTES);
2137  }
2138 
2139  return $xml;
2140 }
2141 
2142 function generate_valid_xml_from_array($array, $node_block='nodes', $node_name='node') {
2143 
2144  /**
2145  * 9/21/2018
2146  * Prodigy interferface does not like the XML tag
2147  * -- BUT I BELIEVE CRUISE WILL NEED THIS
2148  */
2149  $xml = '';
2150  if (false) {
2151  $xml = '<?xml version="1.0" encoding="UTF-8" ?>';
2152  }
2153 
2154  $xml .= '<' . $node_block . '>';
2155  $xml .= generate_xml_from_array($array, $node_name);
2156  $xml .= '</' . $node_block . '>';
2157 
2158  return $xml;
2159 
2160 }
2161 
2162 /**
2163  * Function: FormatDateForSubmit
2164  * @param type $p_value - This is the value that is being evaluated.
2165  * @param type $p_value_type -- This is the value 'validation_match' from the attribute
2166  * -- column
2167  * Returns: This will evaluate tyep p_value_type and format the value if necessary.
2168  * The formatted value is returned
2169  *
2170  */
2171 function FormatDateForSubmit ($p_value, $p_value_type) {
2172  $retVal = $p_value;
2173 
2174  switch ($p_value_type) {
2175  case 'usd':
2176  // ** Always remove commas first
2177  $p_value = str_replace(",", "", $p_value);
2178  $retVal = number_format(floatval($p_value), 2, ".", "");
2179 
2180  break;
2181  case 'number':
2182  case 'integer':
2183  // ** For KNOWN dollar amounts, I want to remove any comma
2184  $retVal = str_replace(",", "", $p_value);
2185  break;
2186  default:
2187  $retVal = $p_value;
2188  }
2189 
2190  return $retVal;
2191 }
2192 
2193 
2194 /**
2195  * Function: ValidateRange
2196  * @param string $pFieldLabel -- The label identifying the value
2197  * @param array $pFieldAttr -- The field attributes for current row
2198  [validate_require_numeric_range_chk]
2199  [validate_require_numerica_range[min/max]]
2200 
2201  * @param mixed $pFieldVal -- The field value
2202  *
2203  * @return string
2204  * return the error message if the value does not fit in range
2205 */
2206 function ValidateRange($pFieldLabel, $pFieldAttr, $pFieldVal) {
2207  $retErrors = ''; // ** Return Errors in this string
2208 
2209  $pCompVal =
2210  // * Get the current checkbox value
2211  $verifyRange = 0;
2212  if (array_key_exists("validation_require_numeric_range_chk", $pFieldAttr)) {
2213  $verifyRange = ($pFieldAttr['validation_require_numeric_range_chk'] == 1 ? 1 : 0);
2214  }
2215 
2216  if ($verifyRange) {
2217  $rangeMinVal = '';
2218  $rangeMaxVal = '';
2219 
2220  if (array_key_exists("validation_require_numeric_range", $pFieldAttr)) {
2221  // * Get min
2222  if (array_key_exists("min", $pFieldAttr["validation_require_numeric_range"])) {
2223  $rangeMinVal = $pFieldAttr["validation_require_numeric_range"]["min"];
2224  }
2225  // * Get Max
2226  if (array_key_exists("max", $pFieldAttr["validation_require_numeric_range"])) {
2227  $rangeMaxVal = $pFieldAttr["validation_require_numeric_range"]["max"];
2228  }
2229  }
2230 
2231  // * Min or max should be set
2232  // ** ONLY COMPARE if Val is set
2233 
2234  // MUST be Greater than equal to Min
2235  if ($rangeMinVal != '' && ($pFieldVal < $rangeMinVal)) {
2236  $retErrors .= "<li>$pFieldLabel is less than the minimum allowed ($rangeMinVal).</li>";
2237  }
2238  // MUST be Less than equal to Max
2239  if ($rangeMaxVal != '' && ($pFieldVal > $rangeMaxVal)) {
2240  $retErrors .= "<li>$pFieldLabel is greater than the maximum allowed ($rangeMaxVal).</li>";
2241  }
2242 
2243  }
2244 
2245  return $retErrors;
2246 }