Technical Articles
SAP ABAP RAP & Fiori Elements to refresh calculated fields without manual refresh ( Part – 1 )
The most common feature in building a transactional application is to calculate/ determine fields based on input from dependent fields. In this example, dependent field is Booking Fee while calculated field is Total Price. User expects to see calculated Total Price on entering/updating the Booking Fee without refreshing the page. In most of the tutorials, we get the information on building apps with ABAP RAP.
This blog post helps in achieving the above problem statement to refresh dependent field simply with annotations called SideEffects .
Prerequisites:
- Knowledge on ABAP Restful Application Programming to build basic List Repost Application
- Knowledge on Entity Manipulation Language (EML) to build calculation/determination logic in Application Layer
- Hands on experience in OpenSAP course Building Apps with the ABAP RESTful Application Programming Model
Use case:
When user updates Booking Fee, refresh the calculated Total Price and show it on the application by fetching only Total Price from data base.
This use case is referenced from OpenSAP course so that you can readily implement solution.
Reference: https://github.com/SAP-samples/abap-platform-rap-opensap/blob/main/week3/unit6.md
Steps to follow :
- Create a fiori app using business application studio ( Tutorial link ) for the service (
ZUI_RAP_TRAVEL_O2_####
) you generated in the course.
2. Preview the application with below steps.
Right click on Preview Application.
Select Start
Fiori Application is opened in a new tab. that means, Basic Fiori app is working similar to RAP Preview.
Navigate to Object page, then update Booking fee but Total Price does not reflect automatically. You can see the new Total Price only after refreshing the page. That means our problem statement is ready.
3. Go to local annotation xml in the path webapp/annotations/annotation.xml
4. Replace the xml content using below code snippet and replace XXXX with your id in the tutorial.
<edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx" Version="4.0">
<edmx:Reference Uri="https://sap.github.io/odata-vocabularies/vocabularies/Common.xml">
<edmx:Include Namespace="com.sap.vocabularies.Common.v1" Alias="Common"/>
</edmx:Reference>
<edmx:Reference Uri="/sap/opu/odata/sap/ZUI_RAP_TRAVEL_O2_XXXX/$metadata">
<edmx:Include Namespace="cds_zui_rap_travel_XXXX"/>
</edmx:Reference>
<edmx:DataServices>
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="rj">
<Annotations Target="cds_zui_rap_travel_XXXX.TravelType">
<Annotation Term="Common.SideEffects">
<Record>
<PropertyValue Property="SourceProperties">
<Collection>
<PropertyPath>BookingFee</PropertyPath>
</Collection>
</PropertyValue>
<PropertyValue Property="TargetProperties">
<Collection>
<PropertyPath>TotalPrice</PropertyPath>
</Collection>
</PropertyValue>
</Record>
</Annotation>
</Annotations>
</Schema>
</edmx:DataServices>
</edmx:Edmx>
5. Explanation :
-
- Term=”Common.SideEffects” is an annotation that has 2 properties. In our example, Booking fee triggers recalculation of Total price.
- SourceProperties : These are Collection of properties that triggers determination of an action . So Booking fee is source property.
- TargetProperties : These are Collection of properties that are effected by determination of an action. So Total Price is target property.
- “Common” is referenced from library using edmx:Reference.
- Service name : ZUI_RAP_TRAVEL_O2_XXXX
- Entity name : Travel
- Term=”Common.SideEffects” is an annotation that has 2 properties. In our example, Booking fee triggers recalculation of Total price.
6. Now save the annotation file and preview the application
7. Its time to test the feature by changing Booking fee in object page. Now you can see new Total Price automatically.
8. Below is the OData call fired automatically to refresh new value.
GET Travel(TravelUUID=guid'0c8d0000-4107-3e5c-1700-030214461038',IsActiveEntity=false)?$select=TotalPrice
Watch below clipping for demo.
Hope this blog post gives you a hint to build transactional application to next level.
I will explain in next blog post how to refresh parent property when child entity’s field is updated.
Good job Ramjee, Thanks for this blog post.
It would be great if you can provide the link for possible annotations? like for side effects one here..
Hi Gaurav,
below is the link for SideEffects and Navigate to ToC for more annnotations.
https://help.sap.com/viewer/468a97775123488ab3345a0c48cadd8f/201809.000/en-US/61cf21d50ed34cbf888713496c618904.html
Hi Ramjee,
With some action "Process Data", I am updating chilld entity data in backend DB. Now I want show the updated child entity data on UI screen without manual refresh immediately after clicking on Process Data button. Could you please guide me on how to do that
Thanks
Hello Mohan,
I have not yet tried it . There is no direct example found in the documentation.
Please try below one and let me know if it works..
Best wishes,
Ramjee Korada
Hello Ramji
Thanks for the wonderful blog.
Can you please tell me how to do this in SAP RAP , Which UI annotation should be used in Metadata extension .
Thank you
Regards
Venkat Srikantan
Hi Venkat,
These annotations are not available in ABAP RAP or its preview application . We have to do in fiori app and prerequisite is Determination in Behavior from RAP.
This is explained openSAP course ( week 3, Unit 6 ) already .
https://github.com/SAP-samples/abap-platform-rap-opensap/blob/main/week3/unit6.md
Best wishes,
Ramjee Korada
Hi Ramjee, Nice and informative blog 🙂
May I request your help ?I tried creating annotation file as below in BAS for my custom application , but "The field intended to get updated is not getting updated correctly on change in UI , it gets triggered only on Create or Update" can you please help ?
Behaviour definition code:
determination setCurrentOrgDetails on modify { field Requestedfor; }
Implementation:
METHOD setCurrentOrgDetails.
read ENTITIES of ZIVIEW_MGR_REQUESTS IN LOCAL MODE
ENTITY Requests
FIELDS ( Requestedfor )
WITH CORRESPONDING #( keys )
RESULT DATA(requests).
MODIFY ENTITIES OF ziview_mgr_requests IN LOCAL MODE
ENTITY Requests
UPDATE
* UPDATE FIELDS ( Currentcontracttype Currentpersonnelarea Currentpositionid Currentpsa Currentsalary )
FROM VALUE #( FOR request in requests INDEX INTO I (
%tky = request-%tky
Currentpersonnelarea = '1300'
%control-Currentpersonnelarea = if_abap_behv=>mk-on
)
)
REPORTED DATA(updated_reported)
.
reported = CORRESPONDING #( DEEP updated_reported ).
ENDMETHOD.
Annotation.xml code:
<edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx" Version="4.0">
<edmx:Reference Uri="https://sap.github.io/odata-vocabularies/vocabularies/Common.xml">
<edmx:Include Namespace="com.sap.vocabularies.Common.v1" Alias="Common"/>
</edmx:Reference>
<edmx:Reference Uri="/sap/opu/odata/sap/ZSB_MGR_REQUESTS/$metadata">
<edmx:Include Namespace="cds_zsd_mgr_requests"/>
</edmx:Reference>
<edmx:DataServices>
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="cds_zsd_mgr_requests2">
<Annotations Target="cds_zsd_mgr_requests.ZCVIEW_MGR_REQUESTSType">
<Annotation Term="Common.SideEffects">
<Record>
<PropertyValue Property="SourceProperties">
<Collection>
<PropertyPath>Requestedfor</PropertyPath>
</Collection>
</PropertyValue>
<PropertyValue Property="TargetProperties">
<Collection>
<PropertyPath>Currentpersonnelarea</PropertyPath>
</Collection>
</PropertyValue>
</Record>
</Annotation>
</Annotations>
</Schema>
</edmx:DataServices>
</edmx:Edmx>
Hi Manikandan,
Definition , Annotation seems fine. But I have suspect on Implementation.
As an initial check, Is that filed updated in database table and reflected on UI if you browser refresh ? please confirm.
in code snippet, Fields are not specified in MODIFY and only one filed value is sent.
Yes , it gets triggered after Create or Save(Update)
Hi Ramjee,
is it possible to add side-effects to a standard Fiori Elements app? And if yes, how?
Background: we extended the standard app with custom fields (Custom Fields and Logic app) and there is dependency between the value of a field and the visibility of another field. So when I change the value of one custom fields, the other custom field need to be refreshed.
Kind regards,
Szilamer