logic hooks popup alert

Hello,

Please help me solution to display popup alert by logic hooks

This logic hooks after save of Case, when Case set to Closed but Task in subpanel is not Completed, the logic hooks will popup alert and restrict save.

Thanks 

Parents
  • Hi,

    You can use throw exception and popup the alert.Using exception you can restrict the save. Put below code in your logic hooks and check.

    throw new SugarApiExceptionNotAuthorized('SUGAR_API_EXCEPTION_RECORD_NOT_AUTHORIZED',array('view'));
     throw new SugarApiExceptionInvalidParameter(string_format(
                            $GLOBALS['app_strings']['LBL_UPLOAD_IMAGE_FILE_NOT_SUPPORTED'],
                            array($extension)
                        ));
    throw new SugarApiExceptionError('Unable to load field definition');

    Another way is use the Validations of sugarcrm. Please check one of sugarcrm link http://support.sugarcrm.com/Documentation/Sugar_Developer/Sugar_Developer_Guide_7.6/UI_Model/Views/Examples/Adding_Field… 


    Let me know if you need more help.

    -BPATEL

  • Hi Bhavesh Patel,

    Thank you very much, I'll try and feedback

    Regards

  • Hi Bhavesh Patel

    This is my logic hooks

    <?php

    class CheckClosed
    {
    public function CheckTask(SugarBean $bean, $event, $args)
    {
    global $sugar_config, $db,$current_user;
    //check Task status
    $id = $bean->id;
    $query = "SELECT status FROM tasks WHERE parent_id = '$id' AND deleted = '0'";
    $result = $db->query($query,true);
    $rows = $db->fetchByAssoc($result);
    $check = 0;
    foreach ($row as $rows) {
    if ($row['status'] != 'Completed') {
    $check = 1;
    $GLOBALS['log']->test('check: '.$id);
    break;
    }
    }
    if ($check = 1) {
    throw new SugarApiExceptionError('Unable to Closed. Please set Task to Completed');
    $GLOBALS['log']->test('check: '.$check);
    }
    }
    }

    It dose not work with your code throw new SugarApiExceptionError('Unable to Closed. Please set Task to Completed');

    Please help me. Thanks

  • 1) Are you sure the logic hook is firing at all? Have you added this function to the logic hooks array and done a repair and rebuild? Alternatively, you could put this at the top of the function to check it's firing:

    $GLOBALS['log']->test('Logic hook is active');

    2) You've got an assignment in your code where you should have a comparison operator. Instead of:

    if ($check = 1) {

    You should have:

    if ($check == 1) {

    3) Instead of using throw new SugarApiExceptionError, have you tried sugar_die as I recommended:

    sugar_die('Unable to Closed. Please set Task to Completed.');

     

  • Thank for your reply

    1. I'm sure my logic hook is firing at alls

    2. New my code, but it did not work

    3. Please help me how to display code format in my post

    <?php
    class CheckClosed
    {
    public function CheckTask(SugarBean $bean, $event, $args)
    {
    global $sugar_config, $db,$current_user;
    //check Task status
    $id = $bean->id;
    $status = $bean->status;
    $query = "SELECT status FROM tasks WHERE parent_id = '$id' AND deleted = '0'";
    $result = $db->query($query,true);
    $rows = $db->fetchByAssoc($result);
    $check = 0;
    foreach ($row as $rows) {
    if ($row['status'] != 'Completed') {
    $check = 1;
    break;
    }
    }
    if ($check == 1 && $status = 'Closed') {
    //throw new SugarApiExceptionError('Unable to Closed. Please set Task to Completed');
    sugar_die('Unable to Closed. Please set Task to Completed.');
    //$GLOBALS['log']->test('check: '.$check);
    }
    }
    }
  • Well, let's try and break it down bit by bit. Change your code to:

    <?php
    class CheckClosed
    {
        public function CheckTask($bean, $event, $args){
            sugar_die('Unable to Closed. Please set Task to Completed.');
        }
    }

    This should stop a task from ever being saved. If that doesn't work, then the logic hook isn't firing. If it does work, then log the results of your SQL and figure out why that isn't doing what you're doing. Break the problem into little bits.

    With regards to the syntax highlighting - click on 'More ' in the editor, and then click on 'Syntax Highligher'.

    Let me know where/if    you get stuck.

  • Thank for your help.

    My purpose is stop Case save when set Case to Closed if Task of Case is not Completed and popup Alert.

     With your code I did not know how to check Task Completed when Case set to Closed

  • Hello Bao Tran Hoang,

    Please Put below code in your file.

    <?php
    class CheckClosed
    {
        public function CheckTask($bean, $event, $args){
             throw new SugarApiExceptionInvalidParameter(string_format(
                            $GLOBALS['app_strings']['LBL_UPLOAD_IMAGE_FILE_NOT_SUPPORTED'],
                            array($extension)
                        ));

        }
    }

    I have checked this is working fine for me.

    Hope it will help you.

    -BPATEL

  • Hi Bhavesh Patel,

    My logic hooks is working but this code dose not prevent Case save, I received error message: PHP Notice:  Undefined variable: extension

    public function CheckTask(SugarBean $bean, $event, $args)
        {
        global $sugar_config, $db,$current_user;
           //check Task status
           $id = $bean->id;
           $status =  $bean->status;
           $GLOBALS['log']->test('check: '.$status);
           $query = "SELECT status FROM tasks WHERE parent_id = '$id' AND deleted = '0'";
           $result = $db->query($query,true);
           $rows = $db->fetchByAssoc($result);
           $check = 0;
           foreach ($rows as $row) {
              if ($row['status'] != 'Completed') {
              $check = 1;
              $GLOBALS['log']->fatal('check: '.$status);
              break;
             } 
           }
           if ($check == 1 && $status = 'Closed') {
             throw new SugarApiExceptionInvalidParameter(string_format(
                            $GLOBALS['app_strings']['LBL_UPLOAD_IMAGE_FILE_NOT_SUPPORTED'],
                            array($extension)
                        ));
           }
        }
  • Hi Bao,

    Firstly, you've got a mistake '

           foreach ($row as $rows) {

    It should be:

           foreach ($rows as $row) {

    Secondly what is your logging output? Also, try putting in  $GLOBALS['log']->test(print_r($rows, true));  and let me know what the output of the rows are. Try putting in logging everywhere and try and solve it that way.   

  • Hi Bao Tran Hoang,

    That is not PHP Notic. You need to remove that extension variable.

    throw new SugarApiExceptionInvalidParameter(string_format(
         $GLOBALS['app_strings']['SET_YOUR_CUSTOM_MESSAGE'],''));

    This way you can prevent the save.and got red alert pop-up.

    Below is the second way that you can use.

    http://support.sugarcrm.com/Documentation/Sugar_Developer/Sugar_Developer_Guide_7.6/UI_Model/Views/Examples/Adding_Field… 

  • Thanks Bhavesh Patel

    I updated my code and add string LBL_CASE_NOT_CLOSED to lang, I received message in error PHP Notice:  Undefined index: LBL_CASE_NOT_CLOSED. Anh receive red alert  A parameter in your request was invalid.

    public function CheckTask(SugarBean $bean, $event, $args)
        {
        global $sugar_config, $db,$current_user;
           //check Task status
           $id = $bean->id;
           $status =  $bean->status;
           $GLOBALS['log']->test('check: '.$status);
           $query = "SELECT status FROM tasks WHERE parent_id = '$id' AND deleted = '0'";
           $result = $db->query($query,true);
           $rows = $db->fetchByAssoc($result);
           $check = 0;
           foreach ($rows as $row) {
              if ($row['status'] != 'Completed') {
              $check = 1;
              $GLOBALS['log']->fatal('check: '.$status);
              break;
              }
           }
           if ($check == 1 && $status = 'Closed') {
             throw new SugarApiExceptionInvalidParameter(string_format(
                  $GLOBALS['app_strings']['LBL_CASE_NOT_CLOSED'],''));
           }
        }
  • Thank you very much, I updated my code below but it dose not work

  • I'm not sure about this 'throw new SugarApiExceptionInvalidParameter'. I'd use a sugar_die instead (I've mentioned this before). For example, using the code above:

    public function CheckTask(SugarBean $bean, $event, $args)
        {
        global $sugar_config, $db,$current_user;
           //check Task status
           $id = $bean->id;
           $status =  $bean->status;
           $GLOBALS['log']->test('check: '.$status);
           $query = "SELECT status FROM tasks WHERE parent_id = '$id' AND deleted = '0'";
           $result = $db->query($query,true);
           $rows = $db->fetchByAssoc($result);
           $check = 0;
           foreach ($rows as $row) {
              if ($row['status'] != 'Completed') {
              $check = 1;
              $GLOBALS['log']->fatal('check: '.$status);
              break;
              }
           }
           if ($check == 1 && $status = 'Closed') {
              sugar_die('Case Not Closed');
           }
        }

    If you want to carry on using SugarApiExceptionInvalidParameter, I'd recommend creating a new label for LBL_CASE_NOT_CLOSED.

Reply
  • I'm not sure about this 'throw new SugarApiExceptionInvalidParameter'. I'd use a sugar_die instead (I've mentioned this before). For example, using the code above:

    public function CheckTask(SugarBean $bean, $event, $args)
        {
        global $sugar_config, $db,$current_user;
           //check Task status
           $id = $bean->id;
           $status =  $bean->status;
           $GLOBALS['log']->test('check: '.$status);
           $query = "SELECT status FROM tasks WHERE parent_id = '$id' AND deleted = '0'";
           $result = $db->query($query,true);
           $rows = $db->fetchByAssoc($result);
           $check = 0;
           foreach ($rows as $row) {
              if ($row['status'] != 'Completed') {
              $check = 1;
              $GLOBALS['log']->fatal('check: '.$status);
              break;
              }
           }
           if ($check == 1 && $status = 'Closed') {
              sugar_die('Case Not Closed');
           }
        }

    If you want to carry on using SugarApiExceptionInvalidParameter, I'd recommend creating a new label for LBL_CASE_NOT_CLOSED.

Children
  • hi Alan Apter

    I used your mentioned but I received red alert There was an error while connecting to the server. Please try again.

  • You could check the apache error logs. Or you're going to have to take things out line-by-line and figure out what's causing the problem. First take out the sugar_die line. Then 

           if ($check == 1 && $status = 'Closed') {        
           }

    Etc etc.

  • Hi Alan Apter,

    The apache is no error logs. If I take out the sugar_die is no red alert. 

    Thank for your help

  • Hi Alan Apter,

    The status is dropdown so I can not get value setected by $bean

    But I did not know to use $_POST in logic hooks

    Please help me

  • So, the logic hooks approach isn't going to work. For some reason I thought you were using Sugar 6/a BWC module. It used to work in Sugar 6, but seeing as you're not using a BWC module, there's no way to communicate back to front end interface using a logic hook in the manner you describe.

    The way to solve your problem is using javascript. The sugarcrm examples of using validation are here: http://support.sugarcrm.com/Documentation/Sugar_Developer/Sugar_Developer_Guide_7.6/UI_Model/Views/Examples/Adding_Field… 

    The way to do it is to add a file in /custom/modules/Cases/clients/base/views/record/record.js

    The file should have this in it:

    ({
         extendsFrom: 'RecordView',
        initialize: function (options) {
            this._super('initialize', [options]);
              
              //add the validation task
            this.model.addValidationTask('validate_cases', _.bind(this._doValidateCases, this));
        },

        _doValidateCases: function (fields, errors, callback) {
            var case = this.model;
            if(case.attributes.status == 'Closed'){
                        var tasks = case.getRelatedCollection('case_tasks');
                        
                        //fetch the tasks
                        var fetchTasks = tasks.fetch({relate: true});
                        
                        //wait until the fetch finishes before executing the next bit
                        fetchAllocations.xhr.done(function () {
                             
                             tasksJSON = tasks.toJSON();
                             //loop through all the tasks
                             _.each(tasksJSON, function (task) {
                                  
                                  //if one of the tasks isn't completed, throw an error message, and add a validation problem
                                  if (task.status != 'Completed'){
                                       app.alert.show('message-id', {
                                            level: 'error',
                                            messages: 'The  Case has a related task that is not completed and therefore the Task cannot be closed',
                                            autoClose: true
                                       });
                                       errors['status'] = errors['status'] || {};
                                       errors['status'].required = true;
                                  }
                             });
                             
                             //proceed to the callbacks
                             callback(null, fields, errors);
                        });
                }                
            } else {
                   //proceed to the callbacks
                   callback(null, fields, errors);
            }
            
            
            


        },
    })

    BTW This will not prevent save on mobile. You'll need to do a repair and rebuild and delete your local cache (try it from incognito mode) to test it. Also, I've written all this from memory, so there might be a bug in the code. Let me know if you have any problems.

  • Hi Alan Apter,

    I updated record.js and then repari and rebuild, but my sugar is loading, it can not display home

    the apache is not error.

    Thank you very much

  • Sorry, made a few mistakes with the code - I wrote it all from memory as I don't have access to my developer environment. I've fixed the mistakes I can see, here is my updated code, try this. If it doesn't work, open up the javascript console (ctrl-shift-i, then click on console) and see if there are any errors.

    ({
        extendsFrom: 'RecordView',
        initialize: function (options) {
            this._super('initialize', [options]);
            //add the validation task
            this.model.addValidationTask('validate_cases', _.bind(this._doValidateCases, this));
        },
        _doValidateCases: function (fields, errors, callback) {
            var singleCase = this.model;
            if (singleCase.attributes.status == 'Closed') {
                var tasks = singleCase.getRelatedCollection('case_tasks');
                //fetch the tasks
                var fetchTasks = tasks.fetch({relate: true});
                //wait until the fetch finishes before executing the next bit
                fetchTasks.xhr.done(function () {

                    tasksJSON = tasks.toJSON();
                    //loop through all the tasks
                    _.each(tasksJSON, function (task) {

                        //if one of the tasks isn't completed, throw an error message, and add a validation problem
                        if (task.status != 'Completed') {
                            app.alert.show('message-id', {
                                level: 'error',
                                messages: 'The  Case has a related task that is not completed and therefore the Task cannot be closed',
                                autoClose: true
                            });
                            errors['status'] = errors['status'] || {};
                            errors['status'].required = true;
                        }
                    });
                    //proceed to the callbacks
                    callback(null, fields, errors);
                });
            } else {
    //proceed to the callbacks
                callback(null, fields, errors);
            }
        }
    })
  • Hi Alan Apter,

    Thank you very much

    I have some error from javascript console, I am debugging, I'll feedback soon

    Thanks

  • Hi Alan Apter

    I received error from console when I save Case set to Closed

    1. {error: "not_found", error_message: "Could not find a relationship named: case_tasks"}
      1. error:"not_found"
      2. error_message:"Could not find a relationship named: case_tasks"
  • Thanks for the logging information, it has helped me with the issue. It's a bit of an edge case, the problem appears to be with:

                var tasks = singleCase.getRelatedCollection('case_tasks');

    The relationship is called case_tasks in studio, but you fetch the related collection just using 'tasks'. It's annoyingly inconsistent, but so is life. Here is the fixed code:

    ({
        extendsFrom: 'RecordView',
        initialize: function (options) {
            this._super('initialize', [options]);
            //add the validation task
            this.model.addValidationTask('validate_cases', _.bind(this._doValidateCases, this));
        },
        _doValidateCases: function (fields, errors, callback) {
            var singleCase = this.model;
            if (singleCase.attributes.status == 'Closed') {
                var tasks = singleCase.getRelatedCollection('tasks');
                //fetch the tasks
                var fetchTasks = tasks.fetch({relate: true});
                //wait until the fetch finishes before executing the next bit
                fetchTasks.xhr.done(function () {

                    tasksJSON = tasks.toJSON();
                    //loop through all the tasks
                    _.each(tasksJSON, function (task) {

                        //if one of the tasks isn't completed, throw an error message, and add a validation problem
                        if (task.status != 'Completed') {
                            app.alert.show('message-id', {
                                level: 'error',
                                messages: 'The  Case has a related task that is not completed and therefore the Task cannot be closed',
                                autoClose: true
                            });
                            errors['status'] = errors['status'] || {};
                            errors['status'].required = true;
                        }
                    });
                    //proceed to the callbacks
                    callback(null, fields, errors);
                });
            } else {
    //proceed to the callbacks
                callback(null, fields, errors);
            }
        }
    })

    Let me know if this works, and if it doesn't, let me know what the console says. I'm hoping to get a development environment up soon so I can test it myself.