Introduction
I just want to reflect a part of my last project here in this blog.
About six month ago I get in touch with the Business Object Processing Framework (BOPF) the first time. It was a lot of pain to get an understanding of the generic framework with all the interfaces, methods, nodes, associations, actions, validations and keys. But thanks to all the blogs and tutorials, I found my way through the jungle of dependent and undependent keys.
Abbreviations used in the further text:
BO = Business Object
DO = Delegated Object
CBO = Cross Business Object
Navigate through objects in SAP TM
1. Navigate within a BO from one node to another (to a representation node)
My first goal was to read the depending item data of the root node. That was easily made after understanding the RETRIEVE_BY_ASSOCIATION method of the service manager.
We need only a few things: The root node key, the name of the association and the structure of the data we want to read (here: structure /SCMTMS/T_TRQ_ITEM_K).
To get the name of the item structure, we have to go into the BO /SCMTMS/TRQ in transaction BOBX.
Fig 1. Business Object /SCMTMS/TRQ
Our root node key and the association could be found in the constants of our BO interface /SCMTMS/IF_TRQ_C.
With all this data we can call the method Retrieve_by_association.
*************************************************************************
* Coding 1 - read items of root
* Navigate within a BO from one node to another
*************************************************************************
DATA: ls_key TYPE /bobf/s_frw_key,
lt_key TYPE /bobf/t_frw_key,
lt_item type /SCMTMS/T_TRQ_ITEM_K,
lo_message TYPE REF TO /bobf/if_frw_message.
* Make instance of BO TRQ
DATA(lo_srv_mgr) = /bobf/cl_tra_serv_mgr_factory=>get_service_manager(
/scmtms/if_trq_c=>sc_bo_key ).
* Sample root key of BO TRQ
ls_key-key = '0050568176441ED2A1FDA55C17A3E60F'.
APPEND ls_key TO lt_key.
* Retrieve item data
lo_srv_mgr->retrieve_by_association(
EXPORTING
iv_node_key = /scmtms/if_trq_c=>sc_node-root
it_key = lt_key
iv_association = /scmtms/if_trq_c=>sc_association-root-item
iv_fill_data = abap_true
iv_edit_mode = /bobf/if_conf_c=>sc_edit_read_only
IMPORTING
eo_message = lo_message
et_data = lt_item ).
Fig 2. Coding 1 – Retrieve_by_association
There we are. Now we can access the fields of the internal table lt_items.
2. Navigate from BO to node data of a DO
My second goal was to read the POSTAL_ADDRESS of the node ORDPTYADDRESS.
To get the data of node ordptyaddress is easy and could be realized with example Coding 1. But we want to get one step deeper to read the postal address.
If we take a look at the node ORDPTYADDRESS in the BO /SCMTMS/TRQ, we can see that the association will lead us into a Delegation class and the CBO /BOFU_ADDRESS.
Fig 3. Delegation class of node ORDPTYADDRESS
So we have to take a closer look into the dependent object /BOFU/ADDRESS. There we get the structure name of the postal address /BOFU/T_ADDR_POSTAL_ADDRESSK.
Fig 4. Delegation class of node ORDPTYADDRESS
But to read the data of the DO is not working like in Coding 1. So I read the following blog of Senthil Kumar: BOPF Working on Delegated nodes
After understanding that the DO is generated during runtime, it is clear that there is no direct access to this object. We have to use the GET_CONTENT_KEY_MAPPING method from the framework configuration reference to get the right association key.
After getting the mapped key, we’ll get the opportunity to read the target key, that we need to access the node data of the DO.
With the root key and the target key we can call the already known method retrieve_by_association.
*************************************************************************
* Coding 2 - read postal address of DO
* Navigate from BO to node data of a DO
*************************************************************************
DATA: ls_key TYPE /bobf/s_frw_key,
lt_key TYPE /bobf/t_frw_key,
lt_target_key TYPE /bobf/t_frw_key,
lt_data TYPE /BOFU/T_ADDR_POSTAL_ADDRESSK,
lo_message TYPE REF TO /bobf/if_frw_message.
* Make instance of BO TRQ
DATA(lo_srv_mgr) = /bobf/cl_tra_serv_mgr_factory=>get_service_manager(
/scmtms/if_trq_c=>sc_bo_key ).
DATA(lo_frw_conf) = /bobf/cl_frw_factory=>get_configuration(
iv_bo_key = /scmtms/if_trq_c=>sc_bo_key ).
* Sample root key of BO TRQ
ls_key-key = '0050568176441ED2A1FDA55C17A3E60F'.
APPEND ls_key TO lt_key.
* Set nodes and association
DATA(lv_root_node) = /scmtms/if_trq_c=>sc_node-root.
DATA(lv_target_node) = /scmtms/if_trq_c=>sc_node-ordptyaddress.
DATA(lv_association) = /scmtms/if_trq_c=>sc_association-root-ordptyaddress.
DATA(lv_do_assoc_key) = /bofu/if_addr_constants=>sc_association-root-postal_address.
* Word - blacklist warning!!!
* Hey - I didn't wrote the word a_s_s!!!! ;-) - ok let's try it like this:
DATA(lv_content_cat) = /bobf/if_conf_c=>sc_content_a$$.
* Read association key of target node
*/SMCTMS/TRQ-ROOT -> /BOFU/ADDRESS-ROOT-POSTAL_ADDRESS"
DATA(lv_assoc_key) = lo_frw_conf->get_content_key_mapping(
iv_content_cat = lv_content_cat
iv_do_content_key = lv_do_assoc_key
iv_do_root_node_key = lv_target_node ).
* read target key(s)
lo_srv_mgr->retrieve_by_association(
EXPORTING
iv_node_key = lv_root_node
it_key = lt_key
iv_association = lv_association
IMPORTING
et_target_key = lt_target_key ).
* Retrieve data of node ordptyaddress
lo_srv_mgr->retrieve_by_association(
EXPORTING
iv_node_key = lv_target_node "Here we have to use the target node as node key
it_key = lt_target_key "...and the target key as key
iv_association = lv_assoc_key "...and the mapped association key
iv_fill_data = abap_true
IMPORTING
eo_message = lo_message
et_data = lt_data ).
Fig 5. Coding 2 – get_content_key_mapping
And “schwupps” we got the data that we wanted. (I like the german word Schwupps!)
3. Navigate from DO to CBO
My third goal was to read data of a CBO within the DO.
In my case I wanted to read the depending data of BO /SCMTMS/FREIGHTAGREEMENT from BO /SCMTMS/TOR) via DO /SCMTMS/TCC_TRNSP_CHRG.
Fig 6. Test /SCMTMS/TOR with BOBT transaction
It looked easy. While checking the assocciations in the BOBT transaction, the dobble click on the requested node presented me the data of the CBO. So far so nice. Now I wanted to get it done via coding. I tried a lot of methods and ways to get the CBO data. But the only reslut I got, were dumps and empty data containers.
Now we come to the subtitle of this blog. “One goal and two ways to get there”
3.1 Knowing that the key of the (CBO) is stored in one field of the (DBO)
Knowing that the key of the (CBO) is stored in one field of the (DBO) saves a lot of frustrating development time and dumps.
Fig 7. Reading associations with BOBT transaction
Fine. But how do we know, that the field UUID057 is realy the right one and not only a piece of luck?
Therefore we have to take a look into DO /SCMTMS/TCC_TRNSP_CHRG and go further on to the structure /SCMTMS/S_TCC_CHRGITEM_K. Here we will find the included structure /SCMTMS/S_FRGHT_AGREEMENT_UUID.
Fig 8. Structure /SCMTMS/S_FRGHT_AGREEMENT_UUID
The short description confirms, that we found the right field and key to the CBO.
With the combination of Coding 1 and Coding 2 we will get the data we want to read. For sure, we have to create instances of two different service managers. The first for the transport order an the second for the freight agreement.
Nevertheless, it’s a lot of coding needed to get from the root node of the TRANSPORTORDER to the DO TRANSPORTCHARGES and at long last to the CBO FREIGHT_AGREEMENT.
And as it happens, I found another very delightful way to read the data.
3.2 Knowing that we can use the data crawler in SAP TM
Luckily I scrolled down in Holger Polchs SAP TM9 Enhancement Guide to the coding of chapter “4.3 Conditions”.
*&---------------------------------------------------------------*
*& Report ZREP_DC_TEST
*&---------------------------------------------------------------*
*& This report demonstrates the usage of a Data Crawler Profile to
*& read and retrieve data from a business object.
*&---------------------------------------------------------------*
REPORT zrep_dc_test.
DATA: ls_dc_prof_id TYPE /scmtms/dc_profile_id,
lt_dc_prof_id TYPE /scmtms/t_dc_profile_id,
ls_bo_inst_key TYPE /bobf/s_frw_key,
lt_bo_inst_key TYPE /bobf/t_frw_key,
lo_crawler TYPE REF TO /scmtms/cl_data_crawler,
lt_dc_data TYPE /scmtms/cl_data_crawler=>tt_data,
lo_message TYPE REF TO /bobf/if_frw_message.
CLEAR: ls_dc_prof_id, lt_dc_prof_id.
* Secify the Data Crawler Profile to be used
ls_dc_prof_id = 'ZENH_TRQ_ITEM'.
APPEND ls_dc_prof_id TO lt_dc_prof_id.
* Specify the key of an example BO instance (here: a TRQ instance)
ls_bo_inst_key-key = '4D08C2BEC9015E16E10000000A421A6A'.
APPEND ls_bo_inst_key TO lt_bo_inst_key.
* Create an instance of the Data Crawler class
CREATE OBJECT lo_crawler EXPORTING it_profile_id = lt_dc_prof_id.
* Call the Data Crawler with the given profile and BO instance
CALL METHOD lo_crawler->get_data
EXPORTING
it_profile_id = lt_dc_prof_id
it_key = lt_bo_inst_key
IMPORTING
et_data = lt_dc_data
eo_message = lo_message.
* The resulting data can be found in LT_DC_DATA
Fig 9. Coding 3 – Using data crawler to read data
[Source: SAP Transportation Management 9.x™ – Enhancement Guide Page 108]
No! – That easy? Yes! – that easy.
The only thing we have to do: Define a data crawler profile and it steps from one node to the next, mark “fill data” and call this profile as shown above.
Example of an data crawler profile:
Fig 10. Path steps configuration in data crawler profile
That’s all for today. Hopefully I could save some developers a lot of time, while learning BOPF.
Source: https://blogs.sap.com/2018/06/11/bopf-navigate-through-objects-in-sap-tm/
Nenhum comentário:
Postar um comentário