In SAP S4HANA Utilities implementations, Contract Account (CA) notes are a valuable source of contextual information for customer service representatives. Contract Account notes in SAP Utilities (IS-U) are stored at the database level but are not natively exposed through the BOL framework as a relation to the UtilsContrAcctPartner object. To enable this, a new custom Business Layer object — UtilsContrAcctPartnerNotes — has been created for component ISUMDE. This blog post walks through the end-to-end technical approach used to surface CA notes as a display-only section on the WebUI, from BOL modeling all the way through UI component wiring.
The foundation of the solution begins with the creation of the data structures and CDS views that support the new BOL entity. These artefacts provide the metadata, business-layer representation, and query capabilities required to expose Contract Account notes within the CRM WebUI.
The following ABAP structures are created as part of the implementation:
- ZCRMS4S_IU_CA_NOTES_KEY – Defines the key structure used to uniquely identify a Contract Account note record.
- ZCRMS4S_IU_CA_NOTES_BL_DATA – Contains the non-key business data attributes associated with the note.
- ZCRMS4S_IU_CA_NOTES_ATTR – Serves as the main attribute structure by combining the key and business data structures. It also includes additional fields such as Contract Account, Business Partner, and note text content to support BOL relationships and UI requirements.
- ZCRMS4S_IU_CA_NOTES_BL – Represents the business layer structure used during BOL object configuration. For this instance, the structure is taken the same as the Attribute Structure
- ZCRMS4S_IU_CA_NOTES_QRY – Defines the query structure that powers search and retrieval operations for the custom BOL entity. For this instance, the structure is taken the same as the Attribute Structure.
To enable efficient search and data retrieval, two CDS views are introduced:
- ZCRMS4_IU_I_CANOTES – An interface view that reads Contract Account note data directly from the underlying SAP IS-U database table – STXH.
- ZCRMS4_IU_C_CANOTE – A consumption view built on top of the interface view, designed specifically for use by the BOL query framework.
Together, these structures and CDS views form the data foundation for the custom BOL/GenIL enhancement, enabling Contract Account notes to be seamlessly surfaced within the CE WebUI.
With the data model in place, the next step is to implement the runtime logic required to expose and retrieve Contract Account notes through the BOL/GenIL framework. This is achieved by creating custom ABAP classes across the Interaction Layer and Business Layer, each extending the appropriate SAP standard base class.
The following classes are introduced:
- ZCL_IU_IL_CA_NOTES (extends CL_CRMS4_IU_IL_ABSTR_ROOT) – The Interaction Layer root entity class responsible for handling attribute access, property behavior, and entity-level interactions.
- ZCL_IU_IL_CA_NOTES_QUERY (extends CL_CRMS4_IU_IL_ABSTR_QUERY) – The Interaction Layer query class that manages search requests and query execution for the custom business object.
- ZCL_IU_BL_CA_NOTES (extends CL_CRMS4_IU_BL_BASE) – The Business Layer implementation class that provides data access logic and serves as the bridge between the BOL framework and the underlying CDS-based data model.
A key enhancement within the Business Layer is the implementation of the IF_CRMS4_IU_BL_ACCESS~QUERY method in ZCL_IU_BL_CA_NOTES. This method is extended to execute search operations against the custom CDS views, enabling the retrieval of Contract Account notes based on the criteria supplied by the CRM WebUI.
METHOD if_crms4_iu_bl_access~query.
TYPES: text_line(132) TYPE c.
DATA: lt_lines TYPE comt_text_lines_t,
ls_lines LIKE LINE OF lt_lines,
lv_vkont TYPE vkont_kk,
lv_gpart TYPE bu_partner,
lt_text_table TYPE TABLE OF text_line,
lv_string TYPE string,
lv_str TYPE string,
lv_blanks TYPE i,
lt_selection_parameters TYPE genilt_selection_parameter_tab,
lt_result TYPE TABLE OF zcrms4s_iu_ca_notes_qry,
lv_tdname TYPE tdobname.
FIELD-SYMBOLS: TYPE text_line,
TYPE zcrms4s_iu_ca_notes_qry,
TYPE ANY TABLE.
*** removing the parameters gpart & vkont and adding them to Tdname ****
lt_selection_parameters = it_selection_parameters.
LOOP AT lt_selection_parameters ASSIGNING FIELD-SYMBOL().
IF -attr_name EQ 'GPART'.
lv_gpart = |{ -low ALPHA = IN }|.
CLEAR: .
ENDIF.
IF -attr_name EQ 'VKONT'.
lv_vkont = |{ -low ALPHA = IN }|.
CLEAR: .
ENDIF.
IF lv_gpart IS NOT INITIAL AND lv_vkont IS NOT INITIAL .
-attr_name="TDNAME".
-sign = 'I'.
-option = 'EQ'.
-low = lv_vkont && lv_gpart.
ENDIF.
ENDLOOP.
DELETE lt_selection_parameters WHERE attr_name IS INITIAL.
TRY.
CALL METHOD super->if_crms4_iu_bl_access~query
EXPORTING
iv_max_hits = iv_max_hits
it_selection_parameters = lt_selection_parameters
it_convertion = it_convertion
ir_message_container = ir_message_container
iv_object_name = iv_object_name
iv_no_fillup_attributes = abap_false
IMPORTING
et_table = lt_result
ev_selection_changed = ev_selection_changed
ev_only_keys_selected = ev_only_keys_selected.
CATCH cx_crms4_iu_base.
ENDTRY.
LOOP AT lt_result ASSIGNING .
CALL FUNCTION 'READ_TEXT'
EXPORTING
id = -tdid
language = -tdspras
name = -tdname
object = -tdobject
TABLES
lines = lt_lines
EXCEPTIONS
OTHERS = 0.
CALL FUNCTION 'LANGUAGE_CODE_SAP_TO_ISO'
EXPORTING
sap_code = -tdspras
IMPORTING
iso_code = -languiso
EXCEPTIONS
OTHERS = 0.
READ TABLE lt_lines INDEX 1 INTO ls_lines.
-tdformat = ls_lines-tdformat.
CALL FUNCTION 'CONVERT_ITF_TO_STREAM_TEXT'
EXPORTING
language = sy-langu
TABLES
itf_text = lt_lines
text_stream = lt_text_table.
IF sy-tabix GT 1.
CLEAR lv_blanks.
LOOP AT lt_text_table ASSIGNING .
MOVE TO lv_str.
SHIFT lv_str BY lv_blanks PLACES RIGHT.
CONCATENATE lv_string lv_str INTO lv_string.
lv_blanks = 132 - strlen( ).
ENDLOOP.
ELSE.
LOOP AT lt_text_table ASSIGNING .
lv_string = .
ENDLOOP.
ENDIF.
-tdform = 'SYSTEM'.
-tdstyle="SYSTEM".
-tdline = lv_string.
MOVE cl_gstext_tools=>transform_itf_to_itfstring( lt_lines ) TO -conc_formatted_lines.
IF lv_gpart IS NOT INITIAL AND lv_vkont IS NOT INITIAL.
-gpart = lv_gpart.
-vkont = lv_vkont.
ELSE.
-vkont = -tdname(12).
-gpart = substring( val = -tdname off = 12 len = 10 ).
ENDIF.
ENDLOOP.
et_table = CORRESPONDING #( lt_result ).
*** update the data retrieved in the global container
* GR_DATAS
ASSIGN gr_datas->* TO .
= CORRESPONDING #( et_table ).
ENDMETHOD.
Together, these classes provide the runtime framework necessary for querying, retrieving, and exposing Contract Account note information through the custom BOL entity.
After creating the required data structures and implementing the Interaction Layer and Business Layer classes, the new BOL entity must be registered within the CRM framework. This is accomplished through transaction SM34 using the view cluster CRMC_IUIL_OBJPROP for the ISUMDE component.
The registration process consists of four key configuration areas:
1. Root Object Registration
The custom entity is registered as a related object under the existing UtilsContrAcctPartner root object, enabling Contract Account notes to be accessed within the established business object hierarchy. During this step:
- ZCL_IU_IL_CA_NOTES is assigned as the Interaction Layer implementation class.
- The custom key and attribute structures are linked to the object definition.
- The object is exposed as UtilsContrAcctPartnerNotes within the BOL model.
2. Query Object Registration
To enable search and retrieval capabilities, a dedicated query object is configured using ZCL_IU_IL_CA_NOTES_QUERY as the Query Interaction Layer class.
The configuration specifies:
- UtilsContrAcctPartner as the root object.
- UtilsContrAcctPartnerNotes as the result object returned by the query execution.
3. Dynamic Query Object Configuration
A corresponding Dynamic Query object is created using the same configuration principles. This allows the framework to support dynamic search scenarios and runtime query execution for the new entity.
4. BOL Relation Definitions
To enable seamless navigation between business objects, two BOL relations are defined:
- A forward relation from UtilsContrAcctPartner to UtilsContrAcctPartnerNotes, allowing Contract Account notes to be retrieved from the parent object.
- A reverse relation from UtilsContrAcctPartnerNotes back to UtilsContrAcctPartner, supporting bidirectional navigation within the BOL model.
Once the configuration is saved and activated, the newly registered entity, query objects, and relationships can be validated using transaction GENIL_MODEL_BROWSER, ensuring that the custom BOL object is correctly integrated into the CRM framework.
With the BOL entity successfully registered, the next step is to configure the corresponding Business Layer (BL) components. The Business Layer serves as the data access framework behind the BOL object and must be aligned with the entity structure, CDS views, and relationships defined in the previous steps.
The configuration is maintained within the Business Layer customization transactions for the ISUMDE component and includes the following activities:
1. Business Layer Object Definition
The custom Business Layer object is created as a Root Object Type, establishing the primary entry point for data retrieval. During this configuration:
- The custom CDS view is assigned as the data source.
- The Business Layer structure is linked to the object definition.
- The custom Business Layer implementation class (ZCL_IU_BL_CA_NOTES) is assigned to handle runtime processing and data access.
2. Query Registration
Custom queries are registered within the Define Queries configuration section. Each query is mapped to its corresponding CDS view, enabling the Business Layer to execute searches and return Contract Account note records based on the criteria supplied by the CRM WebUI.
3. Relation Configuration
The relationships established in the BOL model are replicated within the Business Layer through the Define Relations configuration. Both forward and backward relations are defined here along with the relation type and associated query objects.
4. Relation Key and Parameter Mapping
To support accurate data retrieval and object navigation, relation keys and parameter mappings are configured for each relationship. These mappings define how key fields are transferred between related objects, ensuring that Contract Account notes are correctly associated with their parent Contract Account and Business Partner entities.
Once completed, the Business Layer configuration provides the underlying data access and navigation framework required for the custom BOL entity to function seamlessly within the CRM WebUI.
To leverage the standard GSTEST component, a dedicated Text Determination Procedure is configured for Contract Account note types associated with text object FKKVKP. The note types included in this procedure define the set of notes that are retrieved and displayed within the WebUI. This configuration ensures that only relevant and business-approved note categories are presented to end users, providing a controlled and consistent user experience.
To enable the display of Contract Account (CA) notes within the Contract Account view, several WebUI configurations activities and component enhancements are implemented to make the view available with the Contract Account screen.
Form Configuration
- A Simple Create/Change form is configured in the Define Forms section, with form titles maintained.
- A dedicated Form Mask is created in the BSP Workbench, specifying the Window Name, Component Name, Inbound Plug, and Context Node.
- The form is registered under the Form Overview (a custom form is created by copying standard form UCAP_OV), where the corresponding Object Determination Profile and relation are assigned.
The Component Controller of IUFMUCAP is enhanced to facilitate data transfer between the Business Object Layer (BOL) and the reused GSTEXT component. To support this integration, two additional context nodes are introduced:
- TEXTATTR (Value Node):
This node stores text attribute information. The IF_BSP_MODEL~INIT method is redefined to assign the appropriate structure, leveraging the existing definition provided by the reused GSTEXT component. The ON_NEW_FOCUS method is defined to provide data to the added collection
METHOD on_new_focus.
DATA: current TYPE REF TO if_bol_bo_property_access,
entity TYPE REF TO cl_crm_bol_entity,
ls_attributes TYPE crmst_uiu_text_attr.
current = collection_wrapper->get_current( ).
CHECK current IS BOUND.
** TEXTPROC
SELECT SINGLE textprocedure FROM comc_text_p INTO (ls_attributes-textproc)
WHERE object="FKKVKP".
* TEXTOBJ
ls_attributes-textobj = 'FKKVKP'. "#EC NOTEXT
* LANGU_ATTR_NAME
ls_attributes-langu_attr_name="LANGUISO". "#EC NOTEXT
* IDENT_ATTR_NAME
ls_attributes-ident_attr_name="TDID". "#EC NOTEXT
* LINES_ATTR_NAME
ls_attributes-lines_attr_name="TDLINE". "#EC NOTEXT
* PARENT_RELATION
ls_attributes-parent_relation = 'UtilsContrAcctPartnerNotesRel'. "#EC NOTEXT
* formatting related attributes
ls_attributes-lines_formatted_attr_name="CONC_FORMATTED_LINES". "#EC NOTEXT
* TDFORM and TDSTYLE are supported for accounts to provide formatting
ls_attributes-form_attr_name="TDFORM". "#EC NOTEXT
ls_attributes-style_attr_name="TDSTYLE". "#EC NOTEXT
ls_attributes-use_formatting = 'X'. "#EC NOTEXT
* PARENT_ENTITY
TRY.
entity ?= focus_bo.
ls_attributes-parent_entity = entity.
CATCH cx_sy_move_cast_error .
ENDTRY.
current->set_properties( ls_attributes ).
me->collection_wrapper->publish_current( ).- TEXT (Model Node):
This node is bound to the custom BOL object UtilsContrAcctPartnerNotes. The ON_NEW_FOCUS method is implemented to populate the collection by utilizing the relation configured within the Business Layer.
METHOD on_new_focus.
DATA: lv_collection TYPE REF TO if_bol_bo_col,
entity TYPE REF TO cl_crm_bol_entity.
* get collection of dependent nodes
TRY.
entity ?= focus_bo.
CATCH cx_sy_move_cast_error. " Create
ENDTRY.
TRY.
lv_collection = entity->get_related_entities(
iv_relation_name="UtilsContrAcctPartnerNotesRel" ).
CATCH cx_crm_genil_model_error.
* should never happen
EXIT.
CATCH cx_sy_ref_is_initial.
ENDTRY.
* CHECK lv_collection IS BOUND.
me->collection_wrapper->set_collection( lv_collection ).
ENDMETHOD.Additionally, the WD_USAGE_INITIALIZE method is redefined to establish the context binding between IUFMUCAP and GSTEXT. This enables the collection data maintained in the parent component to be passed seamlessly to the reused text component, ensuring the relevant Contract Account notes are retrieved and displayed correctly within the WebUI.
By implementing the above configuration and development steps, the notes maintained in CAA3 can be seamlessly displayed within the WebUI as a dedicated tab (configured as Remarks) on the Contract Account screen.
This approach demonstrates how custom Business Layer objects can be seamlessly integrated into the SAP S/4HANA Utilities Customer Engagement WebUI by leveraging the standard BOL framework, component reuse, and WebUI configuration capabilities. By following established SAP design patterns, we can extend standard functionality in a maintainable and upgrade-friendly manner while minimizing modifications to the core application.
The same implementation pattern can be applied to a wide range of custom business objects and use cases, enabling efficient integration of additional business data and processes into the Customer Engagement WebUI.



