Skip to Content
Author's profile photo Mateusz Jarmuzek

SAP Fiori 2.0 for SAP HCM – How to extend “My Profile” app – new section

In this post I will show you step-by-step how to extend standard SAP Fiori application on example My Profile.

This is a continuation to my previous blog on SAP Fiori “My Profile” app extension.

I would like to consider following scenario:

  • Scenarios 1: Add new custom section contains agreement data.

 

Please make sure that you implement all sap notes before you start to extend application.

Important:

2680652 – My Profile (SAP Fiori 2.0) (UI): Positive flextime balances are not displayed and customer-specific areas are not visible

 

Backend – OData :

Go to SEGW -> select ZHCMFAB_MYPROFILE project -> Data Model -> Entity Types and create new type.

In my case I added 3 additional fields: hire date, agreement type and date of end of agreement.

Create EntitySet.

In Entity Type “EmployeeDetail” add new Navigation Properties as below.

Go to ZCL_ZHCMFAB_MYPROFILE_DPC_EXT class.

Go to SE80.

Reimplement method: /IWBEP/IF_MGW_APPL_SRV_RUNTIME~GET_ENTITYSET

METHOD /iwbep/if_mgw_appl_srv_runtime~get_entityset.
    DATA lv_entityset_name TYPE string.
    DATA adddata_get_entity TYPE zcl_zhcmfab_myprofile_mpc=>tt_additionaldata.

    lv_entityset_name = io_tech_request_context->get_entity_set_name( ).

    CASE lv_entityset_name.
      WHEN 'AddDataSet'.
        adddataset_get_entityset(
          EXPORTING
            iv_entity_name               = iv_entity_name
            iv_entity_set_name           = iv_entity_set_name
            iv_source_name               = iv_source_name
            it_filter_select_options     = it_filter_select_options
            is_paging                    = is_paging
            it_key_tab                   = it_key_tab
            it_navigation_path           = it_navigation_path
            it_order                     = it_order
            iv_filter_string             = iv_filter_string
            iv_search_string             = iv_search_string
            io_tech_request_context      = io_tech_request_context
          IMPORTING
            et_entityset                 = adddata_get_entity
            es_response_context          = es_response_context    " Feed request response information (EntitySet)
        ).
*          CATCH /iwbep/cx_mgw_busi_exception.    "
*          CATCH /iwbep/cx_mgw_tech_exception.    "
        copy_data_to_ref(
       EXPORTING
         is_data = adddata_get_entity
       CHANGING
         cr_data = er_entityset
     ).
      WHEN OTHERS.
        TRY.
            CALL METHOD super->/iwbep/if_mgw_appl_srv_runtime~get_entityset
              EXPORTING
                iv_entity_name           = iv_entity_name
                iv_entity_set_name       = iv_entity_set_name
                iv_source_name           = iv_source_name
                it_filter_select_options = it_filter_select_options
                it_order                 = it_order
                is_paging                = is_paging
                it_navigation_path       = it_navigation_path
                it_key_tab               = it_key_tab
                iv_filter_string         = iv_filter_string
                iv_search_string         = iv_search_string
                io_tech_request_context  = io_tech_request_context
              IMPORTING
                er_entityset             = er_entityset
                es_response_context      = es_response_context.
          CATCH /iwbep/cx_mgw_busi_exception .
          CATCH /iwbep/cx_mgw_tech_exception .
        ENDTRY.
    ENDCASE.
  ENDMETHOD.

 

Create method ADDDATASET_GET_ENTITYSET.

 

Frontend – SAP Fiori app:

Go to Web IDE -> Select application HCMFAB_PRFL_MONExtension

Create 3 files in customerBlocks folder.

 

AdditonalBlock.js

sap.ui.define(["sap/uxap/BlockBase"], function(B) {
	"use strict";
	return B.extend("hcm.fab.myprofile.HCMFAB_PRFL_MONExtension.customerBlocks.AdditionalBlock", {
		metadata: {
			views: {
				Collapsed: {
					viewName: "hcm.fab.myprofile.HCMFAB_PRFL_MONExtension.customerBlocks.AdditionalBlock",
					type: "XML"
				},
				Expanded: {
					viewName: "hcm.fab.myprofile.HCMFAB_PRFL_MONExtension.customerBlocks.AdditionalBlock",
					type: "XML"
				}
			},
			events: {}
		}
	});
});

AdditionalBlock.view.xml

<mvc:View controllerName="hcm.fab.myprofile.HCMFAB_PRFL_MONExtension.customerBlocks.AdditionalBlockController" xmlns:core="sap.ui.core"
	xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m" xmlns:form="sap.ui.layout.form" xmlns:l="sap.ui.layout">
	<l:Grid id="addDataContainer" content="{ path: 'toAdditionalData', templateShareable: false }" containerQuery="false" hSpacing="0"
		defaultSpan="L12 M12 S12" visible="true">
		<l:content>
			<VBox renderType="Bare">
				<form:SimpleForm id="AdditionalData2Form" maxContainerCols="2" editable="false" layout="ResponsiveGridLayout" labelSpanXL="4" emptySpanXL="0"
					columnsXL="3" labelSpanL="12" emptySpanL="0" columnsL="3" labelSpanM="12" emptySpanM="0" columnsM="2" labelSpanS="12" emptySpanS="0"
					adjustLabelSpan="false" singleContainerFullSize="false">
					<form:content>
						<Label text="{i18n>hiredate}" id="hiredatel" labelFor="hiredate" visible="true"/>
						<Text id="hiredate" text="{HireDate}" visible="true"/>
						<Label text="{i18n>agreementtype}" id="agreementtypel" labelFor="agreementtype" visible="true"/>
						<Text id="agreementtype" text="{AgreementType}" visible="true"/>
						<Label text="{i18n>enddate}" id="enddatel" labelFor="enddate" visible="{= ${EndDate} === 'true'}"/>
						<Text id="enddate" text="{EndDate}" visible="{= ${EndDate} === 'true'}"/>
					</form:content>
				</form:SimpleForm>
			</VBox>
		</l:content>
	</l:Grid>
</mvc:View>

AdditionalBlockController.controller.js

sap.ui.define([
	"hcm/fab/myprofile/controller/BaseController",
	"hcm/fab/myprofile/utils/reuseHandler",
	"hcm/fab/myprofile/utils/formatter"
], function(B, r, f) {
	"use strict";
	return B.extend("hcm.fab.myprofile.HCMFAB_PRFL_MONExtension.customerBlocks.AdditionalBlockController", {
		onInit: function() {
			this.oApplicationController = r.getOwnerComponent().getModel("appProperties").getProperty("/applicationController");
			this.oODataModel = r.getOwnerComponent().getModel();
		}
	});
});

 

Go to Extension Panel.

Select extensionProfileSections and click button “Extend” -> “Extend view/fragment”.

 

<mvc:View controllerName="hcm.fab.myprofile.HCMFAB_PRFL_MONExtension.customerBlocks.AdditionalBlockController" xmlns:core="sap.ui.core"
	xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m" xmlns:form="sap.ui.layout.form" xmlns:l="sap.ui.layout">
	<l:Grid id="addDataContainer" content="{ path: 'toAdditionalData', templateShareable: false }" containerQuery="false" hSpacing="0"
		defaultSpan="L12 M12 S12" visible="true">
		<l:content>
			<VBox renderType="Bare">
				<form:SimpleForm id="AdditionalData2Form" maxContainerCols="2" editable="false" layout="ResponsiveGridLayout" labelSpanXL="4" emptySpanXL="0"
					columnsXL="3" labelSpanL="12" emptySpanL="0" columnsL="3" labelSpanM="12" emptySpanM="0" columnsM="2" labelSpanS="12" emptySpanS="0"
					adjustLabelSpan="false" singleContainerFullSize="false">
					<form:content>
						<Label text="{i18n>hiredate}" id="hiredatel" labelFor="hiredate" visible="true"/>
						<Text id="hiredate" text="{HireDate}" visible="true"/>
						<Label text="{i18n>agreementtype}" id="agreementtypel" labelFor="agreementtype" visible="true"/>
						<Text id="agreementtype" text="{AgreementType}" visible="true"/>
						<Label text="{i18n>enddate}" id="enddatel" labelFor="enddate" visible="{= ${EndDate} === 'true'}"/>
						<Text id="enddate" text="{EndDate}" visible="{= ${EndDate} === 'true'}"/>
					</form:content>
				</form:SimpleForm>
			</VBox>
		</l:content>
	</l:Grid>
</mvc:View>

 

Add custom texts and translaction in i18n:

Result:

In my blog you could learrn how to extend both parts: Frontend (SAP UI5) and Backend (OData) on the example of “My Profile” app.

I am looking for your feedback through comments and I hope you enjoyed this blog.

 

 

 

Assigned Tags

      4 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Damian Collado Rodriguez
      Damian Collado Rodriguez

      Good job Mateusz , definitively a very helpful post!

      One thing we are trying to achieve is to access the My Profile app to any employee as a manager, it's possible or we need big enhancements?

      Author's profile photo Mateusz Jarmuzek
      Mateusz Jarmuzek
      Blog Post Author

      Dear Damian,

      My recomendation:

      I think it is better to create new custom (Z*) application or copy My Profile application to custem (Z) application.

      Please take a look into method _onObjectMatched in ProfileOverview.controller.js file. There is variable m.EmployeeId. Please remember that you have to edit oData because of check authorisation.

      Kind regards

      Mateusz Jarmużek

      Author's profile photo Schwaerzler Lorenz
      Schwaerzler Lorenz

      Dear Mateusz,

      thank you for this write up. it still is somewhat complex...

      how can we sort the appearance of the profile sections? in enhancmentspot  badi HCMFAB_B_MYPROFILE we can set section on or off (ABAP_TRUE or ABAP_FALSE). would this also be the area where we can seort them?

      kind regards, Lorenz

      Author's profile photo Peeyush Ranjan
      Peeyush Ranjan

      Dear Mateusz,

      Thanks a lot for you great blog .I am able to the the extension on web ide  and Its working fine.

      But When I deploy this extended app to ABAP repository then I am not able to run.

      It always give me below error:

      Component-preload.js?eval:40 Uncaught TypeError: Cannot read property 'isNavigationSupported' of undefined
      at constructor._checkNavIntendSupported (Component-preload.js?eval:40)
      at constructor._initCrossAppNavigationSettings (Component-preload.js?eval:40)
      at new constructor (Component-preload.js?eval:40)
      at f.init (Component-preload.js?eval:4)
      at ManagedObject-dbg.js:539
      at f.constructor (ManagedObject-dbg.js:558)
      at f.constructor (Component-dbg.js:293)
      at f.constructor (UIComponent-dbg.js:81)
      at f [as constructor] (Metadata-dbg.js:463)
      at new f (Metadata-dbg.js:463)

       

      Can you please kindly provide your input.

       

      Regards

      Peeyush Ranjan