{"id":6455,"date":"2021-12-09T04:38:27","date_gmt":"2021-12-09T04:38:27","guid":{"rendered":"https:\/\/www.greytrix.com\/blogs\/salesforce\/?p=6455"},"modified":"2021-12-09T04:39:27","modified_gmt":"2021-12-09T04:39:27","slug":"custom-approval-process-part-2","status":"publish","type":"post","link":"https:\/\/www.greytrix.com\/blogs\/salesforce\/2021\/12\/09\/custom-approval-process-part-2\/","title":{"rendered":"Custom Approval Process in Salesforce \u2013 Part 2"},"content":{"rendered":"\n<p>In continuation to our\u00a0<a rel=\"noreferrer noopener\" href=\"https:\/\/www.greytrix.com\/blogs\/salesforce\/2021\/12\/08\/custom-approval-process-in-salesforce-part-1\/\" data-type=\"URL\" data-id=\"https:\/\/www.greytrix.com\/blogs\/salesforce\/2021\/12\/08\/custom-approval-process-in-salesforce-part-1\/\" target=\"_blank\">previous blog<\/a>, where we worked on the UI for Approver. In this blog, we will be working on the functionality &amp; also build UI.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong><em>ApproverOrReject.cmp<\/em><\/strong><\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;aura:component controller=\"QuoteApprovalProcessController\" implements=\"force:lightningQuickActionWithoutHeader,force:hasRecordId,force:appHostable,lightning:actionOverride\" access=\"global\" >\n            &lt;!--&lt;aura:handler name=\"reinit\" value=\"{!this}\" action=\"{!c.reInit}\" \/>-->\n            &lt;aura:attribute name=\"recordId\" type=\"Id\" default=\"\"\/>\n            &lt;aura:attribute name=\"comment\" type=\"String\" default=\"\" \/>\n            &lt;aura:attribute name=\"loaded\" type=\"Boolean\" default=\"true\" \/>\n            &lt;aura:attribute name=\"Spinner\" type=\"Boolean\" default=\"false\"\/>\n            &lt;aura:attribute name=\"LoadMessage\" type=\"string\" default=\"Loading..\"\/>\n            &lt;aura:attribute name=\"showProgressbar\" type=\"Boolean\" default=\"false\"\/>\n            &lt;aura:attribute name=\"isOpen\" type=\"Boolean\" default=\"false\"\/>\n            &lt;aura:attribute name=\"filetype\" type=\"List\" default=\"&#91;'.pdf']\" \/>\n            &lt;aura:attribute name=\"multiple\" type=\"Boolean\" default=\"true\" \/>\n            &lt;aura:attribute name=\"disabled\" type=\"Boolean\" default=\"true\" \/>\n    \t    &lt;aura:attribute name=\"encryptedToken\" type=\"String\" \/>\n            &lt;aura:attribute name=\"FileList\" type=\"String\"\/>\n            &lt;ltng:require scripts=\"{!$Resource.CommonFunction}\" afterScriptsLoaded=\"{!c.doInit}\" \/>\n    \t\t&lt;c:spinner Spinner=\"{! v.Spinner}\" LoadMessage=\"{! v.LoadMessage}\" showProgressbar=\"{! v.showProgressbar}\" progress=\"{! v.progress}\"\/>\n            &lt;aura:html tag=\"style\"> \n                .cuf-content \n                {\n                padding: 0 0rem\t!important;\n                }\n                &lt;!-- MOD -->\n                .slds-p-around--medium \n                {\n                padding: 0rem !important;\n                }        \n                \n                .slds-modal__content\n                {\n                \/\/\toverflow-y:hidden !important;\n                height:unset !important;\n                max-height:unset !important;\n                }       \n                \n                .GUMUStyle \n                {\n                z-index: 10000;\n                position: fixed;\n                visibility: visible;\n                opacity: 1;\n                height: 100%;\n                width: 100%;\n                max-height: 250px;\n                background-color: rgba(255, 255, 255, 0.75) !important;\n                }\n    \n            &lt;\/aura:html>\n    &lt;aura:if isTrue=\"{!v.isOpen}\">\n            &lt;section role=\"dialog\" tabindex=\"-1\" aura:id=\"Modalbox\" aria-labelledby=\"modal-heading-01\" aria-modal=\"true\" aria-describedby=\"modal-content-id-1\" class=\"slds-modal slds-fade-in-open\">\n                &lt;div class=\"slds-modal__container slds-col slds-size_1-of-1 slds-small-size_1-of-1 slds-medium-size_1-of-1\">\n                    &lt;header class=\"slds-modal__header\">\n                        &lt;h2 id=\"modal-heading-01\" class=\"slds-text-heading_medium slds-hyphenate\">Approval \/ Reject&lt;\/h2> \n                    &lt;\/header> \n                    &lt;div class=\"slds-modal__content slds-p-around_medium\" id=\"modal-content-id-1\">\n                        &lt;div class=\"slds-grid slds-wrap\"> \n                                &lt;div class=\"slds-col slds-size_1-of-1 slds-small-size_1-of-1 slds-medium-size_1-of-1 inputArea\">\n                                    &lt;lightning:textarea name=\"comment\" label=\"Comments\" value=\"{!v.comment}\" placeholder=\"Type here...\" \/>\n                                &lt;\/div>\n                         &lt;\/div>\n                         &lt;div class=\"slds-text-align_center slds-p-top_small\">\n                               &lt;!--&lt;aura:if isTrue=\"{! v.loaded }\">-->\n                                      &lt;!--&lt;footer class=\"slds-modal__footer slds-m-top_x-small slds-m-bottom_medium slds-m-horizontal_none\">--> \n                        \t\t\t\t\t&lt;div class=\"slds-m-top_x-small slds-m-bottom_medium slds-m-horizontal_none slds-float_right\">\n       \t\t\t\t\t\t\t\t\t\t\t&lt;lightning:button class=\"slds-button slds-button_neutral slds-float_bottom\" label=\"Cancel\" onclick=\"{!c.closeModal }\"\/> \n                                                &lt;lightning:button class=\"slds-button \" variant=\"brand\" label=\"Approve\" onclick=\"{!c.handleApproval}\" \/>\n                                                &lt;lightning:button class=\"slds-button slds-button_destructive\" variant=\"brand\" label=\"Reject\" onclick=\"{!c.handleRejection}\" \/>\n                                            &lt;\/div>\n                                      &lt;!--&lt;\/footer>-->\n                               &lt;!--&lt;\/aura:if>-->\n                        &lt;\/div>\n                    &lt;!--&lt;\/div>-->\n                &lt;\/div>\n                &lt;\/div>\n            &lt;\/section>\n    &lt;\/aura:if>\n&lt;\/aura:component><\/code><\/pre>\n\n\n\n<p>The above code will create the UI for the Approver Screen as shown below,<\/p>\n\n\n\n<center><a href=\"https:\/\/www.greytrix.com\/blogs\/salesforce\/wp-content\/uploads\/2021\/12\/Approver-Screen.png\" target=\"_blank\" rel=\"noreferrer noopener\"><img decoding=\"async\" class=\"size-full\" style=\"border: 1px solid #A9A9A9; padding: 2px; margin: 2px; align: center;\" src=\"https:\/\/www.greytrix.com\/blogs\/salesforce\/wp-content\/uploads\/2021\/12\/Approver-Screen.png\" alt=\"Approver Screen\"><\/a><\/center>\n<font size=\"2\"><center><i>Approver Screen<\/i><\/center><\/font>\n\n\n\n<p>Here Approver can write their comment prior to Approval or Rejection<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><strong>Approve<\/strong>: Where Approver can approve the request for Approval with comment.<\/li><li><strong>Reject:<\/strong> Where Approver can reject the request for Approval with comment.<\/li><li><strong>Comment<\/strong>: Where Approver can write their comment regarding notes or reason to reject.<\/li><\/ul>\n\n\n\n<h4 class=\"wp-block-heading\"><strong><em>ApproverOrRejectController.cmp<\/em><\/strong><\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code>({\r\n    doInit : function(component, event, helper) {\r\n        helper.approvalStatusChecker(component, event, helper);\r\n    },\r\n                           \r\n    handleApproval : function (component, event, helper) \r\n    {\r\n        helper.goToApproval(component, event, helper,'Approved');\r\n    },\r\n    handleRejection : function (component, event, helper)\r\n    {\r\n        helper.goToApproval(component, event, helper,'Rejected');\r\n    },\r\n    closeModal : function(component,event,helper)\r\n    {    \r\n        component.set(\"v.isOpen\", false);\r\n        $A.get(\"e.force:closeQuickAction\").fire();\r\n    },    \r\n    handleUploadFinished: function (cmp, event,helper) \r\n    {\r\n       \r\n        var uploadedFiles = event.getParam(\"files\");\r\n        \/\/alert (\"uploadedFiles\"+uploadedFiles);\r\n        cmp.set(\"v.FileList\",uploadedFiles);\r\n        var showToast = $A.get(\"e.force:showToast\");\r\n        showToast.setParams({\r\n            title : 'Files Load',\r\n            message : 'Files Loaded Successfully.',\r\n            duration:' 10000',\r\n            type : 'success',\r\n            mode: 'dismissible'\r\n        });\r\n        showToast.fire();\r\n        $A.get('e.force:refreshView').fire(); \r\n       \r\n    }\r\n})\r<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\"><strong><em>ApproverOrRejectHelper.cmp<\/em><\/strong><\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code>({\r\n\tapprovalStatusChecker : function(component, event, helper)\r\n    {\r\n        debugger;\r\n        var getID = component.get(\"v.recordId\");\r\n        \/\/alert('getID'+getID)\r\n        var action = component.get('c.ApprovalRequestCheck');\r\n        component.set(\"v.Spinner\", true);\r\n        action.setParams({\r\n            \"recordId\": component.get(\"v.recordId\")\r\n        });\r\n        action.setCallback(this, function(response) \r\n          {\r\n            component.set(\"v.Spinner\", false);  \r\n            var state = response.getState();\r\n            \/\/alert('state::'+state);\r\n            if(state === \"SUCCESS\") \r\n            {\r\n                var resp = response.getReturnValue();\r\n                \/\/alert('resp::'+resp);\r\n                if(resp == 'failure')\r\n                {\r\n                    \/\/alert('response:::'+resp);\r\n                    helper.showToast(component, event, helper, 'warning', 'There is no request for Approval','warning Message');\r\n                    $A.get(\"e.force:closeQuickAction\").fire(); \r\n                }\r\n                else if(resp == 'success')\r\n                {\r\n                     helper.UserChecker(component, event, helper);\r\n                }\t\r\n            } \r\n              else \r\n              {\r\n                var errors = response.getError();\r\n                if (errors) \r\n                {\r\n                    if (errors&#91;0] &amp;&amp; errors&#91;0].message) \r\n                    {\r\n                        console.log(\"Error message: \" +errors&#91;0].message);\r\n                    }\r\n                } \r\n                  else \r\n                    {\r\n                        \/\/alert(\"Unknown error\");\r\n                    }\r\n                console.log('Problem getting account, response state: ' + state);\r\n            }\r\n        });\r\n        $A.enqueueAction(action);        \r\n    },\r\n    \r\n    UserChecker : function(component, event, helper)\r\n    {\r\n        debugger;\r\n        var getID = component.get(\"v.recordId\");\r\n        \/\/alert('getID'+getID)\r\n        var action = component.get('c.UserCheck');\r\n        component.set(\"v.Spinner\", true);\r\n        action.setParams({\r\n            \"recordId\": component.get(\"v.recordId\")\r\n        });\r\n        action.setCallback(this, function(response) \r\n          {\r\n            component.set(\"v.Spinner\", false);  \r\n            var state = response.getState();\r\n            \/\/alert('state::'+state);\r\n            if(state === \"SUCCESS\") \r\n            {\r\n                var resp = response.getReturnValue();\r\n                \/\/alert('resp::'+resp);\r\n                if(resp == 'Userfailure')\r\n                {\r\n                    \/\/alert('response:::'+resp);\r\n                    helper.showToast(component, event, helper, 'error', 'Not A valid Approver','Error Message');\r\n                    $A.get(\"e.force:closeQuickAction\").fire(); \r\n                }\r\n                else if(resp == 'success')\r\n                {\r\n                    component.set(\"v.isOpen\", true);\r\n                }\t\r\n            } \r\n              else \r\n              {\r\n                var errors = response.getError();\r\n                if (errors) \r\n                {\r\n                    if (errors&#91;0] &amp;&amp; errors&#91;0].message) \r\n                    {\r\n                        console.log(\"Error message: \" +errors&#91;0].message);\r\n                    }\r\n                } \r\n                  else \r\n                    {\r\n                        \/\/alert(\"Unknown error\");\r\n                    }\r\n                console.log('Problem getting account, response state: ' + state);\r\n            }\r\n        });\r\n        $A.enqueueAction(action);        \r\n    },\r\n    goToApproval : function(component, event, helper,State)\r\n    {\r\n        debugger;\r\n        component.set('v.loaded', false);\r\n        var getID = component.get(\"v.recordId\");\r\n        \/\/alert('Id:::'+getID);\r\n        var getComment = component.get(\"v.comment\");\r\n        \/\/alert('comments:::'+getComment);\r\n        var action = component.get('c.ApprovedOrReject');\r\n        component.set(\"v.Spinner\", true);\r\n        action.setParams({\r\n                            \"recordId\": component.get(\"v.recordId\"), \r\n                            \"comment\": component.get(\"v.comment\"),\r\n                            \"State\" : State,\r\n        \t\t\t\t});\r\n        console.log('action::'+JSON.stringify(action));\r\n        action.setCallback(this, function(response) \r\n         {\r\n            component.set(\"v.Spinner\", false); \r\n            var state = response.getState();\r\n            if(state === \"SUCCESS\") \r\n            {\r\n                var resp = response.getReturnValue();\r\n                \/\/alert('response:::'+resp);\r\n                if(!$A.util.isEmpty(resp) &amp;&amp; resp == 'success') \r\n                {\r\n                    helper.showToast(component, event, helper, 'success', 'Your Responce successfully submitted!', 'Success Message');\r\n                    $A.get(\"e.force:closeQuickAction\").fire();\r\n                    $A.get('e.force:refreshView').fire();\r\n                }\r\n                if((!$A.util.isEmpty(resp)) &amp;&amp; (!$A.util.isUndefined(resp)) &amp;&amp; resp.includes('first error:')) {\r\n                    var showErrorList = &#91;];\r\n                    showErrorList = resp.split('first error: ');\r\n                    helper.showToast(component, event, helper, 'error', showErrorList&#91;1], 'Error Message');\r\n                    var erromessage = showErrorList&#91;1];\r\n                    \/\/alert('erromessage==='+erromessage);\r\n                    $A.get(\"e.force:closeQuickAction\").fire();\r\n                }\r\n                if(resp == 'failure')\r\n                {\r\n                    helper.showToast(component, event, helper, 'warning', 'No Active Approval Process Found.','Error Message');\r\n                    $A.get(\"e.force:closeQuickAction\").fire();                    \r\n                }\r\n                component.set('v.loaded', false);\r\n            } else {\r\n                component.set('v.loaded', true);\r\n                var errors = response.getError();\r\n                if (errors) {\r\n                    if (errors&#91;0] &amp;&amp; errors&#91;0].message) {\r\n                        console.log(\"Error message: \" +\r\n                                    errors&#91;0].message);     \r\n                    }\r\n                } else {\r\n                    console.log(\"Unknown error\");\r\n                }\r\n                console.log('Problem getting account, response state: ' + state);\r\n            }\r\n        });\r\n        $A.enqueueAction(action);\r\n    }, \r\n    \r\n    showToast : function(component, event, helper, messageType, message, title) {\r\n        var toastEvent = $A.get(\"e.force:showToast\");\r\n        \/\/alert('toastEvent'+toastEvent);\r\n        toastEvent.setParams({\r\n            title : title,\r\n            message: message,\r\n            messageTemplate: '',\r\n            duration:' 10000',\r\n            key: 'info_alt',\r\n            type: messageType,\r\n            mode: 'dismissible'\r\n        });\r\n        toastEvent.fire();\r\n    }\r\n})\r<\/code><\/pre>\n\n\n\n<p>The above code will update data from custom object Named as <strong>&#8220;ApprovalInstance__c<\/strong>&#8221; where based on Approver action, record has been Updated.<\/p>\n\n\n\n<p>We hope you may find this blog resourceful and helpful. If you still have concerns and need more help, please contact us at <a href=\"mailto:salesforce@greytrix.com\">salesforce@greytrix.com<\/a>.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p>References &#8211; <a rel=\"noreferrer noopener\" href=\"https:\/\/www.biswajeetsamal.com\/blog\/custom-file-upload-in-salesforce-lightning-component\/\" data-type=\"URL\" data-id=\"https:\/\/www.biswajeetsamal.com\/blog\/custom-file-upload-in-salesforce-lightning-component\/\" target=\"_blank\">Custom file upload in Salesforce lightning component<\/a> &amp; <a href=\"https:\/\/www.jitendrazaa.com\/blog\/salesforce\/dynamic-approval-process-based-on-the-apex-and-trigger\/\" data-type=\"URL\" data-id=\"https:\/\/www.jitendrazaa.com\/blog\/salesforce\/dynamic-approval-process-based-on-the-apex-and-trigger\/\" target=\"_blank\" rel=\"noreferrer noopener\">Dynamic Approval Process based on Apex and Trigger<\/a><\/p><\/blockquote>\n\n\n\n<p style=\"text-align: justify\"><b>About Us<\/b><\/br>\n<p><a href=\"https:\/\/www.greytrix.com\/\">Greytrix<\/a> \u2013 a globally recognized and one of the oldest Sage Development Partner and a Salesforce Product development partner offers a wide variety of integration products and services to the end users as well as to the Partners and Sage PSG across the globe. We offer Consultation, Configuration, Training and support services in out-of-the-box functionality as well as customizations to incorporate custom business rules and functionalities that require apex code incorporation into the Salesforce platform.<br><br> Greytrix has some unique solutions for Cloud CRM such as <a href=\"\">Salesforce Sage integration<\/a> for <a href=\"https:\/\/www.greytrix.com\/sage-x3-erp\/integration\/\">Sage X3<\/a>, <a href=\"https:\/\/www.greytrix.com\/salesforce-cloud-services\/sage-100-integration\/\">Sage 100<\/a> and <a href=\"https:\/\/www.greytrix.com\/salesforce-cloud-services\/sage-300-integration\/\">Sage 300 (Sage Accpac)<\/a>. We also offer best-in-class Cloud CRM <a href=\"https:\/\/www.greytrix.com\/salesforce-cloud-services\/crm-development\/\">Salesforce customization and development services<\/a> along with services such as Salesforce <a href=\"https:\/\/www.greytrix.com\/salesforce-cloud-services\/data-migration-support\/\">Data Migration<\/a>, <a href=\"https:\/\/www.greytrix.com\/salesforce-cloud-services\/crm-development\/\">Integrated App development<\/a>, Custom App development and Technical Support business partners and end users. Salesforce Cloud CRM integration offered by Greytrix works with Lightning web components and supports standard opportunity workflow. Greytrix GUMU&#x2122; integration for Sage ERP \u2013 Salesforce is a 5-star rated app listed on <a href=\"https:\/\/appexchange.salesforce.com\/appxListingDetail?listingId=a0N30000000psM5EAI\" target=\"_blank\" rel=\"noopener\">Salesforce AppExchange<\/a>.<br> The GUMU&#x2122; Cloud framework by Greytrix forms the backbone of cloud integrations that are managed in real-time for processing and execution of application programs at the click of a button.<br><br> For more information on our Salesforce products and services, contact us at <a href=\"mailto:salesforce@greytrix.com\">salesforce@greytrix.com<\/a>. We will be glad to assist you.<\/p>\n\n\n\n<p><strong>Related Posts<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/www.greytrix.com\/blogs\/salesforce\/2021\/10\/06\/how-to-use-email-template-in-standard-salesforce-flow\/\">How to use Email Template in Standard Salesforce Flow<\/a><\/li><li><a href=\"https:\/\/www.greytrix.com\/blogs\/salesforce\/2021\/08\/18\/how-to-create-a-dynamic-multi-filter-object-in-salesforce-part-ii\/\">Create a dynamic multi-filter object in Salesforce-Part II<\/a><\/li><li><a href=\"https:\/\/www.greytrix.com\/blogs\/salesforce\/2021\/11\/18\/how-to-create-and-implement-custom-salesforce-notification-using-process-builder\/\">How to Create (and Implement) Custom Salesforce Notification using Process Builder<\/a><\/li><\/ul>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In continuation to our\u00a0previous blog, where we worked on the UI for Approver. In this blog, we will be working on the functionality &amp; also build UI. ApproverOrReject.cmp The above code will create the UI for the Approver Screen as shown below, Approver Screen Here Approver can write their comment prior to Approval or Rejection\u2026 <span class=\"read-more\"><a href=\"https:\/\/www.greytrix.com\/blogs\/salesforce\/2021\/12\/09\/custom-approval-process-part-2\/\">Read More &raquo;<\/a><\/span><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[1226,1228,1227,206,1122,1055,1133,207,208,1050,916,651,1032],"class_list":["post-6455","post","type-post","status-publish","format-standard","hentry","category-salesforce-srv","tag-approval-process","tag-approval-process-validation","tag-custom-approval-process","tag-lightning","tag-lightning-application","tag-lightning-aura-component","tag-lightning-basic","tag-lightning-basics","tag-lightning-component","tag-lightning-web-component","tag-salesforce-custom-object","tag-salesforce-lightning-component","tag-salesforce-lightning-component-bundle"],"_links":{"self":[{"href":"https:\/\/www.greytrix.com\/blogs\/salesforce\/wp-json\/wp\/v2\/posts\/6455","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.greytrix.com\/blogs\/salesforce\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.greytrix.com\/blogs\/salesforce\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.greytrix.com\/blogs\/salesforce\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.greytrix.com\/blogs\/salesforce\/wp-json\/wp\/v2\/comments?post=6455"}],"version-history":[{"count":3,"href":"https:\/\/www.greytrix.com\/blogs\/salesforce\/wp-json\/wp\/v2\/posts\/6455\/revisions"}],"predecessor-version":[{"id":6462,"href":"https:\/\/www.greytrix.com\/blogs\/salesforce\/wp-json\/wp\/v2\/posts\/6455\/revisions\/6462"}],"wp:attachment":[{"href":"https:\/\/www.greytrix.com\/blogs\/salesforce\/wp-json\/wp\/v2\/media?parent=6455"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.greytrix.com\/blogs\/salesforce\/wp-json\/wp\/v2\/categories?post=6455"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.greytrix.com\/blogs\/salesforce\/wp-json\/wp\/v2\/tags?post=6455"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}