Search code examples
sugarcrmsugarbean

How to make sure that Sugar field validation has enough time to run


I'm trying to create a field validation in the Opportunity module that will throw an error when a user tries to change a commit stage from "Upside" or "Commit" back to "Funnel". The validation function in record.js runs as the user attempts to save an edited opportunity. It compares the selected commit stage with the commit stage saved in the database for the opportunity. A validation error is thrown if the selected commit stage is "Funnel" and the saved commit stage is either "Upside" or "Commit". When the validation error is thrown, the commit stage field should be highlighted and a pop-up should be displayed with an error message.

The validation code in record.js looks like this:

initialize: function (options) {
    this._super('initialize', [options]);
    app.error.errorName2Keys['check_commit_stages'] = 'ERROR_CHECK_COMMIT_STAGES';
    this.model.addValidationTask('check_commit_stages', _.bind(this._doValidateCommitStages, this));
},

_doValidateCommitStages: function(fields, errors, callback) {
    console.log('Validating commit stages in record.js');

    let CommitStageSelected = this.model.get('commit_stage_c');
    let OpportunityId = this.model.get('id');
    let OpportunityBean = app.data.createBean('Opportunities');
    OpportunityBean.set('id', OpportunityId);
    let CommitStageSaved = '';
    OpportunityBean.fetch({success: function(model, data){
            CommitStageSaved = OpportunityBean.get('commit_stage_c');
            console.log('selected commit stage: ' + CommitStageSelected);
            console.log('saved commit stage: ' + CommitStageSaved);

            let SavedStageUpsideOrCommit = 
            ("Upside" == CommitStageSaved || "Commit" == CommitStageSaved);

            if ("Funnel" == CommitStageSelected && SavedStageUpsideOrCommit) {
                errors['commit_stage_c'] = errors['commit_stage_c'] || {};
                errors['commit_stage_c'].check_commit_stages = true;

                app.alert.show('message-id', {
                    level: 'error',
                    messages: 'Commit Stage cannot be changed from Upside or from Commit to Funnel',
                    autoClose: false
                });
            }

            callback(null, fields, errors);
    }});
},

The problem is that the validation error is thrown after the opportunity is already saved. I get a "success" pop-up saying "Saved", then I get an "error" pop-up with the validation error message. The commit stage field does not get highlighted.

I'm guessing that the validation task takes too long to run, probably due to the OpportunityBean.fetch function, so that the record is saved before the validation task has had time to throw an error. Is there a way to either delay saving, or to speed up getting data from the bean? Or, is the problem something different altogether?


Solution

  • Thank you to all respondents! The only thing that worked for me is this:

    let changedFields = this.model.changedAttributes(this.model.getSynced());
    let CommitStageSaved = changedFields.commit_stage_c;
    

    When I tried the approach in @Sheikh Rahat Ali's answer, I got CommitStageSaved = undefined. When I tried @Jay's approach and restricted the fetch function to only the commit_stage_c field, I got the same problem with the record being saved before the validation ran. I found out about the changedAttributes function from a response to my question on the Sugar developer forum.