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:
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.
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?
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
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
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