I started working in SAP TM module (Version 8.1) 1 year back and we hardly find little help since we started working on it. My past experience enforced me to publish this blog which I hope it will definitely help developers to learn and understand how to retrieve the data by making use of Business objects based out in BOPF framework.

SAP TM has been developed using a set of new technologies that require skills that go beyond typical SAP Developments:

  • Floor plan manager (based on Web Dynpro ABAP concept)
  • BOPF – Business object processing framework
  • BRF+ – Business Rules framework plus
  • Adobe forms.

Apart from the above skills, it will always be an advantage if developer has knowledge on Process Integration (PI) and SAP NetWeaver Business client (NWBC).

These days SAP TM client base is getting increased quite significantly since then TM 9.0 had been released. I am sure most of the aspirants who started working on TM and BOPF might have lot of questions in the first experience. In this blog, I have presented how to make use of the standard methods QUERY, RETRIEVE and RETRIEVE BY ASSOCIATION to read the data and display it as report output.

Introduction to BOPF:

The Business Object Processing Framework is an ABAP OO-based framework that provides a set of generic services and functionalities to speed up, standardize, and modularize your development.

BOPF controls the application business logic as well as the data retrieval of the buffer and persistency layer. The main design principles are a clear separation of the business logic and the buffering of data as well as a clear structuring of the business logic into small parts with a clear separation of changing and checking business logic. The BOPF approach for implementing business objects breaks down business logic into the following four concepts:

  • Actions
  • Determinations
  • Validations
  • Queries

Examples for TM Business Objects are the Forwarding Order (TRQ) and Freight Order / Freight Booking (TOR).

Important transactions to note while working on BOPF:

/BOBF/CONF_UI: This transaction is used to display the modeling of the TM business objects. This is called as BOPF Modeling Tool.

/BOBF/CUST_UI: This transaction is used for launching the BOPF Enhancement workbench. This transaction is used for enhancing the standard business objects and for creating a new business objects.

/BOBF/TEST_UI: This transaction is used as a test environment. This transaction would help consultant (Either it is a functional or technical) to see the data of a particular Forwarding order or Freight order or Freight booking. I will explain in detail in my next blog effective use of test environment.

Use Case for Report Development:

I would like to explain how to read the data from database using BOPF with below use case. This is based on one of the latest requirement from my customer (Leading Freight Forwarder) which I had developed.

Management is interested in tracking all the shipments (FWO’s with charge calculation) out of which how many are created following the Forwarding agreement and how many are not? Therefore this report will help them to insist business users to ensure effective way of using agreements.

Unlike ABAP, here we follow a different approach in BOPF to retrieve the data from database. We are not going to write any select query;
instead data is retrieved by calling the standard methods – QUERY, RETRIEVE and RETRIEVE BY ASSOCIATION depending on the relation between nodes in a business objects.

In this example, we are trying to display shipment (FWO) information, invoicing amount and Forwarding agreement. To achieve the expected
results, we are going to access different business objects such as /SCMTMS/TRQ, /SCMTMS/CUSTFREIGHTINVREQ  and
/SCMTMS/TCC_TRNSP_CHRG. Relations between 2 business object nodes are associated via a direct, unidirectional and binary relationship.

Please find a report program below with code snippet for achieving the expected business requirement.

*&———————————————————————*
*& Report  ZTM_READ_TRQ_FAG
*&
*&———————————————————————*
*&Purpose: This report will help management to track the usage of Forwarding agreements
*&during invoicing for shipments created globally
*&Report output contain: Sales organization, Forwarding order, FWO Type, country, File Number,
*&Order creation date, Invoice amount, agreement
*&———————————————————————*

REPORT  ztm_read_trq_fag.

TABLES: /scmtms/d_trqrot.
***Data declaration
DATA:     ls_selpar                 TYPE          /bobf/s_frw_query_selparam,
          lt_selpar                
TYPE TABLE OF /bobf/s_frw_query_selparam,
          lt_trq_key               
TYPE          /bobf/t_frw_key,
          lt_trq_root              
TYPE          /scmtms/t_trq_root_k,
          ls_trq_root              
LIKE LINE OF  lt_trq_root.
DATA:     ls_cfir_root              TYPE          /scmtms/s_cfir_root_node_k,
          lt_cfir_root             
TYPE          /scmtms/t_cfir_root_node_k,
          lo_trq_srvmgr            
TYPE REF TO   /bobf/if_tra_service_manager,
          lt_cfir_root_key         
TYPE          /bobf/t_frw_key,
          ls_cfir_root_key         
TYPE          /bobf/s_frw_key,
          lt_tcc_root              
TYPE          /scmtms/t_tcc_root_k,
          lt_tcc_root_key          
TYPE          /bobf/t_frw_key,
          ls_tcc_root_key          
LIKE LINE OF  lt_tcc_root_key,
          ls_tcc_root              
TYPE          /scmtms/s_tcc_root_k,
          lo_srvmgr_cfir           
TYPE REF TO   /bobf/if_tra_service_manager,
          ls_tcc_charge_item       
TYPE          /scmtms/s_tcc_chrgitem_k,
          lt_tcc_charge_item       
TYPE TABLE OF /scmtms/s_tcc_chrgitem_k,
          lt_trq_cfir_link         
TYPE          /bobf/t_frw_key_link,
          ls_trq_cfir_link         
LIKE LINE OF  lt_trq_cfir_link,
          lv_chrg_it_assoc_key     
TYPE /bobf/obm_assoc_key.

TYPES: BEGIN OF ty_final,
        sales_org_id 
TYPE zforw_house,
        fileno       
TYPE zfileno,
        trq_type     
TYPE /scmtms/trq_type,
        fagrmntid044 
TYPE /scmtms/fag_id,
        order_date   
TYPE sydatum,
        amount       
TYPE /scmtms/amount,
END OF ty_final.

DATA: ls_final TYPE ty_final,
      lt_final
TYPE TABLE OF ty_final.

FIELD-SYMBOLS: <fs_root>                 LIKE LINE OF lt_cfir_root,
               <fs_tcc_root_key>        
TYPE /scmtms/s_tcc_root_k.

SELECT-OPTIONS: s_date  FOR systdatum OBLIGATORY NOEXTENSION,
                s_org  
FOR /scmtms/d_trqrotsales_org_id OBLIGATORY NO INTERVALS.

**Get instance of service manager for TRQ
lo_trq_srvmgr
= /bobf/cl_tra_serv_mgr_factory=>get_service_manager( /scmtms/if_trq_c=>sc_bo_key ).

CLEAR: ls_selpar, lt_selpar.
ls_selpar
attribute_name = /scmtms/if_trq_c=>sc_node_attributerootorder_date.
MOVE-CORRESPONDING s_date TO ls_selpar.
APPEND ls_selpar TO lt_selpar.

CLEAR: ls_selpar.
DATA: ls_org LIKE LINE OF s_org[].

LOOP AT s_org[] INTO ls_org.
  ls_selpar
attribute_name = /scmtms/if_trq_c=>sc_node_attributerootsales_org_id.
 
MOVE-CORRESPONDING ls_org TO ls_selpar.
 
APPEND ls_selpar TO lt_selpar.
 
CLEAR: ls_selpar, ls_org.
ENDLOOP.

***Here we can not call RETRIEVE method because we do not have TRQ node keys on hand.
***For this requirement it is recommended to call QUERY since RETRIEVE does not aligned with the selection screen parameters

CLEAR: lt_trq_key, lt_trq_root.
lo_trq_srvmgr
->query(
 
EXPORTING
    iv_query_key           
= /scmtms/if_trq_c=>sc_queryrootquery_by_attributes
    it_selection_parameters
= lt_selpar
    iv_fill_data           
= abap_true
 
IMPORTING
    et_data                
= lt_trq_root
    et_key                 
= lt_trq_key ).

**If no data exist in database table then raise error message.
IF lt_trq_key IS NOT INITIAL.
 
CLEAR: lt_cfir_root, lt_trq_cfir_link.
  lo_trq_srvmgr
->retrieve_by_association(
 
EXPORTING
    iv_node_key            
= /scmtms/if_trq_c=>sc_noderoot                     ” Node Name
    it_key                 
= lt_trq_key                                         ” Key Table
    iv_association         
= /scmtms/if_trq_c=>sc_associationrootcfir_root    ” Name of Association
    iv_fill_data           
= abap_true
 
IMPORTING
    et_data                
= lt_cfir_root    ” Data Return Structure
    et_key_link            
= lt_trq_cfir_link
).

  LOOP AT lt_cfir_root ASSIGNING <fs_root>.
    ls_cfir_root_key
key = <fs_root>key.
   
INSERT ls_cfir_root_key INTO TABLE lt_cfir_root_key.
   
CLEAR: ls_cfir_root_key.
 
ENDLOOP.

  IF lt_cfir_root_key IS NOT INITIAL.

    lo_srvmgr_cfir = /bobf/cl_tra_serv_mgr_factory=>get_service_manager( /scmtms/if_custfreightinvreq_c=>sc_bo_key ).

    CLEAR: lt_tcc_root.
    lo_srvmgr_cfir
->retrieve_by_association(
     
EXPORTING
        iv_node_key      
= /scmtms/if_custfreightinvreq_c=>sc_nodetrnspcharges
        it_key           
= lt_cfir_root_key
        iv_association   
= /scmtms/if_custfreightinvreq_c=>sc_associationroottrnspcharges
        iv_fill_data     
= abap_true
     
IMPORTING
        et_data          
= lt_tcc_root ).
 
ENDIF.

  CLEAR: ls_tcc_root_key.
 
LOOP AT lt_tcc_root ASSIGNING <fs_tcc_root_key>.
    ls_tcc_root_key
key = <fs_tcc_root_key>key.
   
INSERT ls_tcc_root_key INTO TABLE lt_tcc_root_key.
   
CLEAR: ls_tcc_root_key.
 
ENDLOOP.

  IF lt_tcc_root_key IS NOT INITIAL.
* Get Charge Item node key and Charge<->Charge Item Association key
   
CALL METHOD /scmtms/cl_common_helper=>get_do_keys_4_rba
     
EXPORTING
        iv_host_bo_key     
= /scmtms/if_custfreightinvreq_c=>sc_bo_key
        iv_host_do_node_key
= /scmtms/if_custfreightinvreq_c=>sc_nodetrnspcharges
        iv_do_node_key     
= /scmtms/if_tcc_trnsp_chrg_c=>sc_nodechargeitem
        iv_do_assoc_key    
= /scmtms/if_tcc_trnsp_chrg_c=>sc_associationrootchargeitem
     
IMPORTING
        ev_assoc_key       
= lv_chrg_it_assoc_key.

*& –> Get the DO transportcharges chargeitem data …
*&—————————————————–

    CALL METHOD lo_srvmgr_cfir->retrieve_by_association
     
EXPORTING
        iv_node_key   
= /scmtms/if_custfreightinvreq_c=>sc_nodetrnspcharges
        iv_association
= lv_chrg_it_assoc_key
        it_key        
= lt_tcc_root_key
        iv_fill_data  
= abap_true
     
IMPORTING
        et_data       
= lt_tcc_charge_item.

  ENDIF.
ENDIF.

CLEAR: ls_trq_root, ls_trq_cfir_link, ls_cfir_root, ls_tcc_charge_item, ls_tcc_root, ls_final.
LOOP AT lt_trq_root INTO ls_trq_root.
 
LOOP AT lt_trq_cfir_link INTO ls_trq_cfir_link WHERE source_key = ls_trq_rootkey.
   
READ TABLE lt_cfir_root INTO ls_cfir_root WITH KEY key = ls_trq_cfir_linktarget_key BINARY SEARCH.
   
IF sysubrc EQ 0.
     
READ TABLE lt_tcc_charge_item INTO ls_tcc_charge_item WITH KEY root_key = ls_cfir_rootkey BINARY SEARCH.
     
IF sysubrc EQ 0.
        ls_final
fileno         = ls_trq_root-zfileno.
        ls_final
sales_org_id   = ls_trq_rootsales_org_id.
        ls_final
trq_type       = ls_trq_roottrq_type.
        ls_final
fagrmntid044   = ls_tcc_charge_itemfagrmntid044.
        ls_final
order_date     = ls_trq_rootorder_date.

        READ TABLE lt_tcc_root INTO ls_tcc_root WITH KEY root_key = ls_cfir_rootkey BINARY SEARCH.
       
IF sysubrc EQ 0.
          ls_final
amount = ls_tcc_rootrnd_net_amount.
       
ENDIF.
       
APPEND ls_final TO lt_final.
     
ENDIF.
   
ENDIF.
   
CLEAR: ls_final, ls_cfir_root, ls_tcc_charge_item, ls_trq_cfir_link.
 
ENDLOOP.
 
CLEAR: ls_trq_root.
ENDLOOP.

SORT lt_final BY sales_org_id ASCENDING fagrmntid044 order_date DESCENDING.

PERFORM display_grid_output.
*&———————————————————————*
*&      Form  DISPLAY_GRID_OUTPUT
*&———————————————————————*
*       text
*———————————————————————-*
*  –>  p1        text
*  <–  p2        text
*———————————————————————-*
FORM display_grid_output .

  TYPES : BEGIN OF ty_message,
  row         
TYPE i,
  partner
(30TYPE c,
  msg_type    
TYPE char20,
 
message(100) TYPE c,
 
END OF ty_message.

  DATA: t_fieldcat TYPE slis_t_fieldcat_alv WITH HEADER LINE.

  t_fieldcatcol_pos   = ‘1’.
  t_fieldcat
fieldname = ‘SALES_ORG_ID’.
  t_fieldcat
seltext_l = ‘House’.
  t_fieldcat
outputlen = ’15’.
 
APPEND t_fieldcat.

  t_fieldcatcol_pos   = ‘2’.
  t_fieldcat
fieldname = ‘FILENO’.
  t_fieldcat
seltext_l = ‘File Number’.
  t_fieldcat
outputlen = ’20’.
 
APPEND t_fieldcat.

  t_fieldcatcol_pos   = ‘3’.
  t_fieldcat
fieldname = ‘TRQ_TYPE’.
  t_fieldcat
seltext_l = ‘File Type’.
  t_fieldcat
outputlen = ’10’.
 
APPEND t_fieldcat.

  t_fieldcatcol_pos   = ‘4’.
  t_fieldcat
fieldname = ‘FAGRMNTID044’.
  t_fieldcat
seltext_l = ‘Aggreement’.
  t_fieldcat
outputlen = ’30’.
 
APPEND t_fieldcat.

  t_fieldcatcol_pos   = ‘5’.
  t_fieldcat
fieldname = ‘ORDER_DATE’.
  t_fieldcat
seltext_l = ‘Order creation Date’.
  t_fieldcat
outputlen = ’20’.
 
APPEND t_fieldcat.

  t_fieldcatcol_pos   = ‘6’.
  t_fieldcat
fieldname = ‘AMOUNT’.
  t_fieldcat
seltext_l = ‘Amount’.
  t_fieldcat
outputlen = ’15’.
 
APPEND t_fieldcat.

  CALL FUNCTION ‘REUSE_ALV_GRID_DISPLAY’
   
EXPORTING
      i_callback_program
= ‘ZTM_READ_TRQ_FAG’
*     i_grid_title       = lw_title
      it_fieldcat       
= t_fieldcat[]
*     is_layout          = ls_layout
   
TABLES
      t_outtab          
= lt_final
   
EXCEPTIONS
      program_error     
= 1
     
OTHERS             = 2.

ENDFORM.                    ” DISPLAY_GRID_OUTPUT

Hope now you have got a basic idea of how to retrieve the data in BOPF environment. In my further blogs, I would like to present troubleshooting and analyzing the critical issues during support and tips and tricks during Development phase.

Appreciate your comments if any better way of doing it.

When I started working on BOPF initially, this is one of the blog series and Enhancement guide document (Links pasted below) which had helped me to understand what BOPF is – .

http://scn.sap.com/community/abap/blog/2013/01/04/navigating-the-bopf-part-1–getting-started

http://scn.sap.com/docs/DOC-32985

Thanks to James Wood and thanks to Holger.

To report this post you need to login first.

16 Comments

You must be Logged on to comment or reply to a post.

  1. Eduardo Chagas

    There is huge lack of knowledge in Brazil on BOPF! I’ve attended a meeting with some TM customers in Brazil this morning and the main discussion was about it.

    Thanks for sharing!

    (0) 
    1. Tarun Kumar

      Hi Eduardo,

      I was supposed to travel to Brazil to give a BOPF detail session to a customer but it was cancelled by the customer because of time crunch in their project.

      Anyways, let’s see if it comes in future.

      Thanks & Regards,

      Tarun Kumar

      (0) 
      1. Eduardo Chagas

        Nice to know! 

        By the way.. we started to organize an Inside Track in South Brazil and would be really great to have a session about BOPF! I’ll let you know.

        Tks

        Eduardo Chagas

        (0) 
  2. Vivek Vijay

    Do we have to write code at the implementation of class created at the time of custom query.

    If I want only internal table lt_trq_key to be filled, what should i write inside the implementation?

    (0) 
  3. Jane Cruz

    Hi Bharath,

    Currenly, I need to read TEXT_CONTENT nodes but Iam confused and I haven’t been able to do it. I already read /SCMTMS/TOR nodes and TEXTCOLLECTION keys… you know how do it?

    I tried with lo_srvmgr_txt_coll = /bobf/cl_tra_serv_mgr_factory=>get_service_manager( /bobf/if_txc_c=>sc_bo_key ).

    but it gets a dump…

    Regards 😀

    get_text_content.PNG

    (0) 
    1. Rajiv Lund

      hi Jane.

      The reason for the dump is: text collection is a dependent node DO -> it does not exist on it own -> it is part of BO where it is integrated (dynamically). No special service manager is allowed. You need to access the DO via the parent BO Service manager.

      There is a dynamic mapping of node keys. It is only one method call. If you search in standard coding, you will find some examples.

      So after such mapping of keys, you can use this node like a standard node of BO. It is a little bit complicated about DOs, however after first time you get used to it.

      BR

      Rajiv

      (0) 
    2. Tarun Kumar

      Hi Jane,

      If you have TEXTCOLLECTION keys you can use 

      /scmtms/cl_common_helper=>get_do_entity_key to get the RUNTIME node & association keys of TEXT_CONTENT node and then you need to fire a retrieve by association on this nodes using TOR service manager. You will get the data without any dump.

      Thanks & Regards,

      Tarun Kumar

      (0) 
      1. Jane Cruz

        Hi Tarum,

        I reviewed the standard as suggested Rajiv, and its correct that you say.. 😉

        I used a combination of methods to retrieve the keys and content.

        Now there are no dumps 

        lo_srvmgr->retrieve_by_association and

        /scmtms/cl_common_helper=>get_do_keys_4_rba

        Thank you both, appreciate your help 🙂

        Regards

        (0) 
    3. Eduardo Chagas

      Hi Jane

      Please I’d ask you to create a thread instead to post questions in a blog/document. It is better to find if someone is facing the same issue.

      Thank you

      Eduardo Chagas

      (0) 
  4. amar srinivas

    Hi All,

    I am new to SAP TM development.. We have got a new system (SAP TM) and our functional has done the basic configuration.. Waiting for the PI/XI box to be given for connecting with ECC.. Mean while i would like to know the difference between seeing the transactions in sap tm system and logging with NWBC..

    We have created a Freight booking and freight order through NWBC..

    I am not able to figure out in which table the freight orders and freight bookings are stored.

    I did not find any entry in any of the tables

    Why cant we create any transactions in SAP TM system directly…

    Can any one let me know how a technical person scope of work differs in TM system with that of NWBC and TM system..

    Do we also do coding in NWBC or its always in the TM system.

    I saw that certain transactions only execute through NWBC where as they are not valid in TM system.

    How different would be the initial set up of master data and creating some transactions.

    Kindly help,

    Amar

    (0) 
    1. Bharath Komarapalem Post author

      Hi amar,

      Please create a new post or ask a question via thread.

      Eduardo has already commented about the same.

      thanks for taking note.

      thanks,

      bharath.

      (0) 
  5. Venkatesh Tharimela

    Hi Baharath,

    I could not able to see the node CFIR_ROOT in the node hierarchy of the TRQ business object ..but it is there a key for the CFIR_ROOT node in the constant interface of the BO.

    .Bopf.PNG

    (0) 

Leave a Reply