Application Development Blog Posts
Learn and share on deeper, cross technology development topics such as integration and connectivity, automation, cloud extensibility, developing at scale, and security.
cancel
Showing results for 
Search instead for 
Did you mean: 
Juwin
Active Contributor

Pre-read 1: Influence Request

Pre-read 2: Community Question  

Brief description from the Influence ticket mentioned above:

Suppose a new Custom Business Object is created using the Fiori App "Custom Business Objects" via InApp methodology. Since this new "Custom Table" is created in a specific package, the developments done on Embedded Steampunk, can't access these tables. Since developers working on Embedded Steampunk, doesn't have access to the specific package for InApp extensions, a "Release Contract" can't be assigned to the new "Custom Table". This creates a situation where a "Custom Code" created via Embedded Steampunk, can't access a "Custom Table" created via InApp Extension. ADT throws an error: The use of CDS Entity.....is not permitted. Similar is the case with Custom CDS Views created using Key User Extensibility or standard SAP objects that are only released for use in Key User Extensibility. This creates a situation where custom artifacts created in one tenant are not available for use in another tenant within the same system.

This behavior is explained in the Layering blog

So, what are some of the standard solutions available? Use a proxy/API

  • Local proxy (CL_WEB_ODATA_CLIENT_FACTORY)
  • API (CL_CBO_DEVELOPER_ACCESS)

What are some of the limitations faced with this standard method?

  • These methods only support custom objects. So, standard CDS views that are released for Key User Extensibility (such as below) are still out of reach

Juwin_0-1708035167703.png

  • Limited number of filters: Since the oData call happens over HTTP, the url length cannot handle long conditions
  • SQL like actions like Joins with other tables are not possible

As of today, there are many CDS views that are still only accessible to Key User Extensibility and not Developer Extensibility.

Juwin_1-1708035562250.png

So, how to get access from Developer Extensibility, to the remaining standard CDSs and the custom developed objects, in a manner that allows SQL like statements. If interested to know, please continue reading....

Writing SQL against these objects, are only possible through Classes written in Key User Extensibility. Writing Classes in Key User Extensibility, can be through various methods (e.g a BADI implementation or Custom Libraries in Custom Reusable Elements). But, since these classes are also written in Key User Extensibility, layering won't allow to access these classes from Developer Extensibility..... Or, will they?

The trick is to implement a BADI that is also released for Developer Extensibility.

Find any BADI, that takes a Filter parameter, that is released for both Developer Extensibility & Key User Extensibility. Filter parameter is important because, this ensures that this dirty solution will only be instantiated if the custom filter value is used. 

For eg. Custom filter value used here is ZSAPBLOG

Juwin_2-1708036200822.png

Next create a Class in Developer Extensibility to call this BADI.

class zcl_sapdemo_keyuser definition public final create public .
  public section.
    interfaces if_oo_adt_classrun.
    class-data: gv_count type i,
                gv_company type bukrs value 'GB00'.
  protected section.
  private section.
endclass.

class zcl_sapdemo_keyuser implementation.
  method if_oo_adt_classrun~main.
    data lo_keyuser_query type ref to srf_report_run_on_delete.
    data lt_msgdummy      type symsg_tab.
    data lv_keydummy      type srf_report_run_key.

    try.
        get badi lo_keyuser_query filters report_id = 'ZSAPBLOG'.
        if lo_keyuser_query is bound.
          call badi lo_keyuser_query->execute
            exporting iv_report_run_key = lv_keydummy  "This is just dummy value 
                      iv_force_delete   = ''
                      iv_test_run       = ''
            changing  ct_message        = lt_msgdummy. "This is just dummy value 
        endif.
        out->write( |{ gv_count } lines| ).
      catch cx_root into data(lo_exception).
    endtry.
  endmethod.
endclass.

Release this Class for use in Key User Extensibility

Juwin_3-1708036737135.png

Now, write the required SQL in the custom BADI implementation.

SELECT COUNT( * )
    FROM i_paymentproposalpayment
    WHERE payingcompanycode = @zcl_sapdemo_keyuser=>gv_company
     INTO @zcl_sapdemo_keyuser=>gv_count.

This can be any complicated SQL. The above example just queries the forbidden CDS view and gets a count of records. I have used static data to pass the required variables back-and-forth between the 2 classes. Please feel free to use any other method if you find them more useful.

Now, this solution is ready for execution. Go back to Developer Extensibility and try to execute the class  ZCL_SAPDEMO_KEYUSER.

If everything is built according to this blog, the BADI will get instantiated, executed and populate back the selected count of records to the calling class. The result of execution in ABAP console will look something similar to: 

Juwin_4-1708037255324.png