Wednesday, April 13, 2016

Using the BOL in BAdIs... Or not?



Developing custom programs from scratch is one thing, creating modifications within SAP CRM is something totally different. Within a system like SAP CRM you need to know how things work, what options you have to achieve a specific goal etc.


In this blog I want to share my experience on working with BOL/GenIL and some of the BAdI's I have implemented, and I hope to get some more insights/tricks from you readers as well. ;-)

If you are not familiar with BAdI's, Check here for more information.

The first problem I ran into was with the following requirement:
"When saving a specific business transaction in the WebClient we want to make sure that field Y is filled".
The first solution for this requirement was created within the configuration making field Y mandatory. After some testing we found out that despite the field being mandatory, when navigating to another view and we clicked the End button the business transaction would still be saved.


BadI order_save and BOL/GenIL

So after some googling and reading SCN posts it seems that if you want to achieve this, you need to implement the order_save BAdI. In the implementation of this BAdI I used the BOL programming technique to read the business transaction data. While testing this solution I saw that despite raising do_not_save exception the order still got saved. It took me quite some time to figure out why the implementation was not working. While in debug everything looks like it was working perfect, the BOL is giving result. The field Y is checked and seems to be empty, and then the raise takes place.

The problem seems to be in the use (misuse) of the different application layers that are present within SAP CRM. See the picture below (also used in blog "The other side of the Business Object Layer").



This picture shows the different layers when using the CRM WebClient. The problem we were facing was caused by a violation of the use of different layers within SAP. In the order_save BAdI implementation the BOL layer was used, and this is not correct (see note 1931099 - Implementation of BAdI ORDER_SAVE does not work in WebUI).



                             
So how do you know if a BAdI is called from this API application layer? Some BAdI's even have a BOL entity in their interface, so in that case I assume that BOL programming is allowed. See for example the BAdI CRM_BP_UIU_SAVE method IF_CRM_BP_UIU_SAVE~REGISTER_4_SAVE.


But how about the BAdI for processing actions in transactions? I have experienced some magical moments in those implementations as well.

BAdI implementation of an action

Lets then take a look at the BAdI implementation of an action. The action can be customized in SAP CRM to be executed on save, direct processing or report processing. Will this setting have effect on when this BAdI will be processed? My experience with this implementation is that it differs in processing when it is processed at save vs immediate processing.

I will check two options for processing, first the option "Immediate Processing".


When processing this action directly from the CRM WebUI we will see the following stack trace. The BAdI is executed and there seems to be no API call in the stack trace below. So at this moment BOL programming will be executed correctly in my opinion.


For the second option we will check "Processing when Saving Document".


When this option is selected the action will be processed when the document is saved. When we take a look at the stack trace we notice that this is within the function CRM_ORDER_SAVE. So then BOL programming is not the way to go.


So what is the right way?
Well I have spent much time figuring out where the strange behavior of some implementations came from. I have read notes, blogs and SCN discussions on this topic. I guess the best way to go is based on the interface of the BAdI you are implementing. If there is a CL_CRM_BOL_ENTITY in there, I would use BOL programming. If there is nothing more than a GUID in the interface, then I would go for the function modules.

Please feel free to discuss and share experiences in the comments.

2 comments:

  1. Hi Pieter,

    Very interesting blog! For CRM programmers the BOL is a very easy way to communicate with the database. It's só easy that you tend to use it wherever you can, especially because the overhead of the framework is neglectible in most cases. But as you pointed out: it's not always the right way.

    BAdIs are points where you can insert custom code in the entire ABAP-layer (this layer spans the Business Engine- and Business Object Layer). If you look at the Web Client architecture you should only use BOL objects in the Business Object Layer and not in the API-layer. Your examples show this as well: the CRM_ORDER_SAVE BAdI is a BAdI on the API-layer. It is also called e.g. in transaction CRMD_ORDER and existed well before the Web Clients was created. So it is not specific to the Web Client. The UIU BAdIs ARE specific to the Web Client. They reside on the Business Object Layer so here you can (and should) use BOL-programming.

    In your example of the processing of actions - although technically it might work - I would not use BOL regardless of the execution trigger. The Action Framework resides on the Business Engine Layer and is not specific to the Web Client.

    So my rule of thumb: if the logic is needed for communication between the business layer and the UI-layer (be it Web Client or a UI through Gateway) then I would use the BOL. In all other cases (e.g. creating an RFC for IS-U or enhancements in non-UI-specific ABAPs) I would not.

    My 2 cents :)

    Cheers, Roel

    ReplyDelete
    Replies
    1. Hi Roel,

      I believe that you sum up my blog/experience very neatly, and your rule of thumb is a good design descision.

      Thanks for your insight.

      Regards,

      Pieter

      Delete