Field Validation stops working unexpectedly

I've written a field validation in the Meetings module that checks to see if there is another meeting for the Assigned to user within 30 minutes of the start or finish of the time.  It works BEAUTIFULLY for like, 12 hours.  Then the "Save" button just freezes gray and I'm unable to save any more meetings.  This is a Dev box so I dont even have CRON enabled.  If I do a quick rebuild and repair, it starts working again for a few hours since it rebuld all the JS files.  Then suddenly out of nowhere the bug returns.  Here is my custom record.js/create.js

I'm using an ajax call to pass some variables to a PHP entrypoint and doing some raw queries inside the entrypoint, passing back a value of TRUE or FALSE.  I've tried making this a synchronous ajax call thinking that the save wasnt waiting for the ajax call to complete but that didnt help either. 

Any ideas?  Francesca Shiekh HALP!  

({
    extendsFrom: 'MeetingsRecordView',

    initialize: function (options) {

        this._super('initialize', [options]);
          
          
          
          //add custom message key
        app.error.errorName2Keys['custom_message'] = 'Invalid dates';

        //add validation tasks
        this.model.addValidationTask('check_meeting_date', _.bind(this._doValidateMeeting, this));
          
    },

     
     
    _doValidateMeeting: function(fields, errors, callback) {
          
          var recordID = this.model.get('id');
          var displayMSG = "false";
          var date_start = this.model.get('date_start');
          var date_end = this.model.get('date_end');
          var assigned_user_id = this.model.get('assigned_user_id');
          //console.log(this.model.get('date_start'));
          
          function ajaxcall(id)
          {
               $.ajax({ 
                                   type: 'POST', 
                                   async: false,
                                   url: 'index.php?entryPoint=checkMeetingDate',
                                   data: {recordID: id, date_start:date_start, date_end:date_end, assigned_user_id:assigned_user_id},
                                   dataType: "json",
                                   success: function(response)
                                   {
                                        console.log('We have success!');               
                                     if(response.is_valid === "TRUE")
                                      {
                                        ajaxResultTrue("true");
                                        console.log("Result was true");
                                        }
                                        else
                                        {
                                             ajaxResultFalse("false");
                                             console.log("Result was false");
                                        }
                                    
                                   }
               });
          }
          
          function ajaxResultTrue(result)
          {
               errors['date_start'] = errors['date_start'] || {};
                    errors['date_start'].custom_message = true;
                    errors['date_end'] = errors['date_start'] || {};
                    errors['date_end'].custom_message = true;
                    app.alert.show('message-id', {
                         level: 'error',
                         messages: 'You have a conflicting Meeting within 30 minutes of this Meeting.  Please choose another time',
                         autoClose: true,
                         autoCloseDelay: 10000,
                         
                              });
               callback(null, fields, errors);
          }
          
          function ajaxResultFalse(result)
          {
               callback(null, fields, errors);
          }
          
          
          ajaxcall(recordID);     

       
    },
     
     
     
     


})

Here is the entrypoint:

<?php

if (!defined('sugarEntry') || !sugarEntry)
          die('Not A Valid Entry Point');
          
          global $current_user,$db, $sugar_config;
          
          $meeting_id = $_POST['recordID'];
          $date_start_post = $_POST['date_start'];
          $date_end_post = $_POST['date_end'];
          $assigned_user_id = $_POST['assigned_user_id'];
          
          
          $date_start_array = explode('T', $date_start_post);
          $date_start_day = $date_start_array[0];
          $date_start_time = $date_start_array[1];
          $date_start_time_array = explode('-', $date_start_time);
          $date_start_time = $date_start_time_array[0];
          $date_start_interval = $date_start_time_array[1];
          $date_start_interval = str_replace('0','',$date_start_interval);
          $date_start_interval = str_replace(':','',$date_start_interval);
          
          $date_start = $date_start_day . ' ' . $date_start_time;
          
          
          //  Take the posted start date and format it correctly
          $date_end_array = explode('T', $date_end_post);
          $date_end_day = $date_end_array[0];
          $date_end_time = $date_end_array[1];
          $date_end_time_array = explode('-', $date_end_time);
          $date_end_time = $date_end_time_array[0];
          $date_end_interval = $date_end_time_array[1];
          $date_end_interval = str_replace('0','',$date_end_interval);
          $date_end_interval = str_replace(':','',$date_end_interval);
          
          $date_end = $date_end_day . ' ' . $date_end_time;
          
          $GLOBALS['log']->fatal("Made it inside the Ajax call! - $assigned_user_id");
          $GLOBALS['log']->fatal("Date start POST = $date_start");
          $GLOBALS['log']->fatal("Date start interval = $date_start_interval");
          
          $meeting = BeanFactory::getBean("Meetings", $meeting_id);
          
          //$date_start = $meeting->date_start;
          //$date_end = $meeting->date_end;
          
          
          $GLOBALS['log']->fatal(" Start date is : $date_start");
          $GLOBALS['log']->fatal(" End date is : $date_end");
          
          $begin = new DateTime($date_start);
          $end = new DateTime($date_end);
          $minutes = '30';
          
          $begin->modify('+'.$date_start_interval.' hours');
          $begin->modify('-'.$minutes.' minutes');
          $end->modify('+'.$date_start_interval.' hours');
          $end->modify('+'.$minutes.' minutes');
          $begin_result = $begin->format('Y-m-d H:i:s');
          $end_result = $end->format('Y-m-d H:i:s');
          
          $GLOBALS['log']->fatal("Query Start date is : $begin_result");
          $GLOBALS['log']->fatal("Query End date is : $end_result");
          
          //$GLOBALS['log']->fatal("New Start date is : $begin_result and the new End Date is $end_result");
          
          $query = "SELECT id from meetings WHERE assigned_user_id = '$assigned_user_id' AND id != '$meeting_id' AND deleted = '0' AND
                            ((date_start BETWEEN '$begin_result' AND '$end_result')
                            OR
                            (date_end BETWEEN '$begin_result' AND '$end_result')
                            )
                         ";
          $queryExec = $db->query($query);
          
          $queryResult = $db->fetchByAssoc($queryExec);
          $queryResultID = $queryResult['id'];
          
          $GLOBALS['log']->fatal("The result is: $queryResultID");
          
          
          if($queryResultID != '')
          {
               $data = array("is_valid" => "TRUE");
          }
          else
          {
               $data = array("is_valid" => "FALSE");
          }
          
          $json_data = json_encode($data);
          
          
          echo $json_data;

?>
Parents Reply Children
  • Man the learning curve and documentation for Custom endpoints is awful.  Finally got it working though.  I won't know for 24 hours or so if this fixes the original problem of the save button just breaking unexpectedly but I followed your advice.  Something tells me that the AJAX call wasnt returning fast enough as the save function doesnt wait for AJAX to return any results.  For the kids following along at home:

    Javascript:

    _doValidateMeeting: function(fields, errors, callback) {

       var recordID = this.model.get('id');
       var date_start = this.model.get('date_start');
       var date_end = this.model.get('date_end');
       var assigned_user_id = this.model.get('assigned_user_id');

       App.api.call('GET', App.api.buildURL('MyEndpoint/CheckMeetings/'+recordID+'/'+date_start+'/'+date_end+'/'+assigned_user_id), null , {
       success: function (data) {
       var result = JSON.parse(data);
       if(result.is_valid === "TRUE")
       {
          errors['date_start'] = errors['date_start'] || {};
          errors['date_start'].custom_message = true;
          errors['date_end'] = errors['date_start'] || {};
          errors['date_end'].custom_message = true;
          app.alert.show('message-id', {
             level: 'error',
             messages: 'You have a conflicting Meeting within 30 minutes of this Meeting. Please choose another time',
             autoClose: true,
             autoCloseDelay: 10000,

             });
          callback(null, fields, errors);
          console.log("Result was true");
       }
       else
       {
          callback(null, fields, errors);
          console.log("Result was false");
          console.log(data);
       }
    },
    error: function (e) {
    throw e;
    callback(null, fields, errors);
    }

    });


    },

    Endpoint registerApiRest() array:

    public function registerApiRest()
    {
       return array(
             'MyGetEndpoint' => array(
             //request type
             'reqType' => array('GET'),

             //set authentication
             'noLoginRequired' => false,

             //endpoint pathinfo
             'path' => array('MyEndpoint', 'CheckMeetings', '?', '?', '?', '?'),

             //endpoint variables
             'pathVars' => array('', '', 'record_id', 'date_start', 'date_end', 'assigned_user_id'),

             //method to call
             'method' => 'ConfirmDate',

             //short help string to be displayed in the help documentation
             'shortHelp' => 'Custom API to check meeting date conflicts',

             //long help to be displayed in the help documentation
             'longHelp' => 'custom/clients/base/api/help/CheckMeetings_ConfirmDate_help.html',

             ),
       );

    }

    As far as the method 'ConfirmDate' the code stayed almost exact the same.  I just changed 4 lines 

    $meeting_id = $args['record_id'];
    $date_start_post = $args['date_start'];
    $date_end_post = $args['date_end'];
    $assigned_user_id = $args['assigned_user_id'];