In my last blog post about Custom Business Objects, I illustrated some simple cases of how to execute API operations on a Custom Business Object in S/4HANA Cloud. In this follow-up post on CBO’s, I’d like to demonstrate a slightly more complex use-case that you might need to employ if you have specific customer requirements that necessitate such a construct. This more complex structure involves the CBO having multiple hierarchies (nodes). In the previous post, I covered an example with just one hierarchy level (‘Demo_CBO’). In this post, we’ll expand on the same example by creating a further hierarchy level with a new parent node ‘Sales Org’. This enables users to better structure their CBOs, as Sales Orders can now be categorized according to the Sales Org. they belong to. Let’s look at the steps involved for this.
Make a copy of the CBO we created previously
On the Custom Business Objects app, I’m going to select the CBO I created in the last post, click copy and give the new CBO a new identifier.
Add Nodes and Fields
Once published, go to the nodes tab. Here we will change the hierarchy to reflect the use case we want to achieve. Let’s’ define Sales Org. as a parent node and change SalesOrder and DeliveryDate to child nodes. After making the necessary changes, your Nodes and Fields tabs should look like this:
Add logic to the multi-level CBO
In the next step, we add logic to our CBO. This is the step that adds complexity to the CBO (in the last post’s example, we only defined the fields for the CBO and populated them via the inbound service URL of the CBO).
To add logic in the CBO, first publish the changes you made to the Nodes and Fields tabs. Now, we can add a new method in the Logic section called “Fetch Sales Orders”. Inside this method, paste the following ABAP code. Make sure you adjust the values according to the types, node and field names specific to your CBO.
* Action FetchSalesOrders for Node ID DEMO_CBO_MULTILEVEL
*
* Importing Parameter : association (Navigation to Parent/Child/Associated Node Instances)
* write (API for creating and updating Custom Business Object Node Instances)
* Changing Parameter : DEMO_CBO_MULTILEVEL (Current Node Data)
* Exporting Parameter : message (Message with Severity S(uccess), W(arning), E(rror))
DATA lv_root_entity_key TYPE yy1_kr_demo_cbo_multilevel.
lv_root_entity_key = demo_cbo_multilevel-salesorg.
* Get an instance of the root entity of the CBO
DATA(lo_root) = write->get_root(
business_object_id = 'YY1_DEMO_CBO_MULTILEVEL'
key = lv_root_entity_key
).
data: lv_SalesOrg type string.
lv_SalesOrg = |{ DEMO_CBO_MULTILEVEL-salesorg ALPHA = IN }|.
*Select required columns from the released I_SalesOrder CDS View
SELECT SalesOrder, RequestedDeliveryDate
FROM I_SalesOrder
INTO TABLE @data(sales_orders_table)
where salesorganization = @lv_SalesOrg.
LOOP AT sales_orders_table INTO DATA(ls_so_row).
* Create new SalesOrder data object by extracting the SalesOrder column from the table
Data(ls_new_so_entry) = VALUE yy1_sales_order_demo_cbo_multi(
SalesOrder = ls_so_row-salesorder
).
* Create new DeliveryDate data object by extracting the SalesOrder column from the table
Data(ls_new_del_date_entry) = VALUE yy1_delivery_date_demo_cbo_mul(
DeliveryDate = ls_so_row-requesteddeliverydate
).
*Create new Sales Order child node
lo_root->create_child(
EXPORTING
Node_id = 'Sales_Order'
Data = ls_new_so_entry
).
*Create new Delivery Date child node
lo_root->create_child(
EXPORTING
Node_id = 'Delivery_Date'
Data = ls_new_del_date_entry
).
ENDLOOP.
message = VALUE #(
severity = co_severity-success
text = 'Action FetchSalesOrders executed'
).
What this code does is the following:
- Gets the root node of the CBO (Sales_Org) using the get_root() method. In this example, I’m using 1110 (Dom. Sales Org GB) and 3010 (Dom. Sales Org GB) as example values for Sales Orgs.
- From the I_SalesOrder CDS View, the Sales Orders for the respective Sales Org. are fetched and stored into an internal ABAP table.
- Loops through the ABAP table, and for each entry found, creates entries for the SalesOrder and DeliveryDate fields using the create_child() method.
Create the 2 parent nodes initially on the UI.
Before we can test the working of the “Fetch Sales Orders” method, we have to create our two parent nodes with the values 1110 and 3010, so that our code can reference these as the root nodes.
- Go to the General Information tab of the CBO and click on “Go to Generated UI”
- Now click the Create button and create 2 entries for each of the Sales Orgs. Your CBO UI should now look like this
Call the Fetch Sales Orders method
Finally, let’s look at how our logic we implemented works. Go into the SalesOrg 1110 created in the step above and click the button “Fetch Sales Orders”
- We see that all Sales Orders along with their delivery dates belonging to Sales Org 1110 appear in our CBO.
- Repeat the same step for Sales Org 3010 and you’ll see the Sales Orders for 3010 appear in the CBO.
The result after calling the method within each of the Sales Orgs. Will look something like this:
To validate the results, you can go to the “Manage Sales Orders – Version 2” app and filter for the respective Sales Orgs. You should see the same results there as in the CBO.
Conclusion
In this part of the blog series about CBO’s in S/4HANA Cloud, we looked at a more advanced use case of working with CBO’s. By creating multiple levels of hierarchy for a CBO and using custom logic to populate child node entries, it is possible to build CBO’s that can fulfill a wide range of customer requirements.