Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
Andre_Fischer
Product and Topic Expert
Product and Topic Expert
18,253

Introduction

In a tutorial Implement a Wrapper for the "Create Purchase Requisition" (BAPI_PR_CREATE) function module that was published recently it was shown how to deal with the case in which no convenient released API is available to create purchase requisitions.

The question that came to my mind was whether there would be a way to automate the steps described in this tutorial so that creating wrappers for other BAPIs would become more easy.

This can now be done using transaction ACO_PROXY. 

 

Prerequisites

- You have to have a system based on SAP S/4HANA 2022 or 2023 on premise.
- You have to have enabled Developer extensibility
- You have to apply the following notes

3444292 - ACO Proxy creates unnecessary shadow types. - SAP for Me

3457580 - SAP ACO - Duplicate Types for Table Parameters - SAP for Me

3518177 - SAP ACO Proxy Improvements - SAP for Me

3519098 - F4: fix function module value help - SAP for Me (only relevant for SAP S/4 HANA 2023)

 

ACO_PROXY

The transaction ACO_PROXY now allows to generate a wrapper class, an C1-interface and a C1-released factory class which is the recommended approach (see the tutorial above). The C1 released factory class can then be used to intantiates the wrapper class being used in your ABAP Cloud coding.

The transaction ACO_PROXY and its underlying API now also check if a data element that is used by a non released function module itself has been released. If this is the case, no shadow type will be generated.

 

How to use the improved transaction ACO_PROXY?

First you have to start transaction ACO_PROXY.

Andre_Fischer_0-1726658492446.png

 

  1. Here you can select one or more function modules that will be wrapped by one single class. (e.g BAPI_PR_CREATE, BAPI_PR_CHANGEBAPI_PR_GETDETAIL, ...)
  2. Choose a name of a proxy class, e.g. ZAF_CL_PR_BAPI_009.
  3. Select an existing package, e.g. TEST_AF_ACO_009
  4. Check the check box Create Interface and choose a name for the interface, e.g. ZAF_IF_PR_BAPI_009
  5. Check the check box Create Factory Class and choose a name for the factory class, e.g. ZAF_CL_F_PR_BAPI_009
  6. Uncheck the check box Pass Destination via Constructor
  7. Choose the radio-button Class-Based Exceptions
  8. Check the check box Do not create Shadows of C1 Released Types
  9. Check the check box C1 Release
  10. Check the check box Create Private Methods

As described in the above mentioned tutorial the approach of using an interface and a factory class is the recommended one.

When you press the green check mark or press F8 you continue to the dialogues that allow you to de-select optional parameters from being used in the public interface of your wrapper class. 

Andre_Fischer_0-1726658961700.png

You can continue to the dialogue for the next function module by pressing the green check mark in the upper left corner of the SAPGUI screen.  

Andre_Fischer_1-1726659006078.png

Finally the generation starts.

The objects can then be checked in the target package.

Andre_Fischer_2-1726659057589.png

When you check the code of the public method you see that the private method is called with the de-selected optional parameters being commented out so that they can easily be added afterwards back to the public interface if you wish to do so. 

Andre_Fischer_0-1726659132033.png

Last not least you can check that the interface and the factory class have been C1-released.

Andre_Fischer_1-1726659255089.png

 

Hope this will help to speed up the process of creating wrappers for non-released function modules.

Call the wrapper class

The wrapper class in the sample shown above can be called as follows (see below) and would produce an out put as follows:  

Andre_Fischer_0-1726659960018.png

 

CLASS zcl_bapi_wrap_test_009 DEFINITION
  PUBLIC
  FINAL
  CREATE PUBLIC .

  PUBLIC SECTION.
    INTERFACES if_oo_adt_classrun .
  PROTECTED SECTION.
  PRIVATE SECTION.
ENDCLASS.



CLASS zcl_bapi_wrap_test_009 IMPLEMENTATION.
  METHOD if_oo_adt_classrun~main.

    DATA pr_returns TYPE bapirettab.

    DATA prheader TYPE zaf_if_pr_bapi_009=>bapimereqheader .
    DATA prheaderx TYPE zaf_if_pr_bapi_009=>bapimereqheaderx .
    DATA number  TYPE zaf_if_pr_bapi_009=>banfn  .
    DATA pritem  TYPE zaf_if_pr_bapi_009=>_bapimereqitemimp .
    DATA pritemx  TYPE zaf_if_pr_bapi_009=>_bapimereqitemx  .
    DATA prheaderexp  TYPE zaf_if_pr_bapi_009=>bapimereqheader .

    DATA(myclass) = zaf_cl_f_pr_bapi_009=>create_instance( ).

    prheader = VALUE #( pr_type = 'NB' ).
    prheaderx = VALUE #( pr_type = 'X' ).

    pritem           = VALUE #( (
                      preq_item  = '00010'
                      plant      = '1010'
                      acctasscat = 'U'
                      currency   = 'EUR'
                      deliv_date = cl_abap_context_info=>get_system_date(  ) + 14   "format: yyyy-mm-dd (at least 10 days)
                      material   = 'ZPRINTER01'
                      matl_group = 'A001'
                      preq_price = '100.00'
                      quantity   = '1'
                      unit       = 'ST'
                      pur_group = '001'
                      purch_org = '1010'
                      short_text = 'ZPRINTER01'
                    ) ).

    pritemx           = VALUE #( (
                      preq_item  = '00010'
                      plant      = 'X'
                      acctasscat = 'X'
                      currency   = 'X'
                      deliv_date = 'X'
                      material   = 'X'
                      matl_group = 'X'
                      preq_price = 'X'
                      quantity   = 'X'
                      unit       = 'X'
                      pur_group = 'X'
                      purch_org = 'X'
                      short_text = 'X'
                    ) ).

    TRY.
        myclass->bapi_pr_create(
          EXPORTING
            prheader = prheader
            prheaderx = prheaderx
            _dest_  = 'NONE'
          IMPORTING
            number   = number
            prheaderexp = prheaderexp
          CHANGING
            pritem = pritem
            pritemx = pritemx
     )
        .
      CATCH cx_aco_application_exception cx_aco_communication_failure cx_aco_system_failure INTO DATA(call_wrapper_exception).
        "handle exception
        out->write( |Exception occured: { call_wrapper_exception->get_text(  ) }| ).
    ENDTRY.
    out->write( |purchase requistion number: { number  } | ).
    LOOP AT pr_returns INTO DATA(bapiret2_line).
      out->write( |bapi_return: { bapiret2_line-message } | ).
    ENDLOOP.
  ENDMETHOD.
ENDCLASS.

Further reading

How to find SAP APIs for SAP S/4HANA 3-tier extens... - SAP Community

SAP/abap-atc-cr-cv-s4hc: ABAP test cockpit cloud readiness check variants for SAP S/4HANA Cloud (git...

 

Future Outlook

In future the idea is to offer the option to start such a generator as well in the ABAP development tools for Eclipse. This will be possible with the next S/4HANA release and the ADT generator framework.    

 

 

13 Comments