Approval Comment is Duplicating

Aparna Gurav
Tera Contributor

Hello Team,

 

Need your help...

 

When an approver rejects the approval and adds a comment, the comment appears twice in the activity stream on the service portal. Even after deactivating the 'approval events (task)' business rule, the issue persists. Could you please provide suggestions to resolve this issue?

 

AparnaGurav_0-1709195692990.png

 

1 ACCEPTED SOLUTION

Sohail Khilji
Kilo Patron
Kilo Patron

Hi @Aparna Gurav ,

 

The issue seems to be happening because of the record watcher observing the approval record.

You may comment the below line in client script and validate.

spUtil.recordWatch($scope, "sysapproval_approver", "state=requested^sys_id=" + c.data.sys_id);

 

Alternatively, you can keep record watcher and change the server side and client side code as mentioned below.

Widget Server Side Script:

(function() {
    data.actionPreventedMsg = gs.getMessage("Update failed");
    var gr = $sp.getRecord();
    if (gr == null || !gr.isValid()) {
        data.isValid = false;
        return;
    }

    data.isValid = true;
    data.isMine = isApprovalMine(gr);

    var approverDisplay = gr.approver.getDisplayValue();
    if (!data.isMine && approverDisplay)
        data.approverDisplay = approverDisplay;

    if (approverDisplay) {
        data.approvedMsg = gs.getMessage("Approved by {0}", approverDisplay);
        data.rejectedMsg = gs.getMessage("Rejected by {0}", approverDisplay);
    } else {
        data.approvedMsg = gs.getMessage("Approved");
        data.rejectedMsg = gs.getMessage("Rejected");
    }
    if (input && input.op && data.isMine && gr.state != "rejected") {
        gr.state = input.op;
        if (gr.state == "rejected") {
            gr.comments = input.comments; //Custom code (DFCT0010123)
        }
        data.updateID = gr.update();
        if (GlideStringUtil.nil(data.updateID)) {
            // update failed so fetch again for correct values
            gr = $sp.getRecord();
        }
        data.op = "";
    }

    var fields = $sp.getFields(gr, 'state,sys_created_on');

    if (gr.sys_mod_count > 0)
        fields.push($sp.getField(gr, 'sys_updated_on'));

    data.fields = fields;
    data.state = gr.state.toString();
    data.sys_updated_on = gr.sys_updated_on.toString();
    data.sys_id = gr.getUniqueValue();
    data.table = gr.getTableName();
    data.label = getRecordBeingApproved(gr).getLabel();
    data.esignature = {
        username: gs.getUserName(),
        userSysId: gs.getUserID(),
        e_sig_required: checkESig(gr)
    };

    function checkESig(approvalGR) {
        var esigRegistryGR = new GlideRecord("e_signature_registry");
        if (!esigRegistryGR.isValid())
            return false;

        var table = approvalGR.getValue("source_table");
        if (!table)
            table = approvalGR.sysapproval.sys_class_name;
        if (!table)
            return false;

        esigRegistryGR.addQuery("enabled", "true");
        esigRegistryGR.addQuery("table_name", table);
        esigRegistryGR.query();
        return esigRegistryGR.hasNext();
    }

    function getRecordBeingApproved(gr) {
        if (!gr.sysapproval.nil())
            return gr.sysapproval.getRefRecord();

        return gr.document_id.getRefRecord();
    }
})();

 

And client side script as below:

function($scope, spUIActionsExecuter, spUtil, spModal) {
    var c = this;

    var ESIGNATURE = {
        "approved": "cbfe291147220100ba13a5554ee4904d",
        "rejected": "580f711147220100ba13a5554ee4904b"
    };

    spUtil.recordWatch($scope, "sysapproval_approver", "state=requested^sys_id=" + c.data.sys_id);
    c.approvalInProgress = false;
    c.action = function(state) {
        if (c.data.esignature.e_sig_required) {
            var requestParams = {
                username: c.data.esignature.username,
                userSysId: c.data.esignature.userSysId
            };
            spUIActionsExecuter.executeFormAction(ESIGNATURE[state], "sysapproval_approver", c.data.sys_id, [], "", requestParams).then(function(response) {});
        } else {
            if (state == "rejected") {
                c.approvalInProgress = true;
                spModal.prompt("Provide a reason for rejecting this approval").then(function(newComments) {
                    c.data.comments = newComments;
                    c.data.op = state;
                    c.approvalInProgress = false;
                    c.server.update().then(function() {
                        if (!c.data.updateID) // update failed
                            spUtil.addErrorMessage(c.data.actionPreventedMsg);
                        else
                            c.data.state = state;
                    });
                });
            } else {
                c.approvalInProgress = true;
                c.data.op = state;
                c.server.update().then(function() {
                    c.approvalInProgress = false;
                    if (!c.data.updateID) // update failed
                        spUtil.addErrorMessage(c.data.actionPreventedMsg);
                    else
                        c.data.state = state;
                });
            }
        }
    }
}

 

 

In the client side code, I added c.approvalInProgress assignment lines, because using this OOB widget is making sure that, if the end user clicked on the Approve or Reject button till the time server processes and responds, system is not letting user click on the buttons again. So it is trying to avoid duplicate actions.


☑️ Please mark responses as HELPFUL or ACCEPT SOLUTION to assist future users in finding the right solution....

LinkedIn - Lets Connect

View solution in original post

1 REPLY 1

Sohail Khilji
Kilo Patron
Kilo Patron

Hi @Aparna Gurav ,

 

The issue seems to be happening because of the record watcher observing the approval record.

You may comment the below line in client script and validate.

spUtil.recordWatch($scope, "sysapproval_approver", "state=requested^sys_id=" + c.data.sys_id);

 

Alternatively, you can keep record watcher and change the server side and client side code as mentioned below.

Widget Server Side Script:

(function() {
    data.actionPreventedMsg = gs.getMessage("Update failed");
    var gr = $sp.getRecord();
    if (gr == null || !gr.isValid()) {
        data.isValid = false;
        return;
    }

    data.isValid = true;
    data.isMine = isApprovalMine(gr);

    var approverDisplay = gr.approver.getDisplayValue();
    if (!data.isMine && approverDisplay)
        data.approverDisplay = approverDisplay;

    if (approverDisplay) {
        data.approvedMsg = gs.getMessage("Approved by {0}", approverDisplay);
        data.rejectedMsg = gs.getMessage("Rejected by {0}", approverDisplay);
    } else {
        data.approvedMsg = gs.getMessage("Approved");
        data.rejectedMsg = gs.getMessage("Rejected");
    }
    if (input && input.op && data.isMine && gr.state != "rejected") {
        gr.state = input.op;
        if (gr.state == "rejected") {
            gr.comments = input.comments; //Custom code (DFCT0010123)
        }
        data.updateID = gr.update();
        if (GlideStringUtil.nil(data.updateID)) {
            // update failed so fetch again for correct values
            gr = $sp.getRecord();
        }
        data.op = "";
    }

    var fields = $sp.getFields(gr, 'state,sys_created_on');

    if (gr.sys_mod_count > 0)
        fields.push($sp.getField(gr, 'sys_updated_on'));

    data.fields = fields;
    data.state = gr.state.toString();
    data.sys_updated_on = gr.sys_updated_on.toString();
    data.sys_id = gr.getUniqueValue();
    data.table = gr.getTableName();
    data.label = getRecordBeingApproved(gr).getLabel();
    data.esignature = {
        username: gs.getUserName(),
        userSysId: gs.getUserID(),
        e_sig_required: checkESig(gr)
    };

    function checkESig(approvalGR) {
        var esigRegistryGR = new GlideRecord("e_signature_registry");
        if (!esigRegistryGR.isValid())
            return false;

        var table = approvalGR.getValue("source_table");
        if (!table)
            table = approvalGR.sysapproval.sys_class_name;
        if (!table)
            return false;

        esigRegistryGR.addQuery("enabled", "true");
        esigRegistryGR.addQuery("table_name", table);
        esigRegistryGR.query();
        return esigRegistryGR.hasNext();
    }

    function getRecordBeingApproved(gr) {
        if (!gr.sysapproval.nil())
            return gr.sysapproval.getRefRecord();

        return gr.document_id.getRefRecord();
    }
})();

 

And client side script as below:

function($scope, spUIActionsExecuter, spUtil, spModal) {
    var c = this;

    var ESIGNATURE = {
        "approved": "cbfe291147220100ba13a5554ee4904d",
        "rejected": "580f711147220100ba13a5554ee4904b"
    };

    spUtil.recordWatch($scope, "sysapproval_approver", "state=requested^sys_id=" + c.data.sys_id);
    c.approvalInProgress = false;
    c.action = function(state) {
        if (c.data.esignature.e_sig_required) {
            var requestParams = {
                username: c.data.esignature.username,
                userSysId: c.data.esignature.userSysId
            };
            spUIActionsExecuter.executeFormAction(ESIGNATURE[state], "sysapproval_approver", c.data.sys_id, [], "", requestParams).then(function(response) {});
        } else {
            if (state == "rejected") {
                c.approvalInProgress = true;
                spModal.prompt("Provide a reason for rejecting this approval").then(function(newComments) {
                    c.data.comments = newComments;
                    c.data.op = state;
                    c.approvalInProgress = false;
                    c.server.update().then(function() {
                        if (!c.data.updateID) // update failed
                            spUtil.addErrorMessage(c.data.actionPreventedMsg);
                        else
                            c.data.state = state;
                    });
                });
            } else {
                c.approvalInProgress = true;
                c.data.op = state;
                c.server.update().then(function() {
                    c.approvalInProgress = false;
                    if (!c.data.updateID) // update failed
                        spUtil.addErrorMessage(c.data.actionPreventedMsg);
                    else
                        c.data.state = state;
                });
            }
        }
    }
}

 

 

In the client side code, I added c.approvalInProgress assignment lines, because using this OOB widget is making sure that, if the end user clicked on the Approve or Reject button till the time server processes and responds, system is not letting user click on the buttons again. So it is trying to avoid duplicate actions.


☑️ Please mark responses as HELPFUL or ACCEPT SOLUTION to assist future users in finding the right solution....

LinkedIn - Lets Connect