In the realm of SAP development, the ABAP RESTful Application Programming Model (RAP) has emerged as a powerful framework for building efficient and scalable Fiori Elements applications. The developer can focus on custom business logic as the RAP framework takes care of common/ standard features. Non-standard operations can be an action or a function in a business object. In most cases, the actions/operations require some parameters to execute the business logic.
The primary purpose of defaulting action parameters is to enhance user efficiency by pre-filling form fields with relevant and context-aware values. This reduces manual data entry, minimizes errors, and ensures data consistency across the application. Implementing complex business logic within these defaulting actions adds a layer of intelligence to the application, enabling it to adapt to varying scenarios and user-specific requirements.
- Default action parameter with a constant value.
@EndUserText.label: 'Abstract entity for Supplier' @Metadata.allowExtensions: true define root abstract entity zrk_a_supplier { @UI.defaultValue: 'S000000003' ToBesupplier : zrk_sup_no; }
- Default action parameter with a direct mapping from the entity.
Syntax: @UI.defaultValue : #( 'ELEMENT_OF_REFERENCED_ENTITY: <field from entity>') Example: @EndUserText.label: 'Abstract entity for Supplier' @Metadata.allowExtensions: true define root abstract entity zrk_a_supplier { @UI.defaultValue : #( 'ELEMENT_OF_REFERENCED_ENTITY: Supplier') ToBesupplier : zrk_sup_no; }
- Default action parameter with complex business logic:This is the primary focus of this blog post to enrich the business logic in this context. The true strength of ABAP RAP Defaulting Actions lies in their ability to handle complex business logic. Developers can embed intricate algorithms, conditions, and calculations within the defaulting actions, allowing for the dynamic determination of default values. This ensures that the Fiori Elements application not only provides a streamlined user experience but also adheres to the unique requirements of the business. This involves a combination of conditional statements, calculations, and data queries to dynamically determine default values.
For example, defaulting a sales price based on historical data, currency exchange rates, and current market trends.
Business example :
The business case is to convert a purchase requisition into a purchase contract. There could be different cases.
- Some of the fields in a PR are optional but mandatory to create a PC and hence to be prefilled.
Ex. Validity dates - Some of the fields can be modified before creating a PC.
Ex. Description of a PC - Some of the fields require a business logic to determine.
Ex: Determination of source of supply if the supplier is not filled in PR
Implementation :
The action definition needs to be enriched with a function in the base behavior definition and the function needs to be consumed in the projection layer. Below are the detailed steps.
- Define the action in the base behavior with a function.
Note : The function name must start with GetDefaultsFor and followed by action name.action ( features : instance, precheck ) Convert_Into_PC parameter ZRK_A_ActionParam_PR_To_PC result [1] $self { default function GetDefaultsForConvert_Into_PC; }
- Quick fix assistant can be used to create the method definition and implementation.
METHODS convert_into_pc FOR MODIFY IMPORTING keys FOR ACTION _prhead~convert_into_pc RESULT result .
METHODS GetDefaultsForConvert_Into_PC FOR READ IMPORTING keys FOR FUNCTION _PRHead~GetDefaultsForConvert_Into_PC RESULT result.
- [ Optional ] Notice that the parameter of the action becomes the result of the function so that any changes in the action parameter can be reflected in the result of the function.
- Enrich the method implementation with business logic in the function to default the values.
Note : If it is a create or create by association action, then %cid needs to be used instead of %tkyMETHOD GetDefaultsForConvert_Into_PC. " Read the requisition header READ ENTITIES OF zrk_i_pur_req_h IN LOCAL MODE ENTITY _PRHead ALL FIELDS WITH CORRESPONDING #( keys ) RESULT DATA(lt_pur_req). CHECK lt_pur_req IS NOT INITIAL. " Read the requisition item READ ENTITIES OF zrk_i_pur_req_h IN LOCAL MODE ENTITY _PRHead BY \_PRItem ALL FIELDS WITH CORRESPONDING #( keys ) RESULT DATA(lt_pur_req_item). CHECK lt_pur_req_item IS NOT INITIAL. LOOP AT lt_pur_req ASSIGNING FIELD-SYMBOL(<fs_pur_req>). APPEND INITIAL LINE TO result ASSIGNING FIELD-SYMBOL(<fs_result>). " If it is create operation, then %cid needs to be used instead of %tky <fs_result>-%tky = <fs_pur_req>-%tky. <fs_result>-%param-description = |Created from { <fs_pur_req>-ObjectId }|. <fs_result>-%param-buyer = COND #( WHEN <fs_pur_req>-Buyer IS NOT INITIAL THEN <fs_pur_req>-Buyer ELSE sy-uname ). " Default the company code from the user attributes in the Org structure <fs_result>-%param-Company_code = zrk_cl_mng_pur_con=>determine_company_code( ). " Calculate the validity dates <fs_result>-%param-valid_from = cl_abap_context_info=>get_system_date( ). <fs_result>-%param-valid_to = cl_abap_context_info=>get_system_date( ) + 365. " Take the first supplier from the requisition item LOOP AT lt_pur_req_item ASSIGNING FIELD-SYMBOL(<fs_item>) WHERE Supplier IS NOT INITIAL. <fs_result>-%param-supplier = <fs_item>-Supplier. EXIT. ENDLOOP. " If the supplier is not assigned to any item in PR, then determine from source of supply IF <fs_result>-%param-supplier IS INITIAL. <fs_result>-%param-supplier = zrk_cl_mng_pur_con=>determine_supplier_material( iv_material = VALUE #( lt_pur_req_item[ 1 ]-PartNo ) ). ENDIF. ENDLOOP. ENDMETHOD.
- Consume the function in the projection behavior for UI usage.
use function GetDefaultsForConvert_Into_PC ;
- Proceed with the action implementation to be executed based on the inputs. For more details on the implementation approach, please refer to the earlier blog.
- The preview application is ready to be tested.
- [ Optional ] Notice that the below annotation is already mapped in metadata which developers are supposed to write in BAS/WebIDE.
<Annotations Target="SAP__self.Convert_Into_PC(SAP__self.PRHeadType)"> <Annotation Term="SAP__core.OperationAvailable" Path="_it/__OperationControl/Convert_Into_PC"/> <Annotation Term="SAP__common.DefaultValuesFunction" String="com.sap.gateway.srvd.zrk_ui_pur_req.v0001.GetDefaultsForConvert_Into_PC"/> </Annotations>
Additional notes:
- If there are multiple records selected in a list report page and different default values are determined, then the framework ignores the field and it will be blank.
- The function name must start with GetDefaultsFor and followed by action name.
- If it is a create or create by association action, then %cid needs to be used instead of %tky
- This feature is released as part of 2311 BTP release.
Conclusion:
ABAP RAP Defaulting action parameters with complex business logic empower Fiori Elements applications to be not just user-friendly but also intelligent and adaptable to the dynamic nature of business processes. The ability to customize defaulting actions according to specific business needs ensures a more seamless and efficient user experience.
References:
https://help.sap.com/docs/abap-cloud/abap-rap/operation-defaulting
https://community.sap.com/topics/abap/rap
For more similar content, Follow me on community or LinkedIn
Be the first to comment