Skip to Content
Technical Articles

Extend SAP GRC Access Approval Fiori Application for “On Hold” functionality

Introduction:

The SAP GRC Webdynpro application (GRFN_POWL_INBOX) for Security requests approvals contains On Hold functionality. Using this functionality the Approver of Security request can place the request on hold .

However in the Fiori application for GRC Approvals (GRC_ACCESSREQUEST_APPROVE) this “On Hold” functionality does not exist. Hence when migrating to GRC Fiori application , client may ask to add this functionality .Reject functionality is achieved by deselecting the roles and submitting the request.

Steps :

To add On Hold and Release ( requests which are on hold to pending status) functionality to the GRC Approvals Fiori application , we will need to modify the oData and SAP UI5 application.

GRC OData:

  1.  Open SEGW tcode in GRC backed. Search for project GRC_ACCESSREQUEST_APPROVE  Right click and copy the project as Z project of the existing Approval application by naming as ZGRC_ACCESSREQUEST_APPROVE
  2. The runtime artifacts will be created automatically.
  3. Go to ABAP workbench to check Class ZCL_ZGRC_ACREQ_APPROVE_DPC_EXT
  4. Under Methods- Inherited Methods,  redefine the method “Requests_Update_Entity”.
  5. Add the code as below to fill the required ABAP structure
Fill structures to put on hold
        LOOP AT li_reqlineitm INTO lwa_reqlineitm.
*       STATUS
          CLEAR lwa_wi_status.
          lwa_wi_status-path_id         = ls_results-path_id.
          lwa_wi_status-path_seq        = ls_results-path_seq.
          lwa_wi_status-stage_id        = ls_results-stage_seqnr.
          lwa_wi_status-stage_config_id = ls_results-stage_config_id.
          lwa_wi_status-stage_is_first  = abap_true.
          lwa_wi_status-stage_is_last   = abap_true.
          lwa_wi_status-wi_id           = ls_request_output_data-wi_group.
          lwa_wi_status-line_item_id    = '001'.
*       Item data
          CLEAR lwa_lineitem.
          lwa_lineitem-req_id            = lwa_reqlineitm-req_id.
          lwa_lineitem-itemnum           = lwa_reqlineitm-itemnum.
          lwa_lineitem-valid_from        = lwa_reqlineitm-valid_from.
          lwa_lineitem-valid_to          = lwa_reqlineitm-valid_to.
          lwa_lineitem-prov_action       = lwa_reqlineitm-prov_action.
          lwa_lineitem-line_item_type    = lwa_reqlineitm-prov_item_type.
          lwa_lineitem-line_item_display = lwa_reqlineitm-item_name.
          IF NOT lo_line_item_data IS BOUND.
            CREATE DATA lo_line_item_data TYPE grac_s_request_msmp_lineitem.
            ASSIGN lo_line_item_data->* TO <fs_item>.
          ENDIF.
          <fs_item> = lwa_lineitem.
          lwa_wi_status-line_item_data = lo_line_item_data.
        ENDLOOP.

6. Add the code to handle onHold event

*     Put the request ON HOLD

        CASE ls_request_output_data-status.

          WHEN 'ON HOLD'.
            TRY.
*       Salida de datos
                ls_request_output_data-status = 'ON HOLD'.
                er_entity =  ls_request_output_data.
                CALL METHOD cl_grfn_msmp_approval_api=>hold_instance
                  EXPORTING
                    it_wi_status   = it_wi_status
                    iv_user        = lv_uname
                    it_app_msgs    = it_app_msgs
                    iv_header_data = lo_header
                    iv_admin_mode  = abap_false.
              CATCH cx_grfn_msmp_wrong_call .
              CATCH cx_grfn_msmp_locked .
              CATCH cx_grfn_msmp_concurrent_change .
              CATCH cx_grfn_msmp.
            ENDTRY.

 

SAP UI5 Application :

  1. In WEBIDE Create Extension of the standard project grc_accreq_approval_ext
  2. In the “RequestDetailCustom.controller.js” add a button for Hold and Release in onInit() function . Hold Button will call handleonHold() and Release button will call handleonRelease() functions.
myNEWButton: {},buttonList: [{sId: "Forward",sI18nBtnTxt: "On Hold",onBtnPressed: function(e) {l.handleonHold();}}, {sId: "Release",sI18nBtnTxt: "Release",onBtnPressed: function(e) {l.handleRelease();}

 

Buttons will look as below in the application.

 

  1. Add the code for both functions as below :
	handleonHold: function() {
		var that = this;
		var D = "";
		var that = this;
		var oModel = that.getView().getModel();
		var D = "";

		D = new sap.m.Dialog({
			title: 'Confirm',
			type: 'Message',
			content: new sap.m.Text({
				text: 'Are you sure you want to keep the request "On Hold"?'
			}),
			beginButton: new sap.m.Button({
				text: "OK",
				press: function() {

					var oModel = that.getView().getModel();
					var bindingContext = that.getView().getBindingContext();
					var object = bindingContext.getObject();
					var RequestNumber = bindingContext.getProperty("RequestNumber");
					var Approver = bindingContext.getProperty("Approver");
					var WorkItemGroup = bindingContext.getProperty("WorkItemGroup");
					object.Status = 'ON HOLD';
					oModel.update("/Requests(WorkItemGroup='" + WorkItemGroup + "',Approver='" + Approver + "',RequestNumber='" + RequestNumber +
						"')", object, null,
						function(oResponse) {
							//Function for success
							sap.m.MessageBox.success("Request is kept on hold successfully", {
								actions: [sap.m.MessageBox.Action.OK],
								onClose: function(oAction) {
									if (oAction === sap.m.MessageBox.Action.OK) {
										D.close();
									}
								}
							});
							//that.setBtnEnabled("Release", false);
						});
				}

			}),
			endButton: new sap.m.Button({
				text: 'Cancel',
				press: function() {
					D.close();
				}
			}),
			afterClose: function() {
				D.destroy();
			}

		});
		//   oModel.refresh();
		D.open();

	},

 

4. Code for handleonRelease()

	handleonHold: function() {
		var that = this;
		var D = "";
		var that = this;
		var oModel = that.getView().getModel();
		var D = "";

		D = new sap.m.Dialog({
			title: 'Confirm',
			type: 'Message',
			content: new sap.m.Text({
				text: 'Are you sure you want to keep the request "On Hold"?'
			}),
			beginButton: new sap.m.Button({
				text: "OK",
				press: function() {

					var oModel = that.getView().getModel();
					var bindingContext = that.getView().getBindingContext();
					var object = bindingContext.getObject();
					var RequestNumber = bindingContext.getProperty("RequestNumber");
					var Approver = bindingContext.getProperty("Approver");
					var WorkItemGroup = bindingContext.getProperty("WorkItemGroup");
					object.Status = 'ON HOLD';
					oModel.update("/Requests(WorkItemGroup='" + WorkItemGroup + "',Approver='" + Approver + "',RequestNumber='" + RequestNumber +
						"')", object, null,
						function(oResponse) {
							//Function for success
							sap.m.MessageBox.success("Request is kept on hold successfully", {
								actions: [sap.m.MessageBox.Action.OK],
								onClose: function(oAction) {
									if (oAction === sap.m.MessageBox.Action.OK) {
										D.close();
									}
								}
							});
							//that.setBtnEnabled("Release", false);
						});
				}

			}),
			endButton: new sap.m.Button({
				text: 'Cancel',
				press: function() {
					D.close();
				}
			}),
			afterClose: function() {
				D.destroy();
			}

		});
		//   oModel.refresh();
		D.open();

	},

 

5. Run the application and check the functionality for Security requests to be put on HOLD and Released.

Here the first request is moved to ON HOLD.

 

 

 

This way we can achieve the same functionality of on Hold for Security requests as we have in existing Webdynpro application.

 

Be the first to leave a comment
You must be Logged on to comment or reply to a post.