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.